Skip to content

fix(mcp): isolate structured tool output per request#504

Closed
cdayAI wants to merge 1 commit into
mainfrom
codex/fix-shared-mcp-structured-result-race-17kmmc
Closed

fix(mcp): isolate structured tool output per request#504
cdayAI wants to merge 1 commit into
mainfrom
codex/fix-shared-mcp-structured-result-race-17kmmc

Conversation

@cdayAI
Copy link
Copy Markdown
Owner

@cdayAI cdayAI commented May 31, 2026

Motivation

  • The server stored action-tool structured output in a mutable MCPServer instance field which is shared across concurrent HTTP requests, allowing a race where one request can read or overwrite another request's structuredContent (leak/wrong-goal responses).
  • The HTTP transport dispatches requests concurrently with asyncio.to_thread() against a single MCPServer instance, so the per-call structured value must be request-local to be safe.

Description

  • Replace the instance-level _structured_override with a request-local ContextVar named _STRUCTURED_OVERRIDE so structured output is isolated to the current call. (_STRUCTURED_OVERRIDE: ContextVar[...]) in packages/maverick-mcp/maverick_mcp/server.py.
  • Update handle_tools_call to set the ContextVar to None at call start, use the token to reset() it in a finally block, and read the request-local value with _STRUCTURED_OVERRIDE.get() when assembling structuredContent.
  • Change maverick_start and maverick_resume handlers to write their structured result with _STRUCTURED_OVERRIDE.set({...}) instead of writing self._structured_override.
  • Add a concurrent regression test test_structured_override_is_request_local in packages/maverick-mcp/tests/test_server.py which simulates two overlapping maverick_start calls and asserts each call receives matching text and structuredContent.

Testing

  • Ran style checks with ruff check and applied fixes; linter passed on the modified files.
  • Ran unit tests via PYTHONPATH=packages/maverick-mcp:packages/maverick-core:packages/maverick-shield pytest packages/maverick-mcp/tests/test_server.py and all tests passed: 27 passed.
  • An initial pytest packages/maverick-mcp/tests/test_server.py run failed in this environment due to import path resolution, after setting PYTHONPATH the full test suite passed.

Codex Task

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant