Why architecture matters here

MCP tools architecture matters because tools are where LLMs meet reality. Bad schemas = wrong tool picked; missing safety = accidents; no streaming = long tools feel broken.

Cost is modest — tool schema in bytes; execution is real work.

Reliability comes from structured results + error signaling + elicitation for missing info.

Advertisement

The architecture: every piece explained

Walk the diagram top to bottom.

Server tools/list. Server response listing available tools with schemas + descriptions.

Tool schema. JSON schema for arguments; JSON schema for result. Enables type safety + docs.

Client picks tool. LLM sees schema + description; picks tool + args based on user goal.

tools/call. Client → server RPC with tool name + args.

Structured result. content array + isError flag. Content items typed (text, image, resource).

Safety metadata. Annotations mark destructive, read-only, requires confirmation.

Elicitation. Server can ask user for missing info via elicitation/create.

Sampling. Server can request LLM completion via sampling/createMessage (if client supports).

Streaming progress. Long-running tools stream progress notifications.

Auth per tool. OAuth scopes required per tool declared in metadata.

Server tools/listadvertise capabilitiesTool schemaJSON schema args + resultClient picks toolvia LLMtools/callserver executesStructured resultcontent + isErrorSafety metadataannotationsElicitationserver asks userSamplingserver requests LLM callStreaming progresslong-running toolAuth per toolOAuth scopesWell-schemed tools = LLM picks correctly + safely
MCP tools architecture: server advertises schemas → LLM picks + calls → server executes → structured result; safety + elicitation + sampling + streaming supported.
Advertisement

End-to-end tool call flow

Trace a tool call. User asks agent to "post to Slack channel #general saying meeting starts in 5 minutes."

Agent client already has tools/list from Slack MCP server. LLM sees post_message tool with schema: channel (required), message (required), scheduled_time (optional).

LLM builds tools/call request: channel="general", message="meeting starts in 5 minutes".

Server receives; validates against schema. Missing scheduled_time is fine (optional).

Server posts to Slack via API; receives message ID.

Structured result: {content: [{type: "text", text: "Posted with ID abc123"}], isError: false}.

Alternative: user asks "delete the last three messages I sent." Server tool has annotation "destructive". Client shows confirmation dialog; user approves.

Alternative: user asks broadly. Server needs specific channel. Sends elicitation/create asking client to prompt user for channel.

Long-running: file processing tool. Server sends progress notifications every second: 25%, 50%, 75%, complete.