ExMCP.Server.Dispatch (ex_mcp v1.0.0-rc.8)

Copy Markdown View Source

Single MCP method table for handler modules invoked with their own state.

ExMCP.Server.HandlerServer (test/BEAM transports) and ExMCP.Server.StdioServer both drive an ExMCP.Server.Handler module by calling its callbacks with the handler state and turning the return value into a JSON-RPC response. They used to carry two independently maintained copies of that table, which drifted: stdio never implemented completion/complete, resources/subscribe, roots/list, logging/setLevel or the task methods, and the two copies normalized tool results differently.

This module owns the table. Transports keep their own framing (stdout lines vs. transport send_message/2), batching, and cancellation bookkeeping, and delegate callback invocation plus result shaping here. Shaping itself lives in ExMCP.Server.ResultNormalizer, which the HTTP message processor also shares, so every transport agrees on tool-result shape and on which error detail is safe to return.

Return value

  • {:response, response_map, new_handler_state} for requests
  • {:notification, new_handler_state} for notifications (no response)

Callbacks that ExMCP.Server.Handler marks optional are probed with function_exported?/3; a handler that does not implement one answers -32601 Method not found.

Summary

Functions

Dispatches a decoded JSON-RPC request or notification to handler_module.

Whether method is part of the shared MCP method table.

Returns the list of MCP methods handled by this dispatcher.

Types

handler_state()

@type handler_state() :: term()

result()

@type result() ::
  {:response, map(), handler_state()} | {:notification, handler_state()}

Functions

dispatch(request, handler_module, handler_state)

@spec dispatch(map(), module(), handler_state()) :: result()

Dispatches a decoded JSON-RPC request or notification to handler_module.

known_method?(method)

@spec known_method?(String.t()) :: boolean()

Whether method is part of the shared MCP method table.

methods()

@spec methods() :: [String.t()]

Returns the list of MCP methods handled by this dispatcher.

tool_arguments(params)

@spec tool_arguments(map()) :: map()

Builds the argument map handed to ExMCP.Server.Handler.handle_call_tool/3.

Request-level _meta (which carries progressToken) lives beside arguments in the JSON-RPC params, but ExMCP.Server.Handler documents it as reachable from the arguments map, so it is merged in here. Arguments that already carry their own _meta win.