The server always returns empty capabilities {} in the initialize response, even when tools, prompts, or resources are registered. This causes MCP clients (including the official MCP Inspector) to disable their Tools/Prompts/Resources tabs.
Steps to Reproduce
- Register tools via
server->AddTool(...)
- Start server
- Send initialize request
- Response:
{
"result": {
"capabilities": {}, // <-- empty, should show {"tools": {}}
"serverInfo": {"name": "...", "version": "..."}
}
}
- MCP Inspector shows "The connected server does not support any MCP capabilities" and grays out all tabs
Root Cause
Two issues:
1. Serializer hardcodes empty object — In src/shared/jsonrpc.cpp, the InitializeResult serializer:
// Line ~90 in adl_serializer<Mcp::InitializeResult>::to_json
j["capabilities"] = json::object(); // Always empty, ignores r.capabilities
This ignores the actual r.capabilities field entirely.
2. Capabilities never set — ServerSession::SetServerCapabilities() exists but is never called anywhere in the codebase. Even if the serializer is fixed, capabilities would still be empty because no code sets them when tools are registered.
Proposed Fix
Fix 1 — Serialize actual capabilities (src/shared/jsonrpc.cpp):
j["capabilities"] = json::object();
if (r.capabilities.tools.has_value()) { j["capabilities"]["tools"] = json::object(); }
if (r.capabilities.prompts.has_value()) { j["capabilities"]["prompts"] = json::object(); }
if (r.capabilities.resources.has_value()) { j["capabilities"]["resources"] = json::object(); }
Fix 2 — Auto-set capabilities on session creation (src/server/server_manager.cpp):
After creating a session, set default capabilities:
auto session = std::make_shared<ServerSession>(transport, config_, sessionId);
Mcp::ServerCapabilities caps;
caps.tools = Mcp::ToolsCapabilities{};
session->SetServerCapabilities(caps);
Ideally, capabilities should be set dynamically based on what's registered (tools → tools, prompts → prompts, etc.).
Impact
- Every MCP server built with this SDK advertises zero capabilities
- No MCP client can discover the server's tools without prior knowledge
- MCP Inspector is unusable without this fix
- This would likely be flagged during LF conformance review
Additional Issue: Case-Sensitive Accept Header
The server's HTTP parser rejects requests with uppercase Accept: header (e.g., Accept: application/json, text/event-stream) but accepts lowercase accept:. Per RFC 7230, HTTP headers are case-insensitive. This prevents the MCP Inspector and browsers from connecting directly — a CORS proxy is needed as a workaround.
Location: src/server/transport/streamable_http_server_transport.cpp, line ~185.
Environment
- MCP C++ SDK from
openJiuwen-ai/agent-protocol
- Tested via MCP Inspector v0.21.1, curl, and custom web UI
Tools shows grayed out (this image contains the fixes above to fix this issue)

The server always returns empty capabilities
{}in theinitializeresponse, even when tools, prompts, or resources are registered. This causes MCP clients (including the official MCP Inspector) to disable their Tools/Prompts/Resources tabs.Steps to Reproduce
server->AddTool(...){ "result": { "capabilities": {}, // <-- empty, should show {"tools": {}} "serverInfo": {"name": "...", "version": "..."} } }Root Cause
Two issues:
1. Serializer hardcodes empty object — In
src/shared/jsonrpc.cpp, theInitializeResultserializer:This ignores the actual
r.capabilitiesfield entirely.2. Capabilities never set —
ServerSession::SetServerCapabilities()exists but is never called anywhere in the codebase. Even if the serializer is fixed, capabilities would still be empty because no code sets them when tools are registered.Proposed Fix
Fix 1 — Serialize actual capabilities (
src/shared/jsonrpc.cpp):Fix 2 — Auto-set capabilities on session creation (
src/server/server_manager.cpp):After creating a session, set default capabilities:
Ideally, capabilities should be set dynamically based on what's registered (tools →
tools, prompts →prompts, etc.).Impact
Additional Issue: Case-Sensitive Accept Header
The server's HTTP parser rejects requests with uppercase
Accept:header (e.g.,Accept: application/json, text/event-stream) but accepts lowercaseaccept:. Per RFC 7230, HTTP headers are case-insensitive. This prevents the MCP Inspector and browsers from connecting directly — a CORS proxy is needed as a workaround.Location:
src/server/transport/streamable_http_server_transport.cpp, line ~185.Environment
openJiuwen-ai/agent-protocolTools shows grayed out (this image contains the fixes above to fix this issue)
