Phase 8f-2: Rewrite MCP tools to wrap SDK + add block tools #22

Closed
opened 2026-03-07 23:57:21 +00:00 by forgejo_admin · 0 comments

Lineage

plan-2026-02-26-tf-modularize-postgres → Phase 8 (SDK + MCP Rewrite) → Phase 8f (MCP Rewrite) → Phase 8f-2 (MCP Rewrite Core)

Repo

forgejo_admin/pal-e-docs-mcp

User Story

As an AI agent on the pal-e platform
I want all MCP tools to wrap the SDK (not raw httpx) and 7 new tools for blocks + delete_sprint
So that I can interact with knowledge at the block level (90% token reduction) and the full SDK surface is available

Context

pal-e-docs-sdk v0.1.0 is now published on Forgejo PyPI (8f-1 complete). The SDK has 32 methods across 8 mixins. The MCP server currently has 26 tools making raw httpx calls (~794 lines). After this rewrite: 32 tools wrapping SDK methods (~250 lines). 100% SDK coverage.

The 7 new tools are the payoff — 6 block tools (get_note_toc, list_blocks, get_section, update_block, create_block, delete_block) enable agents to work at sub-note granularity. Plus delete_sprint for full lifecycle.

Reference pattern: woodpecker-mcp wrapping woodpecker-sdk — identical architecture. Read ~/woodpecker-mcp/src/woodpecker_mcp/server.py for the proven _ok(data: Any) pattern.

File Targets

Files to modify:

  • src/pal_e_docs_mcp/server.py — swap httpx.Client for PalEDocsClient, change _ok/_error_response signatures
  • src/pal_e_docs_mcp/tools/notes.py — rewrite 7 tools to wrap SDK
  • src/pal_e_docs_mcp/tools/sprints.py — rewrite 10 tools + add delete_sprint
  • src/pal_e_docs_mcp/tools/links.py — rewrite 2 tools
  • src/pal_e_docs_mcp/tools/projects.py — rewrite 2 tools
  • src/pal_e_docs_mcp/tools/repos.py — rewrite 3 tools
  • src/pal_e_docs_mcp/tools/tags.py — rewrite 1 tool
  • src/pal_e_docs_mcp/tools/__init__.py — add blocks module registration
  • pyproject.toml — replace httpx with pal-e-docs-sdk, bump version to 0.2.0, add Forgejo PyPI index

Files to create:

  • src/pal_e_docs_mcp/tools/blocks.py — 6 new block tools

Files NOT to touch:

  • src/pal_e_docs_mcp/__init__.py — no changes needed
  • src/pal_e_docs_mcp/__main__.py — no changes needed

Acceptance Criteria

  • server.py: get_client() replaced with get_sdk() returning PalEDocsClient
  • server.py: _ok(data: Any) takes parsed dict/list, returns json.dumps(data, indent=2), returns {"ok": true} for None
  • server.py: _error_response() catches PalEDocsError hierarchy (NotFoundError, ValidationError, ServerError)
  • All 26 existing tools rewritten to call get_sdk().method_name()
  • 6 new block tools added in tools/blocks.py: get_note_toc, list_blocks, get_section, update_block, create_block, delete_block
  • 1 new sprint tool: delete_sprint
  • pyproject.toml: httpx replaced with pal-e-docs-sdk>=0.1.0, version bumped to 0.2.0
  • Forgejo PyPI index configured so uv run --directory resolves the SDK
  • No raw httpx imports in any tool file
  • ruff check and ruff format --check pass
  • MCP server starts successfully: uv run --directory ~/pal-e-docs-mcp python -m pal_e_docs_mcp (ctrl-c after startup)
  • 32 total tools discoverable

Test Expectations

  • Manual smoke test: start MCP server, verify it initializes without import errors
  • Manual smoke test: invoke get_note_toc("plan-2026-02-26-tf-modularize-postgres") — should return heading list
  • Manual smoke test: invoke get_section("plan-2026-02-26-tf-modularize-postgres", "phases") — should return phase table
  • Verify existing tools still work: invoke get_note("agent-workflow"), list_tags(), search_notes(query="CNPG")

Constraints

  • Param translation (8 tools): MCP tool signatures MUST NOT change (backward compat). The wrapper does the translation:
    • search_notes: MCP query → SDK q
    • create_note/update_note: MCP content → SDK html_content; MCP tags CSV → SDK list[str]; MCP project → SDK project_slug
    • update_note_links: MCP target_slugs CSV → SDK list[str]
    • create_sprint: default status="planning" when not provided
    • add_sprint_item: default position=0; MCP labels CSV → SDK list[str]
    • update_sprint: only pass fields explicitly provided (SDK uses _UNSET sentinel)
    • bulk_move_items: json.loads(items) for the JSON string → list[dict]
  • Follow woodpecker-mcp pattern exactly for server.py structure
  • Tool descriptions stay the same or improve — never remove information from descriptions
  • Forgejo PyPI index: Use [tool.uv.index] in pyproject.toml or equivalent so uv resolves pal-e-docs-sdk from https://forgejo.tail5b443a.ts.net/api/packages/forgejo_admin/pypi/simple
  • Block tool descriptions should emphasize token efficiency: "Use get_note_toc to browse structure before fetching content", "Returns ~200 tokens instead of ~5000 for the full note"

Checklist

  • PR opened
  • Lint passes
  • MCP server starts
  • All 32 tools discoverable
  • No unrelated changes
  • phase-postgres-8f2-mcp-rewrite-core — phase note in pal-e-docs
  • phase-postgres-8f-mcp-rewrite — parent phase with full audit findings
  • project-pal-e-docs — project page
