Model Context Protocol: Architecture & Security Guide
Scope: MCP standardizes context exchange between AI applications and external systems. It does not by itself make a tool safe, authorize a user, or decide how a model should use returned data.
The Model Context Protocol (MCP) is an open standard for connecting AI applications to data sources, tools, and reusable workflows. It reduces one-off integration work, but the protocol boundary should be understood before installing a server or exposing a production API.
The three participants
| Participant | Responsibility | Security question |
|---|---|---|
| Host | The AI application coordinating one or more connections | Which servers and actions may the user enable? |
| Client | A host component maintaining a dedicated connection to one server | How are capabilities, messages, and approvals isolated? |
| Server | A local or remote program exposing context or actions | What identity, data, network, and operating-system authority does it hold? |
A host can create multiple clients, each connected to a different server. This separation matters: permissions granted to a filesystem server should not silently become permissions for an unrelated remote service.
What servers can expose
- Tools are callable operations. They may calculate a value, query a system, write a file, or trigger a workflow.
- Resources expose context identified by URIs, such as documents, schemas, or application state.
- Prompts are reusable interaction templates offered by a server.
Capability discovery tells the client what is available; it is not a reason to expose every capability to the model. A mature host can progressively disclose tools relevant to the task and apply policy before execution.
Data and transport layers
MCP uses JSON-RPC messages for lifecycle negotiation and protocol operations. Local servers commonly use standard input/output, while remote servers commonly use Streamable HTTP. Transport changes the threat model. A local process may inherit filesystem and user privileges; a remote service adds authentication, authorization, network, redirect, and server-side isolation concerns.
A minimal design exercise
Before writing code, describe one narrow server contract. For a read-only issue tracker server, for example:
Tool: get_issue
Input: { repository: string, issue_number: integer }
Output: { title, body, labels, updated_at }
Authority: read-only access to approved repositories
Errors: not_found | forbidden | rate_limited
Logging: tool name, repository, issue number, outcome
This contract is easier to secure and test than a generic “run API request” tool. Keep input schemas narrow, return structured errors, apply authorization outside the model, and avoid passing arbitrary URLs or shell fragments.
Local server checklist
- Inspect the package, repository, exact startup command, and transitive dependencies before execution.
- Run with the least operating-system privilege and limit filesystem and network access.
- Prefer a dedicated workspace; never assume localhost is inaccessible to malicious browser or process activity.
- Show the exact command and arguments before one-click installation.
- Require confirmation before writes, execution, deletion, deployment, or communication.
- Provide a clear uninstall and credential-revocation path.
Remote server checklist
- Authenticate the user and authorize each resource or action.
- Validate token audience; do not pass arbitrary upstream tokens through.
- Use exact redirect URI validation and CSRF protections in authorization flows.
- Protect OAuth discovery and redirects against SSRF and internal-network access.
- Separate tenants in storage, logs, caches, and queues.
- Rate-limit and audit actions without recording unnecessary sensitive content.
Testing an MCP integration
Test protocol success and policy failure. Verify capability negotiation, schema validation, cancellation, timeouts, malformed messages, permission denial, expired credentials, and a server that returns hostile instructions in otherwise valid data. Confirm that the host does not treat a tool result as higher-priority policy.
Common misconceptions
- “MCP tools are trusted because they are installed.” Installation expands the trusted computing base; it does not prove safety.
- “Read-only means harmless.” Reading secrets or private data can still create a serious breach.
- “The model will ask before dangerous actions.” Approval must be enforced by the host or tool boundary.
- “One broad tool is more flexible.” Broad primitives are harder to validate, authorize, and audit than task-specific operations.
Worked threat model: a remote ticketing server
Illustrative review—not an assessment of a real server. A remote MCP server exposes ticket_get, ticket_search, and ticket_addComment. It exchanges data with a third-party ticketing API on behalf of signed-in users.
| Asset or boundary | Threat | Required control |
|---|---|---|
| User authorization | A malicious client reuses another client's consent | Per-client consent, exact redirect validation, CSRF protection |
| Access token | Token intended for another audience is accepted or forwarded | Validate issuer and audience; never use token passthrough |
| Ticket content | A ticket contains instructions to exfiltrate data | Treat tool results as untrusted content below host policy |
| Write tool | The model posts a comment without meaningful consent | Per-call authorization and approval tied to exact arguments |
| Tenant boundary | Search leaks another organization's tickets | Derive tenant scope server-side and test isolation |
| Authorization discovery | Attacker-controlled metadata redirects internal requests | SSRF defenses, HTTPS policy, redirect and IP-range validation |
Follow the lifecycle, not just the tool call
- Connect: establish the transport and authenticate the remote endpoint where required.
- Initialize: negotiate protocol version and capabilities; reject unsupported or inconsistent peers.
- Discover: list tools, resources, or prompts and apply host-side visibility policy.
- Present: show users which server supplies a capability and what authority it requires.
- Authorize: evaluate user identity, tenant, scope, target, and approval before each consequential call.
- Execute: send a bounded request with timeout, cancellation, and correlation identifiers.
- Validate: parse the result as untrusted structured data and enforce size and content limits.
- Close or revoke: terminate sessions, remove credentials, and invalidate cached capability state when trust changes.
Use a host-side permission manifest
The protocol describes capabilities; the host still needs a local policy. One possible manifest is:
{
"server": "tickets.example",
"tenant": "tenant_42",
"visible_tools": ["ticket_get", "ticket_search", "ticket_addComment"],
"automatic": ["ticket_get", "ticket_search"],
"requires_approval": ["ticket_addComment"],
"resource_allowlist": ["ticket://tenant_42/*"],
"max_calls_per_run": 20,
"credential_ref": "vault://mcp/tickets/user_7",
"expires_at": "2026-08-10T12:00:00Z"
}Do not let a server response expand this manifest. Approval should bind the tool name, normalized arguments, user, server identity, and a short validity window. If any of those change, ask again.
Transport-specific review
| Concern | Local stdio | Remote HTTP |
|---|---|---|
| Identity | Package, executable path, checksum, and launching user | TLS endpoint, server metadata, OAuth client and resource identity |
| Primary authority | Inherited files, environment, processes, and network | Granted scopes, tenant data, downstream APIs |
| Secret handling | Sanitized environment or brokered credential access | Audience-bound tokens in a secure store |
| Isolation | Sandbox, dedicated workspace, OS permissions | Tenant separation, egress controls, rate limits |
| Revocation | Stop process, remove package/config, rotate exposed secrets | Revoke grant/token, disconnect client, invalidate sessions |
Authorization review for remote servers
- Validate token issuer, signature, expiry, audience, and required scopes.
- Do not accept a client token and pass it unchanged to a downstream API.
- Use exact registered redirect URIs and bind authorization responses to the initiating client and browser session.
- Display the requesting client, requested third-party scopes, and destination before consent.
- Protect discovery, dynamic registration, callbacks, and redirects against SSRF and internal-network access.
- Store refresh tokens encrypted and separately by user, client, server, and tenant.
- Re-evaluate authorization on each call; capability discovery is not an access grant.
Reproducible integration test matrix
| Case | Injected condition | Expected result |
|---|---|---|
| Negotiation | Unsupported protocol version | Clean failure with no tool exposure |
| Schema | Extra key, wrong type, or oversized value | Rejected before server action |
| Authorization | Expired token or wrong audience | Denied; token is not forwarded |
| Consent | Arguments change after approval | Approval becomes invalid |
| Injection | Tool result says to ignore host policy | Content remains data, not instruction |
| Isolation | User requests another tenant identifier | Server-side tenant scope wins |
| Availability | Timeout, cancellation, disconnect | Bounded retry or typed terminal failure |
| Revocation | Grant removed during a session | Next call reauthorizes or fails closed |
Incident response and removal
- Disable the server connection or specific capability without waiting for a full application release.
- Revoke user grants and rotate any credentials available to the server process.
- Preserve a minimal audit trail: server identity, tool, normalized target, user, authorization result, and time.
- Search for related calls while avoiding unnecessary prompt or document disclosure.
- Invalidate cached tool definitions and authorization metadata.
- Patch or remove the server, rerun the adversarial suite, and document the new trust decision before reconnecting.
Primary references
Bottom line
MCP makes integrations portable. Safety still depends on narrow capabilities, real authorization, isolated execution, visible approvals, and testing that treats every external result as untrusted.
What MCP tool calls cost
Model Context Protocol makes it easy to attach tools, and each attachment adds context that is sent on every relevant call. The protocol is cheap; the context it carries is not free. Below: one tool-using request at 25K input, 15K cached, 2.5K output. Of the 25,000 input tokens, 15,000 are billed at the cache-read rate and 10,000 at full input rate.
| Model | Cost per request | Monthly at 8,000 requests |
|---|---|---|
| GPT-5.6 Luna | $0.0053 | $42.40 |
| Gemini 3.8 Flash | $0.018 | $144 |
| Claude Sonnet 5 | $0.048 | $384 |
The interesting comparison is the two small models: they differ by a factor of two while both being far below the flagship, which suggests that for tool-heavy traffic the decision is mostly about how much context the server injects, not about the token rate.
Rates verified against provider documentation on September 18, 2026. Promotional rates expire, so re-check before budgeting: LLM API cost planning · September 2026 pricing update. Run your own numbers in the cost calculator.