Skip to content

[MCP] Respond to stdio initialize before metadata inference - #3805

Draft
Souvik Ghosh (souvikghosh04) wants to merge 2 commits into
mainfrom
Usr/sogh/mcp-stdio-initialize-latency
Draft

[MCP] Respond to stdio initialize before metadata inference#3805
Souvik Ghosh (souvikghosh04) wants to merge 2 commits into
mainfrom
Usr/sogh/mcp-stdio-initialize-latency

Conversation

@souvikghosh04

@souvikghosh04 Souvik Ghosh (souvikghosh04) commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Why make this change?

Fixes #3430.

MCP stdio currently performs database schema introspection before entering the JSON-RPC read loop. For remote databases with many entities, clients can time out waiting for the initialize response even though the process and database are healthy.

Related: #3783 and #3784. This change also ensures stdio initializes metadata providers without starting the HTTP host.

What is this change?

  • Enter the MCP stdio protocol loop before database metadata inference and tool registration.
  • Defer that work until the first tools/list or valid tools/call request.
  • Cache the initialization task so repeated requests cannot run inference more than once.
  • Await initialization before reading or executing tools, including metadata-enriched custom tool schemas.
  • Add a deterministic test that blocks metadata inference and verifies initialize responds while tools/list remains pending.

How was this tested?

  • Integration Tests
  • Unit Tests

Focused MCP stdio, protocol, and registry suite: 76 passed, 0 failed.

dotnet format --verify-no-changes and git diff --check also pass.

Sample Request(s)

Send initialize, notifications/initialized, then tools/list over stdin. The initialize response is emitted immediately; tools/list waits until schema inference and tool registration complete.

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

Defer metadata provider initialization and tool registration until the first tools/list or tools/call request so the MCP handshake is not blocked by schema introspection.

Fixes #3430
Register a no-op metadata provider factory in the shared protocol test service provider so lazy tool initialization can complete for pre-populated test registries.

Copilot AI 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.

🔵 Needs a closer look

Approval assessments are split, and the lazy DI tool-registration path lacks direct coverage.

Pull request overview

Defers MCP stdio metadata inference and tool registration so initialize can respond immediately.

Changes:

  • Lazily caches metadata and tool initialization.
  • Awaits initialization for tool listing and execution.
  • Adds deterministic initialization-order tests.
File summaries
File Description
src/Service/Utilities/McpStdioHelper.cs Removes eager tool registration.
src/Service.Tests/UnitTests/McpStdioServerRunAsyncTests.cs Tests response timing and cached initialization.
src/Service.Tests/UnitTests/McpStdioServerProtocolTests.cs Provides no-op metadata initialization for protocol tests.
src/Azure.DataApiBuilder.Mcp/Core/McpStdioServer.cs Adds lazy metadata and tool initialization; direct coverage of DI-based tool registration remains requested as a nit.
Review details

Suppressed comments (1)

src/Azure.DataApiBuilder.Mcp/Core/McpStdioServer.cs:331

  • Please add coverage for the new lazy registration path. The blocking test registers no IMcpTool, while the protocol tests pre-populate McpToolRegistry, so all tests still pass if these registration lines are removed. Register a tool through DI and assert that it appears in tools/list (ideally also verifying a custom tool's metadata is enriched only after inference completes).
            IEnumerable<IMcpTool> tools = _serviceProvider.GetServices<IMcpTool>();
            McpToolRegistry.InitializeAndRegisterTools(tools, _toolRegistry, _serviceProvider);
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@souvikghosh04

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).

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

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

--mcp-stdio blocks initialize response until all schema introspection completes, causing MCP reconnect timeouts

2 participants