### Lineage `plan-2026-02-26-tf-modularize-postgres` → Phase 8 (SDK + MCP Rewrite) → Phase 8f (MCP Rewrite) → Phase 8f-2 (MCP Rewrite Core) ### Repo `forgejo_admin/pal-e-docs-mcp` ### User Story As an AI agent on the pal-e platform I want all MCP tools to wrap the SDK (not raw httpx) and 7 new tools for blocks + delete_sprint So that I can interact with knowledge at the block level (90% token reduction) and the full SDK surface is available ### Context `pal-e-docs-sdk` v0.1.0 is now published on Forgejo PyPI (8f-1 complete). The SDK has 32 methods across 8 mixins. The MCP server currently has 26 tools making raw httpx calls (~794 lines). After this rewrite: 32 tools wrapping SDK methods (~250 lines). 100% SDK coverage. **The 7 new tools are the payoff** — 6 block tools (get_note_toc, list_blocks, get_section, update_block, create_block, delete_block) enable agents to work at sub-note granularity. Plus delete_sprint for full lifecycle. **Reference pattern:** `woodpecker-mcp` wrapping `woodpecker-sdk` — identical architecture. Read `~/woodpecker-mcp/src/woodpecker_mcp/server.py` for the proven `_ok(data: Any)` pattern. ### File Targets Files to modify: - `src/pal_e_docs_mcp/server.py` — swap httpx.Client for PalEDocsClient, change _ok/_error_response signatures - `src/pal_e_docs_mcp/tools/notes.py` — rewrite 7 tools to wrap SDK - `src/pal_e_docs_mcp/tools/sprints.py` — rewrite 10 tools + add delete_sprint - `src/pal_e_docs_mcp/tools/links.py` — rewrite 2 tools - `src/pal_e_docs_mcp/tools/projects.py` — rewrite 2 tools - `src/pal_e_docs_mcp/tools/repos.py` — rewrite 3 tools - `src/pal_e_docs_mcp/tools/tags.py` — rewrite 1 tool - `src/pal_e_docs_mcp/tools/__init__.py` — add blocks module registration - `pyproject.toml` — replace httpx with pal-e-docs-sdk, bump version to 0.2.0, add Forgejo PyPI index Files to create: - `src/pal_e_docs_mcp/tools/blocks.py` — 6 new block tools Files NOT to touch: - `src/pal_e_docs_mcp/__init__.py` — no changes needed - `src/pal_e_docs_mcp/__main__.py` — no changes needed ### Acceptance Criteria - [ ] server.py: `get_client()` replaced with `get_sdk()` returning `PalEDocsClient` - [ ] server.py: `_ok(data: Any)` takes parsed dict/list, returns `json.dumps(data, indent=2)`, returns `{"ok": true}` for None - [ ] server.py: `_error_response()` catches `PalEDocsError` hierarchy (NotFoundError, ValidationError, ServerError) - [ ] All 26 existing tools rewritten to call `get_sdk().method_name()` - [ ] 6 new block tools added in `tools/blocks.py`: get_note_toc, list_blocks, get_section, update_block, create_block, delete_block - [ ] 1 new sprint tool: delete_sprint - [ ] pyproject.toml: httpx replaced with `pal-e-docs-sdk>=0.1.0`, version bumped to 0.2.0 - [ ] Forgejo PyPI index configured so `uv run --directory` resolves the SDK - [ ] No raw httpx imports in any tool file - [ ] `ruff check` and `ruff format --check` pass - [ ] MCP server starts successfully: `uv run --directory ~/pal-e-docs-mcp python -m pal_e_docs_mcp` (ctrl-c after startup) - [ ] 32 total tools discoverable ### Test Expectations - [ ] Manual smoke test: start MCP server, verify it initializes without import errors - [ ] Manual smoke test: invoke `get_note_toc("plan-2026-02-26-tf-modularize-postgres")` — should return heading list - [ ] Manual smoke test: invoke `get_section("plan-2026-02-26-tf-modularize-postgres", "phases")` — should return phase table - [ ] Verify existing tools still work: invoke `get_note("agent-workflow")`, `list_tags()`, `search_notes(query="CNPG")` ### Constraints - **Param translation (8 tools):** MCP tool signatures MUST NOT change (backward compat). The wrapper does the translation: - `search_notes`: MCP `query` → SDK `q` - `create_note`/`update_note`: MCP `content` → SDK `html_content`; MCP `tags` CSV → SDK `list[str]`; MCP `project` → SDK `project_slug` - `update_note_links`: MCP `target_slugs` CSV → SDK `list[str]` - `create_sprint`: default `status="planning"` when not provided - `add_sprint_item`: default `position=0`; MCP `labels` CSV → SDK `list[str]` - `update_sprint`: only pass fields explicitly provided (SDK uses `_UNSET` sentinel) - `bulk_move_items`: `json.loads(items)` for the JSON string → list[dict] - **Follow woodpecker-mcp pattern exactly** for server.py structure - **Tool descriptions stay the same or improve** — never remove information from descriptions - **Forgejo PyPI index:** Use `[tool.uv.index]` in pyproject.toml or equivalent so `uv` resolves `pal-e-docs-sdk` from `https://forgejo.tail5b443a.ts.net/api/packages/forgejo_admin/pypi/simple` - **Block tool descriptions** should emphasize token efficiency: "Use get_note_toc to browse structure before fetching content", "Returns ~200 tokens instead of ~5000 for the full note" ### Checklist - [ ] PR opened - [ ] Lint passes - [ ] MCP server starts - [ ] All 32 tools discoverable - [ ] No unrelated changes ### Related - `phase-postgres-8f2-mcp-rewrite-core` — phase note in pal-e-docs - `phase-postgres-8f-mcp-rewrite` — parent phase with full audit findings - `project-pal-e-docs` — project page
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/pal-e-mcp#22
No description provided.