Lesson 3 of 3 in Tool Design & MCP Integration

4.3 · MCP in practice

Once you understand the MCP architecture, the operational choices become concrete: local vs remote deployment, security scoping, blast-radius management, and the production patterns that separate a demo from a shipped service. This lesson covers those choices.

Local vs remote deployment

Local MCP servers run as subprocesses on the user's machine — easy to ship, no network, no shared state. Remote servers run as services — shared state, central updates, but need auth, network reliability, and rate limiting.

Local: filesystem, personal notes, per-user git.
Remote: shared Jira, corporate wiki, prod database with scoped read.

The security model

MCP servers run with the privileges of whoever launched them. Treat installing an MCP server as installing code. Production deployments need allow-lists (which servers can be enabled), scoped credentials (server can only touch what it needs), and audit logging at the host.

Good to know — 'Just add the community MCP server' is the modern 'curl | sudo bash'. Vet it.

Tool boundaries and blast radius

The narrower a tool's capability, the smaller its blast radius when the model uses it wrong. A read-only query tool is safer than a general SQL executor. A specific 'refund_order' tool is safer than a generic 'call_shopify_api'.

Production patterns

Version your tool schemas. Avoid breaking changes; add new fields, deprecate old ones. Log every tool call with inputs, outputs, latency, and errors. Rate-limit at the server. Set timeouts on every call. Treat tool results as untrusted input to the next step.

Every tool call → structured log with {caller_id, tool, args, latency_ms, error?, output_size}

Takeaways

  • Local = subprocess; remote = service with auth
  • MCP servers inherit launch privileges — treat as installed code
  • Narrow tools have smaller blast radius
  • Version schemas, log everything, rate-limit at the server

Exam traps

Asking for JSON in prose and parsing the response
Prompt-only JSON drifts: markdown fences, preamble prose, missing fields. Use tool_choice to force a specific tool whose schema matches the desired output.
Requiring fields that may not exist in source documents
Required fields force the model to fabricate when the source doesn't have the data. Mark potentially-missing fields as nullable.
Assuming schemas prevent semantic errors
Schemas prevent SYNTAX errors, not SEMANTIC ones. A total that doesn't equal the sum of line items still passes schema validation.

Practice scenario

A pipeline extracts invoice data into a strict JSON schema. About 5% of extractions have subtly wrong values (e.g., 'total' set to the subtotal, currency guessed as USD when the invoice is in EUR). What's the correct architectural addition?

← PreviousBack to domain