This cheat sheet is the field reference for building, reviewing, debugging, and operating MCP systems. It condenses the course into the decisions engineers actually make: which capability type to expose, which transport to choose, how discovery works, what to log, where authorization belongs, and how to verify a server before a real host depends on it.
Use it as a design review checklist before implementation, a debugging map when a host integration fails, and a production readiness guide before exposing MCP capabilities to internal users or enterprise systems.
The point is not to memorize every method name. The point is to keep the protocol boundaries clear: hosts orchestrate user experience, clients manage sessions, servers expose capabilities, transports carry JSON-RPC messages, and authorization decides whether a requested capability should execute.
For every MCP design decision, ask four questions in order: what capability am I exposing, how will the host discover it, what context or identity is allowed to reach it, and what observable evidence will prove it behaved correctly?
| Need | Use | Why | Typical Examples |
|---|---|---|---|
| Perform an operation with side effects or computed output | Tool | Tools are invokable functions with input schemas, validation, execution, and structured results. | Create ticket, query database, run search, summarize repository state, trigger workflow |
| Expose canonical data for the model to read | Resource | Resources are addressable pieces of context with stable URIs and optional metadata. | Design doc, repo file, customer profile, runbook, schema, incident timeline |
| Package a reusable interaction pattern | Prompt | Prompts turn repeated model workflows into named templates with arguments. | Code review prompt, incident triage prompt, migration planning prompt |
| Constrain filesystem or workspace access | Roots | Roots tell servers which local boundaries the host has made available. | Current project folder, selected workspace, mounted docs directory |
| Protect remote capabilities | Authorization | Remote servers need identity, consent, scopes, and policy enforcement before sensitive operations run. | OAuth-protected HR data, Jira write access, compliance search |
| Connect a local host to a local process | stdio transport | The host owns process startup and communicates over stdin/stdout. | Claude Desktop local filesystem server, IDE helper server |
| Expose MCP over the network | Streamable HTTP transport | The server is independently deployed and can integrate with enterprise auth, routing, scaling, and observability. | Company knowledge server, SaaS connector, shared workflow server |
| Phase | What Happens | Engineer Checks |
|---|---|---|
| Process or connection start | Host starts a local server or connects to a remote MCP endpoint. | Command path, environment variables, network reachability, TLS, proxy behavior |
| Initialize | Client and server exchange protocol version, capabilities, and implementation metadata. | Version compatibility, advertised capabilities, initialization error handling |
| Discovery | Host lists available tools, resources, prompts, and related metadata. | Clear names, useful descriptions, stable schemas, no accidental sensitive exposure |
| Invocation or read | Host calls a tool, reads a resource, or gets a prompt using discovered definitions. | Input validation, authorization, timeout behavior, structured error responses |
| Notifications and progress | Server may send logs, progress, or resource update notifications when supported. | No noisy logs, no protocol data on stderr/stdout mixups, useful correlation IDs |
| Shutdown | Host closes transport or server exits cleanly. | No orphan processes, no leaked handles, no partial writes, graceful backend cleanup |
# Create a TypeScript MCP server project
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node
# Run a local stdio server during development
npx tsx src/index.ts
# Build before configuring a host that points at dist/
npx tsc
node dist/index.js
# Inspect a server interactively
npx @modelcontextprotocol/inspector node dist/index.js
# Inspect with environment variables
npx @modelcontextprotocol/inspector -e API_BASE_URL=https://internal.example.com node dist/index.js
MCP systems are easiest to reason about when you separate user experience from protocol execution. The host owns the product experience and model orchestration. The MCP client inside the host owns the protocol session. The server owns capability definitions and execution. The transport only moves messages.
That separation matters because most bugs come from crossing boundaries accidentally: putting UI policy inside a server, assuming the model can invent hidden tool parameters, logging protocol messages to the wrong stream, or letting a remote server decide permissions that should be enforced by enterprise identity.
Capability design is API design for model-facing systems. A tool, resource, or prompt should be narrow enough for the host to describe accurately and safe enough for repeated model use. If the capability name needs a paragraph of warnings to be understood, split it.
The most useful MCP servers expose a small number of high-quality capabilities instead of a large bag of generic operations. Prefer domain language over implementation language: search_runbooks is clearer than call_elasticsearch, and create_incident_update is safer than post_message.
| Design Question | Good Answer | Warning Sign |
|---|---|---|
| What does this capability do? | One clear user-facing operation or data access pattern. | It can read, write, search, summarize, and mutate depending on parameters. |
| How does the host describe it? | Name and description are enough for selection. | The model must infer behavior from hidden docs or examples. |
| What input is allowed? | Schema is strict, typed, and rejects ambiguous values. | Free-form JSON or string blobs control sensitive behavior. |
| What output is returned? | Structured content with enough context for the model to continue safely. | Large unbounded text dumps, raw stack traces, or backend-specific payloads. |
| What should happen on failure? | User-safe error with diagnostic detail in logs. | Exception leaks secrets or gives the model no recovery path. |
Use tools when the model needs to ask the outside world to do something. The action may be read-only, such as searching tickets, or write-capable, such as creating a pull request. The key difference is that a tool is invoked with arguments and produces a result at execution time.
Treat every tool like a public API endpoint. Validate parameters before touching a backend, authorize before side effects, limit payload size, return stable result shapes, and make errors reproducible. The host and model should never need to know your database schema, SDK quirks, or retry rules.
| Tool Concern | Production Pattern |
|---|---|
| Validation | Reject bad arguments before backend calls and include field-specific messages. |
| Authorization | Check user identity, scopes, tenant, and object-level permissions at execution time. |
| Idempotency | Use request IDs or natural keys for create/update operations that may be retried. |
| Timeouts | Set backend timeouts lower than host timeouts and return recoverable errors. |
| Auditing | Log who invoked the tool, what object was touched, and the decision result. |
Use resources when the server exposes readable context that has an identity. A resource is not just any text blob; it is content the host can address, list, read, cache, or refresh using a URI-like identifier. Good resource design gives the model stable context without forcing every read through a custom tool.
Resources are especially useful for files, docs, records, generated reports, policies, and runbooks. The design challenge is scale: a small server can list everything, but an enterprise server needs pagination, search, templates, subscriptions, and permission-aware discovery.
| Resource Pattern | Use It For | Example URI |
|---|---|---|
| Static resource | Known documents or bundled reference material. | docs://engineering/onboarding |
| Dynamic resource | Content generated from backend state. | incident://INC-1042/timeline |
| Template resource | Large address spaces where the host fills variables. | repo://{owner}/{repo}/file/{path} |
| Paginated listing | Enterprise repositories with many accessible objects. | policy://list?team=payments&page=2 |
Use prompts to package repeatable model workflows. A prompt is not a tool and should not secretly execute backend operations. It gives the host a reusable conversational scaffold with named variables, instructions, and optional context references.
Prompts are valuable when an organization wants consistent behavior across teams: incident triage, architecture review, test generation, migration planning, release note drafting, or compliance analysis. Keep prompts focused on the work pattern and let tools/resources provide live data.
Transport choice is a deployment decision. stdio is excellent when the host launches a local helper process. Streamable HTTP is the right default for independently deployed servers, shared services, enterprise auth, and multi-user access. Legacy HTTP plus SSE may still appear in older integrations, but new production work should avoid choosing it by habit.
The transport should match ownership. If the user installs the server beside a desktop host, stdio is simple and reliable. If a platform team owns the server and many hosts connect to it, HTTP gives you routing, scaling, centralized auth, observability, and operational controls.
| Scenario | Transport | Reason |
|---|---|---|
| Desktop host starts a local filesystem or git helper. | stdio | No network service to deploy; host controls process lifecycle. |
| IDE extension talks to a local workspace server. | stdio or local HTTP | stdio is simple; local HTTP can help when multiple clients share one process. |
| Internal copilot accesses company docs. | Streamable HTTP | Central auth, audit, scaling, and shared deployment are required. |
| SaaS connector used by many tenants. | Streamable HTTP | Tenant isolation, OAuth, rate limits, and monitoring belong at the service boundary. |
| Older client supports only SSE-era remote MCP. | HTTP+SSE compatibility | Use only when required by client compatibility. |
| Special embedded or offline runtime. | Custom transport | Only if both host and server control the runtime and standard transports do not fit. |
Authorization is not a decoration around MCP. It decides whether discovered capabilities should be visible and whether requested operations should execute. For local stdio servers, the host and local environment often define trust boundaries. For remote servers, identity and permission checks must be explicit.
The safest pattern is layered: authenticate the caller, authorize capability discovery, authorize each operation, check object-level access, audit decisions, and require confirmation for dangerous writes when the host supports it. Do not rely on the model to self-police sensitive operations.
Debug MCP from the connection outward. If initialization fails, tool logic is irrelevant. If discovery is wrong, host selection will be wrong. If invocation fails only in the host but not in Inspector, the issue is often configuration, environment, permissions, or stale build output.
Good debugging separates protocol failures from backend failures. A protocol failure means the host and server cannot correctly exchange MCP messages. A backend failure means the tool was invoked but the system behind it failed, denied access, timed out, or returned unexpected data.
| Symptom | Likely Cause | First Check |
|---|---|---|
| Server never appears in host. | Bad command path, missing build, process exits immediately, invalid config. | Run the exact configured command manually and inspect stderr. |
| Initialize fails. | Protocol version mismatch, malformed response, stdout pollution. | Use Inspector and check startup logs. |
| Tools are missing. | Server did not advertise tools, discovery filtered by auth, registration code did not run. | Inspect tools/list output. |
| Tool call fails before backend. | Schema mismatch or invalid arguments from host/model. | Compare tool input against schema and validation errors. |
| Tool works in terminal but not host. | Different environment variables, working directory, permissions, or built file. | Print safe diagnostics to stderr and verify host config. |
| Remote server returns unauthorized. | Missing token, expired token, wrong scope, tenant mismatch. | Inspect auth headers, token audience, and policy logs. |
| Large responses break model flow. | Unbounded resource/tool output. | Add pagination, summaries, limits, or resource section reads. |
MCP logs should answer three questions: what did the host ask for, what did the server decide, and what happened in the backend. Avoid logging full prompts, secrets, tokens, or raw customer records. Prefer structured logs with request IDs and redacted fields.
For stdio servers, logging discipline is non-negotiable: stdout belongs to the protocol. Diagnostics should go to stderr or an external logger. For HTTP servers, use normal service observability: access logs, structured application logs, metrics, traces, and audit streams.
Before production, review the server as both a protocol participant and an enterprise service. A server can be protocol-correct and still unsafe, unreliable, or impossible to support. Production readiness means predictable behavior under bad input, expired auth, backend outages, large payloads, concurrent use, and partial failures.
A small read-only server in one domain with narrow search or lookup capabilities, strict schemas, bounded responses, and clear logging. Once discovery, validation, and debugging are solid, add write tools deliberately.
Start with the initialize exchange and server startup logs. Many failures happen before any real tool, resource, or prompt call occurs.
No. MCP capabilities should be designed around model-usable workflows, not mirrored from backend endpoints. Some APIs are too broad, too dangerous, too low-level, or too noisy for direct model access.
Choose a resource when the data has a stable identity and the host may list, read, cache, or revisit it as context. Choose a read-only tool when the result is computed from parameters or represents a search/action.
Protocol correctness plus operational discipline: strict schemas, scoped authorization, bounded outputs, structured logging, testable failure modes, secret handling, monitoring, and clear ownership.
Explore 500+ free tutorials across 20+ languages and frameworks.