Phase 8f-3: Param Alignment Audit
Goal: Verify and resolve all parameter mismatches between MCP tool signatures and SDK method signatures. Ensure no existing agent workflow breaks.
Owner: Dev agent
Repo:
forgejo_admin/pal-e-docs-mcpDepends on: 8f-2 (tools must be rewritten first)
Scope
MCP tools were designed for AI agents (string params, CSV lists, optional everything). SDK methods were designed for Python developers (typed params, list[str], some required). The rewrite in 8f-2 introduced translation layers in the MCP wrappers. This sub-phase verifies all translations are correct, backward-compatible, and handles edge cases.
Audit Results (2026-03-07)
Betty Sue audited every MCP tool on
origin/main (commit 2c41b7a) against every SDK method signature. Found 8 documented mismatches (all implemented correctly) plus 5 additional items.8 Documented Mismatches — All Verified
| # | MCP Tool | Mismatch | Resolution | Verified |
|---|---|---|---|---|
| 1 | search_notes | MCP <code>query</code> → SDK <code>q</code> | Passed as positional arg to <code>get_sdk().search_notes(query, ...)</code> | YES |
| 2 | create_note / update_note | MCP <code>content</code> → SDK <code>html_content</code> | <code>html_content=content</code> in both tools | YES |
| 3 | create_note / update_note | MCP <code>project</code> → SDK <code>project_slug</code> | <code>project_slug=project</code> in both tools | YES |
| 4 | create_note / update_note | MCP <code>tags</code> CSV → SDK <code>list[str]</code> | <code>[t.strip() for t in tags.split(",")]</code> | YES |
| 5 | update_note_links | MCP <code>target_slugs</code> CSV → SDK <code>list[str]</code> | <code>[s.strip() for s in target_slugs.split(",")]</code> | YES |
| 6 | create_sprint | SDK requires <code>status</code>, MCP optional | <code>status=status or "planning"</code> | YES |
| 7 | add_sprint_item | SDK requires <code>position</code>; labels CSV→list | <code>position=0</code> hardcoded; <code>[l.strip() for l in labels.split(",")]</code> | YES |
| 8 | bulk_move_items | MCP <code>items</code> JSON string → SDK <code>list[dict]</code> | <code>json.loads(items)</code> with <code>JSONDecodeError</code> handling | YES |
5 Additional Findings
| # | Type | Tool | Finding | Risk |
|---|---|---|---|---|
| 9 | Translation | update_sprint | Uses <code>_UNSET</code> sentinel from SDK for <code>goal</code>, <code>start_date</code>, <code>end_date</code>. Passes <code>None</code> for <code>name</code> and <code>status</code> (correct — SDK uses None for "don't send" on those). | LOW — correctly implemented |
| 10 | Translation | move_sprint_item → update_sprint_item | MCP tool name <code>move_sprint_item</code> maps to SDK method <code>update_sprint_item</code>. Also uses <code>_UNSET</code> sentinel for <code>labels</code>. | LOW — correct but undocumented name mapping |
| 11 | Missing param | add_sprint_item | SDK has <code>points</code> param, MCP doesn't expose it. Not a bug — just not exposed to agents yet. | NONE — intentional omission for now |
| 12 | Edge case | create_note | Old MCP sent <code>"tags": []</code> when tags not provided. New MCP sends <code>tags=None</code> to SDK. If API treats missing <code>tags</code> differently from empty list, this is a behavioral regression. | <strong>MEDIUM — needs live test</strong> |
| 13 | Edge case | add_sprint_item | Labels uses <code>if labels else None</code> (falsy check). Empty string <code>""</code> treated as "no labels" — correct, but differs from <code>if labels is not None</code> pattern elsewhere. | LOW — empty string is never a valid label input |
Backward Compatibility Rules
- No MCP tool param names change
- No required params become optional or vice versa (except adding defaults for newly-required SDK params)
- CSV string convention stays — it's the agent interface contract
- Error response format unchanged:
{"error": true, "status_code": N, "detail": ...}
Verification Plan
- Live test #12: Call
create_notewithout tags, verify the API receives it correctly and no tags are applied. Compare with old behavior ("tags": []). - CSV edge cases: Trailing commas, whitespace, empty strings for tools #4, #5, #7.
- Sentinel handling: Verify
update_sprintonly sends explicitly-provided fields (not null for unset sentinel fields). - Test with actual MCP tool invocations via Claude — the real consumer.
Issue Scope (for Forgejo issue)
Items #12 is the only one that may require a code change. Items #9-11, #13 are documentation/verification only. The 8 documented mismatches are verified-correct and need no changes.
Recommended issue deliverables:
- Live test for #12 (tags=None vs tags=[])
- Fix if behavioral regression confirmed
- CSV edge case tests for #4, #5, #7 (trailing comma, whitespace)
- Document #10 (method name mapping) in code comment
Deliverables
- To be filled after completion
Related
phase-postgres-8f-mcp-rewrite— parent sub-phasephase-postgres-8f2-mcp-rewrite-core— the rewrite these translations live in