Damascus Entry Points P3: damascus-mcp server (stdio, 7 tools) #16
Reference in New Issue
Block a user
Delete Branch "feat/entry-points-mcp"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implements P3 of the entry-points work. The MCP server is a thin stdio wrapper around damascus-api: seven tools, each one HTTP call. No direct Postgres access — all data flows through the API.
Tool catalog (7)
list_itemsGET /v1/itemsget_itemGET /v1/items/{id}list_open_questionsGET /v1/issues?status=openanswer_questionPOST /v1/issues/{id}/answeringest_storyPOST /v1/itemsbulk_ingestPOST /v1/items/bulksystem_statusGET /v1/statsTool input schemas are derived from
Mcp*ArgsPydantic models viamodel_json_schema()— single source of truth, no hand-written JSON. The testtest_input_schemas_derived_from_mcp_args_modelsasserts no drift.Files
src/damascus/mcp_server.py(new, 404 lines) — mcp SDK stdio server + 7 toolssrc/damascus/api_schemas.py— addsMcpBulkIngestArgs+McpBulkIngestStoryItemsrc/damascus/cli.py— addsdamascus mcp-servesubcommandtests/contract/test_mcp_roundtrip.py(new, 524 lines) — 11 round-trip tests viahttpx.MockTransporttests/contract/test_mcp_cli.py(new, 77 lines) — CLI subcommand testspyproject.toml—mcp>=1.0dep,pytest-asynciodev extra,asyncio_mode = "auto"Acceptance
python -c "from damascus.mcp_server import mcp; print(len(mcp.list_tools()))"→7pytest tests/contract/test_mcp_roundtrip.py tests/contract/test_mcp_cli.py→ 14/14 passdamascus mcp-serve --helpworkspython -m damascus mcp-servewith EOF on stdin) exits cleanlyimport psycopg/DATABASE_URLreferences in mcp_server.py (no direct DB access)Drift / contract notes
The wiki (
wiki/concepts/entry-points-contract.md§5) names the bulk-ingest toolingest_project(server-side directory scan). The P3 task body names itbulk_ingest(client-supplied list). This PR follows the task body:McpBulkIngestArgs.storiesis a list ofMcpBulkIngestStoryItemitems, posted directly toPOST /v1/items/bulk. The wiki page is.gitignored (per repo.gitignore:wiki/) and lives in the separatekaykayyali/damascus-wikirepo — the schema file is the source of truth per the wiki itself, and the schema is what the MCP catalog is generated from.How to drive
Implements P3 of the entry-points work. The MCP server is a thin stdio wrapper around damascus-api: seven tools, each one HTTP call. No direct Postgres access — all data flows through the API. Tool catalog (7): - list_items → GET /v1/items - get_item → GET /v1/items/{id} - list_open_questions → GET /v1/issues?status=open - answer_question → POST /v1/issues/{id}/answer - ingest_story → POST /v1/items - bulk_ingest → POST /v1/items/bulk - system_status → GET /v1/stats Tool input schemas are derived from Mcp*Args Pydantic models via model_json_schema() — single source of truth, no hand-written JSON. Test test_input_schemas_derived_from_mcp_args_models asserts no drift. Adds: - src/damascus/mcp_server.py mcp SDK stdio server + 7 tools - tests/contract/test_mcp_roundtrip.py 11 round-trip tests via httpx.MockTransport - tests/contract/test_mcp_cli.py CLI subcommand tests - McpBulkIngestArgs / McpBulkIngestStoryItem in api_schemas.py - damascus mcp-serve CLI subcommand - pyproject.toml: mcp>=1.0 dep, pytest-asyncio dev extra, asyncio_mode=auto Acceptance: - python -c 'from damascus.mcp_server import mcp; print(len(mcp.list_tools()))' → 7 - pytest tests/contract/test_mcp_roundtrip.py tests/contract/test_mcp_cli.py → 14/14 pass - All 6 args-derived tools have zero schema drift