CCDV-F · Tools and MCPs
MCP servers: tools, resources, prompts and transport
A data team wrote an MCP server with read-only queries over its metrics warehouse. Each engineer runs it on their own machine, launched by Claude Code. Now a chatbot in the cloud, analysts on Claude Desktop and an Agent SDK agent want to use it, and the warehouse credentials can’t leave the server. Solving it takes understanding two things: what the server exposes and how it communicates.
The pieces
- Host: the application the person or agent works with (Claude Code, Claude Desktop, your app).
- Client: the component of the host that keeps the connection to a server.
- Server: the program that exposes capabilities. It’s written with the official SDKs (Python, TypeScript and others) and speaks JSON-RPC.
Three primitives, three owners
The question for choosing the primitive is who decides when it’s used:
| Primitive | Who controls it | What for |
|---|---|---|
| Tools | The model | Actions and queries Claude decides to make during the conversation: search contracts, create a draft |
| Resources | The application | Read-only context identified by a URI, which the host shows, selects and attaches: a clause library, a database schema |
| MCP prompts | The user | Templates with arguments that the person invokes on purpose, for example as a slash command: “Review an NDA” with counterparty and jurisdiction |
Resources can be fixed or URI templates with parameters (clauses://{type}). MCP tools follow the same design rules as any tool: clear descriptions and errors with isError and a useful message.
Transport: local or remote
stdio transport:
- the host launches the server as a subprocess and they communicate over standard input and output;
- it’s for a local server, for one person, on their machine;
- only protocol messages may go out on stdout: a debugging
printbreaks the connection, and logs go to stderr.
Streamable HTTP:
- the server is an independent process that serves many clients on a single endpoint (POST and GET), with optional SSE for sending multiple messages;
- it replaced the HTTP+SSE transport from the protocol’s early versions;
- it’s for a shared remote server: deployed, updated and monitored in one place;
- it requires authentication (OAuth is recommended for remote servers), validating the
Originheader and, if it runs locally, listening only on localhost.
In the warehouse case, the way out is a remote server over Streamable HTTP with per-user authentication, with the warehouse credentials on the server side. Handing out a stdio package for each group to run with its own keys multiplies the credentials and the versions.
Integrating it
- Claude Code: added with
claude mcp addor in a.mcp.jsonin the repository to share it with the team; its tools show up asmcp__<server>__<tool>and are controlled with the same permissions. - Claude Desktop and claude.ai: as a connector.
- Agent SDK: in the agent’s MCP server configuration.
- Messages API: with the MCP connector, which connects to remote servers.
The usual traps
- Exposing as a tool something that’s reference material the app should attach, or as a resource a flow the user has to start.
- Writing logs to stdout in a stdio server.
- Distributing local copies with credentials to each team instead of a remote server.
- A remote server without authentication, or listening on every interface on a local machine.
- Passing the backend system’s credentials to the clients.
On the exam
For primitives, ask who decides: the model (tool), the application (resource) or the user (prompt). For transport, ask how many use it and where it runs: one person on their machine, stdio; several applications against a single deployment, Streamable HTTP with authentication and credentials on the server.
Quick question
A practice exam question on this domain. It counts towards your progress.
A data-platform team wrote an MCP server that exposes read-only queries over their metrics warehouse. During development each engineer ran it locally with the stdio transport, launched by Claude Code as a subprocess on their own machine.
Now three other groups want to use it: a support chatbot running in the company cloud, analysts on Claude Desktop, and an internal agent built with the Agent SDK. The platform team wants a single deployment they can update and monitor, with access controlled per user.
The warehouse credentials must stay on the server side.
How should the team deploy the server?