How the MCP JSON-RPC 2.0 Protocol Handles Tool Calling: A Complete Technical Guide
The MCP JSON-RPC 2.0 protocol executes tool calls through the tools/call method, which parses requests in cbm_jsonrpc_parse(), dispatches them via cbm_mcp_server_handle() in src/mcp/mcp.c, validates permissions against a static TOOLS[] array, and returns structured responses with strict error handling.
The DeusData/codebase-memory-mcp repository implements a memory-code-portal server that exposes graph-analysis capabilities through a JSON-RPC 2.0 interface. Understanding how the MCP JSON-RPC 2.0 protocol handles tool calling is essential for integrating with its 14 self-describing graph tools, which range from search_graph to trace_path and execute through a unified tools/call endpoint.
The Three-Stage Tool Execution Flow
The tools/call implementation follows a strict pipeline defined in src/mcp/mcp.c, splitting execution into parsing, dispatch, and validation phases.
Stage 1: Request Parsing with cbm_jsonrpc_parse()
Every tool call begins with cbm_jsonrpc_parse() (lines 1082‑1085), which reads the incoming line from stdin or HTTP and extracts the jsonrpc version, method name, request id, and raw params JSON string. The parser supports string-based identifiers as per RFC §4, handling both numeric and string values for the v_id field to ensure compatibility with diverse JSON-RPC clients.
Stage 2: Method Dispatch in cbm_mcp_server_handle()
Inside the main server loop cbm_mcp_server_handle, the protocol compares the method string against known verbs. The critical branch for tool invocation appears at line 10851:
else if (strcmp(req.method, "tools/call") == 0) { … }
This block extracts the tool name from the params payload and routes the request toward validation. The dispatch mechanism treats tools/call as a first-class RPC method while maintaining separation between transport logic and business logic.
Stage 3: Tool Validation and Invocation
Validation occurs through multiple layers before execution:
- Tool Discovery: The static
TOOLS[]array (line 47) holds every tool definition including name, title, description, and input schema. - Profile Checking:
mcp_tool_allowed()(lines 10830‑10857) verifies the requested tool is permitted for the current MCP profile (analysis,scout, orall). - Annotation Lookup:
mcp_tool_annotations()(lines 10888‑10895) provides behavior hints such asreadOnlyHintordestructiveHint. - Execution: Once validated, the server invokes concrete implementations like
cbm_search_graph()orcbm_trace_path().
Errors during any phase convert to JSON-RPC error objects via cbm_jsonrpc_format_error() (lines 10846‑10858).
Tool Discovery and Schema Definition
The protocol implements self-describing APIs through unified schema definitions. Each tool advertises its inputSchema derived from the tool_def_t structure and a generic outputSchema defined by MCP_TOOL_OUTPUT_SCHEMA.
The function mcp_add_tool_def() (lines 10810‑10818) attaches these schemas to the tool JSON object, enabling clients to query tools/list and discover exact parameter requirements before invocation. For large toolsets, pagination occurs via the MCP_TOOLS_PAGE_SIZE constant (line 10836), with cursor logic implemented in mcp_tools_cursor_offset() (lines 10887‑10923) to support incremental fetching without overwhelming the transport layer.
Profile-Based Access Control and Annotations
Security enforcement happens at the protocol layer through profile-based restrictions. The mcp_tool_allowed() function checks whether the current session profile permits access to the requested tool, preventing unauthorized access to destructive operations in restricted modes like scout or analysis.
Behavioral metadata comes from mcp_tool_annotations(), which supplies boolean hints describing tool side effects. These annotations allow clients to display warnings for destructive operations or optimize read-only queries without executing the tool.
Strict JSON-RPC 2.0 Error Handling
The implementation adheres strictly to the JSON-RPC 2.0 specification with standardized error codes generated by cbm_jsonrpc_format_error():
- Parse error (-32700): Returned when the request JSON is malformed or cannot be parsed.
- Method not found (-32601): Triggered when the method string (including misspelled tool names) does not match any registered handler.
- Invalid params (-32602): Raised when required fields are missing from the tool's input schema or parameter types mismatch.
This strict error taxonomy ensures predictable client behavior and simplifies debugging across different transport implementations.
Transport-Agnostic Implementation
The core logic remains transport-neutral, functioning identically across stdio and HTTP interfaces. The HTTP server (src/ui/http_server.c, line 1595) extracts POST request bodies and forwards them directly to cbm_mcp_server_handle, allowing the same tools/call processing pipeline to serve both local subprocesses and remote HTTP clients without code duplication.
Practical Code Examples
Requesting the tool catalog requires no parameters:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
Invoking a specific tool uses the tools/call method with the tool name in the params:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_graph",
"project": "my-repo",
"query": "update settings",
"limit": 20,
"format": "json"
}
}
A minimal C client implementation:
#include "mcp/mcp.h"
int main(void) {
const char *req = "{\"jsonrpc\":\"2.0\",\"id\":42,\"method\":\"tools/call\","
"\"params\":{\"name\":\"search_graph\",\"project\":\"demo\","
"\"query\":\"cache\",\"limit\":5}}";
cbm_mcp_server_t *srv = cbm_mcp_server_new();
char *resp = cbm_mcp_server_handle(srv, req);
printf("%s\n", resp);
free(resp);
cbm_mcp_server_free(srv);
return 0;
}
Summary
- The MCP JSON-RPC 2.0 protocol handles tool calling through the dedicated
tools/callmethod implemented insrc/mcp/mcp.c. - Execution follows a three-stage pipeline: parsing via
cbm_jsonrpc_parse(), dispatch throughcbm_mcp_server_handle(), and validation usingmcp_tool_allowed()against the staticTOOLS[]array. - Self-describing schemas enable automatic tool discovery through
tools/list, with pagination support viamcp_tools_cursor_offset(). - Profile-based access control restricts tool availability based on
analysis,scout, orallprofiles, supplemented by behavioral annotations frommcp_tool_annotations(). - Strict RFC-compliant error handling returns standard JSON-RPC error codes (-32700, -32601, -32602) for parse, method, and parameter failures.
- The architecture is transport-agnostic, supporting both stdio and HTTP interfaces through the same core logic in
cbm_mcp_server_handle().
Frequently Asked Questions
What JSON-RPC method invokes tools in the MCP protocol?
Tools are invoked through the tools/call method. This single endpoint handles all 14 graph-analysis tools (such as search_graph and trace_path) by extracting the specific tool name from the params object and routing to the appropriate implementation after validation checks.
How does the MCP server validate tool permissions before execution?
Validation occurs via mcp_tool_allowed() (lines 10830‑10857), which checks the requested tool against the current session profile. The server maintains a static TOOLS[] array at line 47 containing all tool definitions, and only executes tools permitted for the active profile (analysis, scout, or all).
What error codes does the MCP protocol return for invalid tool calls?
The server returns standard JSON-RPC 2.0 error codes: -32700 for parse errors (malformed JSON), -32601 for method not found (unknown tool names), and -32602 for invalid parameters (missing required fields or schema violations). These are generated by cbm_jsonrpc_format_error() at lines 10846‑10858.
Can the MCP tool calling mechanism work over HTTP or only stdio?
The implementation is transport-agnostic. While designed primarily for stdin/stdout communication, the same tools/call logic supports HTTP transport through src/ui/http_server.c (line 1595), which extracts POST bodies and forwards them to cbm_mcp_server_handle() without modifying the core execution flow.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →