EXAMTOPICS / TECHNOLOGY INSIGHTS

Anthropic CCA-F: MCP Tool Schemas, Errors and Permissions

The Model Context Protocol (MCP) allows a host application to expose tools and other capabilities through a standardized interface. This is valuable when Claude needs to retrieve project facts or request an external operation. It is not, by itself, an authorization system. A model selecting a tool is different from trusted software deciding whether the tool may operate on a particular user, resource, or environment. That distinction drives every important design choice in a production MCP integration.

A well-designed MCP server offers narrow operations, understandable input contracts, safe error handling, and a predictable security boundary. In this article we build a fictional customer-support interface and test it against ambiguous input, denied access, and failed dependencies. The aim is architectural reasoning, not an inventory of configuration keys or a replica of an examination question.

Separate the host, the server and the business service

An MCP host coordinates interaction with the model and connected MCP clients. An MCP server exposes specific tools, resources, or prompts; the underlying business service ultimately owns protected customer data and side effects. Each component has a different trust boundary. A tool appearing in the host’s catalog does not make every record in the business system available to the model, and a valid tool input is not the same thing as enforcing authorization and human approval before a consequential action.

Before configuring an integration, identify the server operator, connection transport, data location, credentials, permitted operations, and expected users. A read-only order lookup belongs in a narrower risk class than a tool capable of modifying a payment. Do not package both inside a single unrestricted command endpoint just because the agent might sometimes need the second operation. If a role never needs an action, remove that action from its tool catalog.

Tool names and descriptions are selection contracts

A tool named lookup tells the model very little. What does it look up? When is it appropriate? Does it return protected fields or cause a change? A more useful get_order_status description explains that it returns limited order state for an authenticated customer’s authorized order and performs no updates. The description supports correct selection, but the server still verifies ownership independently. Tool names and descriptions help a language model make a choice; they cannot serve as permissions.

Specify meaningful preconditions when they affect the workflow. If a customer must supply a valid order ID, say so. If the output excludes payment details, describe that exclusion. If a tool only applies to one organization or environment, encode that condition in the application contract instead of trusting the agent to remember it from a generic prompt. Distinguish tools that propose an action from tools that execute it.

Input schemas should be small, typed and unambiguous

Give each tool only the fields required for its operation. An order lookup might accept order_id as a string; a policy evaluator could also accept a reason code drawn from a defined set. The application should derive authenticated identity from the session, not from an unconstrained customer ID invented by the model. Use required fields, enumerations, clear descriptions, and validation of special cases. Missing data should remain missing rather than being replaced with a plausible value.

A schema checks shape, not truth. A valid string can identify someone else’s order. A correct numeric type can still exceed an allowable amount. The service must check identity, policy, and business state. Successful structure validation is an entry condition, not proof that the requested operation is safe or desired.

Outputs need stable fields and limited exposure

Return only facts needed for the next decision. An agent answering whether an item shipped does not need a full customer profile, internal notes, or account tokens. A narrow result might contain status, delivered_at, eligible_for_review, and a correlation ID. If a lookup is partial or stale, make that state explicit. Do not hide missing fields behind confident human-readable prose.

Structured content improves downstream validation. However, a caller can still misinterpret a semantically incorrect result that conforms to a schema. Test output types, mandatory fields, and factual constraints separately. Keep identifiers stable so a later model turn or a human reviewer can trace which records were actually used.

Distinguish protocol failure from a tool’s business failure

MCP uses JSON-RPC for protocol communication. An unknown method or malformed request can produce a protocol-level error. A valid tools/call request may reach the correct tool but fail because an account lacks permission, an order is not found, or a downstream system times out. The MCP tool result can report that kind of application failure with isError: true and concise explanatory content. These two layers must not be confused.

An error with an invalid method suggests a client integration problem; an unauthorized order requires a corrected identity or legitimate escalation. Retrying the same forbidden order under a different tool name is not recovery. In Claude’s Messages API, client tool-result blocks use is_error with an underscore, whereas MCP uses isError with camel case. They represent related concepts at different interfaces; do not copy a field from one message format into another and assume it will work.

Build a three-tool support example

Imagine three MCP tools: get_customer_summary, lookup_order, and evaluate_refund. The summary returns minimal fields for the authenticated customer. The order lookup verifies that an order belongs to that customer. The policy evaluator reads confirmed order data and returns eligibility, maximum permitted adjustment, and whether human review is required. None of these tools issues a payment. A separate, tightly controlled business operation handles an authorized refund, with its own approval checks and replay protection.

When a customer asks for a refund, the host can allow Claude to request lookup_order and evaluate_refund. An example successful result might say that an order is eligible for manual review, not for automatic credit. The model should communicate that distinction. The server should deny an attempt to read another customer’s order even if the tool’s input schema is valid. An order-not-found or service-timeout response should be explicit, and the model should ask for clarification rather than invent missing facts.

The separation also supports testing. Verify what happens if the customer omits an order number, supplies one with the wrong format, requests an adjustment above policy, or tries to make the agent use a broad alternative tool. Each negative case should return a predictable safe result and leave external account state unchanged.

Configuration scope changes who sees a server

Claude Code supports local, project, and user MCP configuration scopes. A project-scoped server may be declared in a shareable .mcp.json file, while personal and local configurations have different visibility and storage. A repository configuration can help teammates discover required tools, but it must not contain credentials. Treat an unfamiliar server command as executable software that needs dependency review, not as a harmless descriptive link.

For remote MCP servers, inspect authentication, origin, available tools, and transport security. For local servers, check executable paths, environment variables, and file permissions. An automated CI environment may lack an interactive approval prompt, so do not assume a headless agent can safely launch every configured server. Establish explicit approval and secret handling appropriate to the deployment environment.

Tool access should follow each agent’s assignment

A multi-agent research system may have a scout that searches documents, an analyst that extracts evidence, and a writer that reports accepted claims. There is rarely a reason to expose privileged write tools to all three. Restrict their catalogs and enforce service permissions independently. This reduces both security risk and tool-selection ambiguity. If a subagent is intended only to explain data, a read-only catalog may be entirely sufficient.

Description quality matters here too. Two tools with similar names but different powers invite confusion. Prefer clearly separated operations and explicit side-effect declarations. If an agent can ask a tool to perform an irreversible operation, require an appropriately reviewed human or machine authorization boundary before execution.

Test error paths and data boundaries

Test a request with an unknown method, schema-invalid arguments, unauthorized resource, service timeout, stale record, and response containing sensitive information that should not be returned. Confirm that the error is signaled at the right layer, no unauthorized side effect occurs, and useful diagnostic context remains without exposing secrets. Test what the host shows the model after each denial and whether that response could cause an unsafe retry.

An MCP result indicating an error is information for the next step; it is not a command to keep retrying. A read-only lookup might be safely retried with bounded backoff. A write that timed out may have completed already, requiring reconciliation against an external transaction or resource ID. Keep the business outcome distinct from whether the protocol message was delivered successfully.

Use three responses that appear similar to the assistant but require different engineering actions. First, an invalid protocol message should be rejected at the transport or parser boundary. Second, a valid MCP response with a tool-level error should preserve structured information about why the operation failed. Third, a valid request for another tenant’s record must be denied by the protected business service even if its JSON matches the tool schema. A proposed answer to independent CCA-F MCP-error practice questions is defensible only if it names the failing layer and tests whether a retry could repeat a protected operation. A protocol retry cannot cure missing permission, and a friendly error string is not authorization to search for a differently named tool.

Apply the lessons to Architect Foundations

Compare a broad customer-action tool with three narrower operations that read an order, propose an adjustment and commit an authorized change. For each design, identify which inputs are trusted, who may approve a write, where tenant boundaries are checked and what happens if a response is lost after a commit. Narrow contracts make it easier to prove that an ambiguous request did not acquire extra authority just because the model selected a different tool name.

Protocol behavior and client configuration need separate version checks. Validate tool schemas and error signaling against the versioned MCP tools specification, then compare integration settings with the current Claude Code MCP documentation for the version actually deployed. A protocol error, a service authorization denial and an uncertain external side effect need different recovery paths; collapsing all three into a generic retry hides the facts operators most need.