Skip to main content

Module mcp

Module mcp 

Source
Expand description

Model Context Protocol (MCP) HTTP handlers.

Exposes Materialize data products to AI agents via JSON-RPC 2.0 over HTTP POST.

Β§Endpoints

  • /api/mcp/agent - User data products for customer AI agents
  • /api/mcp/developer - System catalog (mz_*) for troubleshooting

Β§Tools

Agent: get_data_products, get_data_product_details, read_data_product, query Developer: query_system_catalog, query

read_data_product and both query tools are dyncfg-gated.

Data products are discovered via mz_internal.mz_mcp_data_products system view.

ModulesΒ§

error_codes πŸ”’
JSON-RPC 2.0 error codes.

StructsΒ§

CacheHints πŸ”’
Required on cacheable results, such as tools/list.
Capabilities πŸ”’
ClientInfo πŸ”’
CommonResultFields πŸ”’
ContentBlock πŸ”’
DiscoverResult πŸ”’
GetDataProductDetailsParams πŸ”’
InitializeParams πŸ”’
InitializeResult πŸ”’
McpError πŸ”’
McpHeaders πŸ”’
The request headers the Streamable HTTP transport defines, with every occurrence kept: a repeated header is rejected rather than reduced to one.
McpRequest πŸ”’
JSON-RPC 2.0 request. Requests have id; notifications don’t.
McpResponse πŸ”’
McpResultBody πŸ”’
A result as sent. common is None on 2025-11-25, whose results carry neither field.
NoArguments πŸ”’
Arguments of a tool that takes none. A struct rather than (): read from a serde_json::Value, () accepts {} only if serde buffers arguments ahead of name, which depends on key order (preserve_order keeps the client’s order).
QueryParams πŸ”’
QuerySystemCatalogParams πŸ”’
RawRequest πŸ”’
The body read as untyped JSON, for the 2026-07-28 checks on fields the typed parse drops. Only 2026-07-28 requests pay for the second read.
ReadDataProductParams πŸ”’
ResultMeta πŸ”’
ServerInfo πŸ”’
TableReferenceCollector πŸ”’
Collects table references from SQL AST with their schema qualification.
ToolAnnotations πŸ”’
MCP 2025-11-25 tool annotations that describe tool behavior. These hints help clients make trust and safety decisions.
ToolContentResult πŸ”’
ToolDefinition πŸ”’
ToolsListResult πŸ”’

EnumsΒ§

McpEndpointType πŸ”’
McpMethod πŸ”’
MCP method variants with their associated parameters.
McpRequestError πŸ”’
MCP request errors, mapped to JSON-RPC error codes.
McpResult πŸ”’
Typed MCP response results.
ProtocolVersion πŸ”’
The protocol revision a request is served on.
ToolName πŸ”’
The tool name a request’s Mcp-Name header must mirror.
ToolsCallParams πŸ”’
Tool call parameters, deserialized via adjacently tagged enum. Serde maps name to the variant and arguments to the variant’s data.

ConstantsΒ§

CACHE_TTL_MS πŸ”’
How long a client may consider a cacheable result fresh, in milliseconds. Kept short so flag changes reach clients soon.
DEFAULT_READ_LIMIT πŸ”’
Default row cap for read_data_product when the caller omits limit.
DETAILS_QUERY_PREFIX πŸ”’
DISCOVERY_QUERY πŸ”’
JSONRPC_VERSION πŸ”’
JSON-RPC protocol version used in all MCP requests and responses.
MCP_PROTOCOL_VERSION πŸ”’
MCP protocol version returned in the initialize response. Spec: https://modelcontextprotocol.io/specification/2025-11-25
READ_ONLY_ANNOTATIONS πŸ”’
Annotations for all MCP tools: read-only, non-destructive, idempotent.

FunctionsΒ§

answer_parse_failure πŸ”’
Answers a 2026-07-28 request whose body did not parse, in JSON-RPC. One that passes check_modern_request gets 404 for a method 2026-07-28 does not define, and -32602 otherwise. Other rejections keep axum’s response.
as_unknown_method πŸ”’
The request body would produce if McpMethod::Unknown accepted params, or None when its method is one we know, whose parse error must stand.
asks_for_2026_07_28 πŸ”’
Whether any MCP-Protocol-Version copy names 2026-07-28, also inside a comma-joined list. Whether it is served on it also depends on the flag (see ProtocolVersion::select).
build_read_query πŸ”’
Builds the SQL the agent runs for read_data_product.
call_status πŸ”’
Maps a handler result to its metric McpCallStatus. Errors carry the closed error_type() label; anything else is Ok.
check_modern_request πŸ”’
Runs the checks every 2026-07-28 request gets before dispatch: a JSON-RPC 2.0 envelope, the mirrored headers, and params._meta.
check_request_meta πŸ”’
Checks the params._meta fields every 2026-07-28 request must carry: the protocol version, matching its header, and the client capabilities.
decode_mcp_name πŸ”’
Decodes the =?base64?...?= form clients use for names that are not plain ASCII. Any other value is the name as is.
default_read_limit πŸ”’
deserialize_tools_call πŸ”’
arguments is optional in the MCP spec, but adjacent tagging requires the content key, so a call that omits it, or sends null, is given {}.
endpoint_instructions πŸ”’
Instructions returned by initialize and server/discover for each endpoint type. These guide the AI agent on how to use the server correctly.
execute_query πŸ”’
execute_sql πŸ”’
Execute SQL via execute_request from sql.rs.
format_rows_response πŸ”’
Serialize rows to JSON and enforce the response size cap.
get_data_product_details πŸ”’
get_data_products πŸ”’
handle_discover πŸ”’
handle_initialize πŸ”’
handle_mcp_agent
Agent endpoint: exposes user data products.
handle_mcp_developer
Developer endpoint: exposes system catalog (mz_*) only.
handle_mcp_method πŸ”’
handle_mcp_method_not_allowed
MCP 2025-11-25 requires servers to return 405 for GET requests on endpoints that only support POST.
handle_mcp_request πŸ”’
handle_mcp_request_inner πŸ”’
handle_tools_call πŸ”’
handle_tools_list πŸ”’
header_text πŸ”’
invalid_id πŸ”’
is_json_content_type πŸ”’
The Content-Type check axum’s Json extractor runs before parsing.
is_valid_request_id πŸ”’
MCP request ids are strings or numbers. Any other id, null included, gets -32600 with no id in the reply.
parse_mcp_request πŸ”’
Parses a request body the way axum’s Json extractor does, so every rejection keeps its status and text. The one exception: an unknown method that carries params becomes McpMethod::Unknown instead of a 422 (see as_unknown_method). The body arrives through Bytes, so the route’s DefaultBodyLimit still applies.
present_id πŸ”’
Wraps a null id in Some, so it stays a request. A missing id is None through #[serde(default)] on the field, and only that is a notification.
query_set_clause πŸ”’
Builds the SET clause for execute_query: always SET CLUSTER, plus SET CLUSTER_REPLICA when a replica is requested (e.g. for EXPLAIN ANALYZE on a cluster with multiple replicas). Both names pass through escaped_string_literal since they are interpolated into SQL string literals.
query_system_catalog πŸ”’
read_data_product πŸ”’
Read rows from a data product. Issues a single read-only query.
read_only_txn πŸ”’
Wraps body in a BEGIN READ ONLY; <set_clause>; <body>; COMMIT; frame so set_clause is scoped to this read and does not leak into the session.
safe_data_product_name πŸ”’
Parses a data product name and returns it safely quoted for SQL interpolation.
select_single_rows πŸ”’
Returns the rows of the single row-returning statement in a response.
server_info πŸ”’
validate_cluster_replica πŸ”’
Rejects an empty or whitespace-only cluster_replica. Such a name would otherwise produce SET CLUSTER_REPLICA = '', which fails deep in the engine as a generic execution error rather than a clean validation error. None (no replica pin requested) is always valid.
validate_origin πŸ”’
Validates the Origin header against the CORS allowlist to prevent DNS rebinding attacks (MCP spec 2025-11-25). Returns Some(403) if Origin is present but not on the allowlist. Returns None if absent (non-browser client) or allowed.
validate_readonly_query πŸ”’
Validates query is a single SELECT, SHOW, or EXPLAIN statement.
validate_system_catalog_query πŸ”’
Validates that a query only references system catalog tables.