Skip to content

Upgrade mcp dependency from 1.x to 2.0 - #40

Draft
shreddd with Copilot wants to merge 4 commits into
mainfrom
copilot/upgrade-mcp-dependency-to-20
Draft

Upgrade mcp dependency from 1.x to 2.0#40
shreddd with Copilot wants to merge 4 commits into
mainfrom
copilot/upgrade-mcp-dependency-to-20

Conversation

Copilot AI commented Aug 14, 2026

Copy link
Copy Markdown

mcp 2.0 changes the low-level Server API: the @server.list_tools() / @server.call_tool() decorators are replaced by on_list_tools / on_call_tool constructor kwargs, handlers take (ctx, params) instead of (tool_name, arguments), and server.request_handlers[...] and response .root unwrapping are removed. In dsagt only the dispatch shell and the test harness touch the SDK Server object; the four *_tools.py concern modules build types.Tool(...) and return plain str/dict, which is a dsagt-internal contract and is unchanged.

Fixes #39.

Dependency
pyproject.toml: mcp>=1.0.0,<2.0.0 → mcp>=2.0.0,<3.0.0. The upper bound is pinned because the SDK has now shipped two breaking majors. The lockfile resolves to mcp 2.1.1; all verification below ran against that version.

Dispatch shell (src/dsagt/mcp/server.py)
build_dispatch_server():

Passes on_list_tools / on_call_tool callables to Server(...) instead of using the removed decorators.
on_list_tools returns types.ListToolsResult(tools=...) instead of a bare list.
on_call_tool(ctx, params) reads params.name / params.arguments and returns types.CallToolResult(content=[...]) instead of a bare content list.
on_call_tool rejects a missing or non-dict params.arguments with a ValueError rather than defaulting silently.
Per-tool dispatch (span opening, ValueError → error dict, str-vs-dict formatting) is unchanged.

async def on_call_tool(ctx, params: types.CallToolRequestParams) -> types.CallToolResult:
tool_name = params.name
arguments = params.arguments
handler = handlers[tool_name]
...
return types.CallToolResult(content=[types.TextContent(type="text", text=text)])

return Server(name, on_list_tools=on_list_tools, on_call_tool=on_call_tool)
_run_stdio, create_dsagt_server, and main() are untouched: mcp.server.stdio.stdio_server, NotificationOptions, InitializationOptions, and server.get_capabilities(...) are stable across the bump.

Test harness
tests/mcp_helpers.py (call_tool_sync / call_tool_async) uses server.get_request_handler("tools/call" | "tools/list").handler in place of the removed server.request_handlers[...] dict, and drops the .root unwrap.
The inline copies of that helper in test_dsagt_server.py, test_kb_search_filters.py, test_knowledge_server.py, and test_memory_tools.py are replaced by the shared mcp_helpers.py versions.
tool.inputSchema reads in tests are changed to tool.input_schema; mcp 2.0 renamed the Python attribute on types.Tool. The inputSchema= constructor kwarg still works through the pydantic alias, so production tool-building code is unaffected.
The subprocess-based helpers (mcp_call_tool, mcp_initialize) exercise the wire protocol and needed no change.
Verification
Rebased onto main after #41 (Template compliance); no conflicts. uv sync --all-groups after the rebase produced no lock change.

uv run --no-sync python -m pytest tests/test_dsagt_server.py tests/test_registry_server.py
tests/test_knowledge_server.py tests/test_memory_tools.py tests/test_skill_tools.py
tests/test_kb_search_filters.py tests/test_server_startup.py -q

121 passed

uv run ruff check src/dsagt/mcp tests/mcp_helpers.py tests/test_dsagt_server.py
tests/test_kb_search_filters.py tests/test_knowledge_server.py tests/test_memory_tools.py

All checks passed

uv run black --check

6 files would be left unchanged

test_server_startup.py starts the real server over stdio and is the direct check for the 'Server' object has no attribute 'list_tools' failure reported in #39 with a fresh mcp 2.x install.

Copilot AI linked an issue Aug 14, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Upgrade mcp dependency from 1.x to 2.0 Upgrade mcp dependency from 1.x to 2.0 Aug 14, 2026
Copilot AI requested a review from shreddd August 14, 2026 18:48
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://AI-ModCon.github.io/dsagt/pr-preview/pr-40/

Built to branch gh-pages at 2026-08-28 14:57 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@ajtritt
ajtritt requested a review from a team August 17, 2026 20:22
@jeanbez

jeanbez commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

While testing, I saw these two:

  1. Previously @server.call_tool() validated against inputSchema by default, which does not seem to be the case now, so every malformed agent call now reaches the handler raw. This should resolve that:
    jsonschema.validate(instance=arguments, schema=schemas[tool_name])
except jsonschema.ValidationError as e:
    result = {"status": "error", "error": f"Input validation error: {e.message}"}

Plus this in server.py line 92 (after tool_category):

schemas = {tool.name: tool.input_schema for tool in tools}
  1. arguments can be None. The PR does arguments = params.arguments adding or {} should resolve the issue
arguments = params.arguments or {}

Together they turn a clean Input validation error: 'query' is a required property into Unexpected error: 'NoneType' object is not subscriptable, plus a full traceback in the server log for what is a client-side error.

@shreddd

shreddd commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@jeanbez - we don't strictly need to accept this PR either. Let's discuss more today.

aarontuor
aarontuor previously approved these changes Aug 25, 2026

@aarontuor aarontuor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Straightforward changes updating to mcp >2.0. Tested and no regressions or side effects but was able to recreate the fault Jean Luca described. Was able to recreate Jean Luca's bug though.

@aarontuor
aarontuor dismissed their stale review August 25, 2026 20:56

Was able to recreate Jean Luca's bug.

Copilot AI and others added 4 commits August 28, 2026 07:55
Co-authored-by: shreddd <143514+shreddd@users.noreply.github.com>
Co-authored-by: shreddd <143514+shreddd@users.noreply.github.com>
The mcp 2.x server invokes on_call_tool without validating arguments
against the tool's input_schema, and params.arguments is None when
omitted. Malformed calls reached handlers raw and returned
"Unexpected error: 'NoneType' object is not subscriptable" plus a
server-log traceback for what is a client-side error.

Coerce None arguments to {} and validate with jsonschema before
dispatch, so a malformed call returns "Input validation error: 'query'
is a required property" as under mcp 1.x. Validation runs before the
categorization span, matching 1.x, where rejected calls never reached
dsagt code. Declare jsonschema as a direct dependency (previously only
transitive via mcp).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@aarontuor
aarontuor force-pushed the copilot/upgrade-mcp-dependency-to-20 branch from 6f1580a to 86d2a0f Compare August 28, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade mcp dependency from 1.x to 2.0

4 participants