
TL;DR
- Stratigraphic Amenity, our open-source toolkit for scanned geological maps, illustrates MCP tool design in practice: its local server exposes ten tools to AI agents.
- Real-agent testing revealed that many hosts pass only plain text, causing agents to invent labels, estimate preview coordinates, and misread 86 mineral occurrences as “1 item”.
- We adapted our architecture by appending text evidence digests, reporting records per provider, placing fixes inside error messages, and structuring tools around agent tasks.
Key Takeaways
- Many hosts pass only text to the model. Critical identifiers, bounding boxes, counts, and warnings are repeated in an evidence digest appended to text payloads.
- Report records, not groups. Grouping 86 mineral occurrences as “1 item” led agents to treat data as scarce. Summaries now report records per provider and in total.
- Say what is missing in words. Blank fields invite models to guess. Unextracted values carry explicit tags like
label_extraction: "not_available"andlow_confidence. - Errors must carry their own fix. Hosts frequently expose only error messages, so remedies live in the message itself. Asset installers take zero arguments to prevent unapproved downloads.
- Descriptions and schemas steer the agent. Strict boundaries prevent malformed calls, agent testing reveals failures unit tests miss, and tool results must be treated as untrusted input.
Building an MCP server is one thing; building a server real agents can use reliably is another. This post collects what testing with real agents changed about our MCP tool design. The examples come from our open-source geoscience servers, where agent behavior exposed gaps that schema checks alone could not show.
How Do MCP Tool Results Reach the Model?
The Model Context Protocol lets applications start a local server and call its tools. Under the official MCP tools specification, tool execution returns a CallToolResult containing content (text, images, embedded resources) and optional structuredContent (JSON with typed fields). Placing domain data solely in structuredContent assumes the host forwards both to the model.
Stratigraphic Amenity is our open-source MCP server for scanned geological maps; our larger Geocluster Research Harness exposes roughly 50 tools. Stratigraphic Amenity provides ten tools to AI agents: registering maps, detecting layout, georeferencing, querying knowledge providers, and rendering overlays. We tested it with real agents on scanned maps, later refining schemas after evaluations with DeepSeek V4.
Many Hosts Only Show the Model Text
In tested hosts, client applications frequently forward a tool’s text content while omitting structuredContent entirely. In those environments, machine-readable JSON never reaches the model.
Without structured fields, agents guessed missing values: inventing plausible rock unit names for blank legend entries or estimating coordinates from downscaled previews.
The fix was an evidence digest appended directly to each result’s text. It repeats fields an agent must not guess, one per line: identifiers, bounding boxes, confidence scores, legend detection status, georeferencing residuals, records per provider, and warnings.
Automated regression checks verify that critical parameters and warnings appear in both text and structured output. For reliable MCP tool design, treat structuredContent as the machine record and text as the primary delivery channel in tested hosts. Anything that steers agent decisions belongs in both.
How Should You Design MCP Tools Around What the Model Actually Sees?
Because an agent’s reasoning depends on tokens in its context window, designing MCP tools requires shaping descriptions, schemas, and results around what the model actually receives.
Report Records, Not Items
A knowledge query groups results by provider. Early summaries counted those groups, so a query returning one group with 86 mineral occurrences was summarized as “1 item”. Agents took that count literally and concluded data was scarce.
Summaries now state record counts per provider and in total: Knowledge query found N record(s) across P provider(s): active_faults=..., earthquake_history=.... When results are truncated, summaries explicitly contrast returned records with the total found.
Say What Is Missing, in Words
The toolkit ships without OCR, so detected legend entries lack transcribed text. An empty string looks like data to fill in. Each entry now specifies label: null and label_extraction: "not_available", and the summary explicitly notes that labels were not extracted.
The same practice applies across outputs. Legend counts are labeled legend_extracted_candidates: N (not a verified map-unit count). Detections under 0.5 confidence receive a low_confidence tag. When no legend is found, warnings flag unclassified regions as potential candidates.
Previews Are a Different Coordinate Frame
Tools that return images include an inline preview capped at 1,536 pixels. However, all bounding boxes in the result use coordinates from the full-resolution source image, which is often several times larger.
An agent measuring pixel positions on the preview and passing them to georeferencing generates inaccurate transforms without an error. Results now explicitly mark the preview’s coordinate_frame as "preview" and the payload’s as "source", accompanied by a warning that the frames differ.
Why Are MCP Tool Descriptions an Agent’s Primary Decision Signal?
An AI agent decides which tool to call based primarily on its name and description. As noted in an analysis of designing MCP tools by Tarik Davis (authored by AI agent Claudius), tool metadata serves as the prompt-level interface for language models. A model cannot inspect internal backend code; it relies on descriptions to establish clear operational boundaries.
Effective MCP tool descriptions define what the tool does, explicit conditions for when to invoke it, negative boundaries specifying when not to call it, and what data it returns. Phrasing descriptions as direct instructions guides model planning. In Stratigraphic Amenity, geomap_list_capabilities uses an explicit directive: “Discover registered, installed, configured, and ready capabilities. Call this first; inspect provider readiness, supported_requests, and missing_requirements before selecting a workflow.”
The contrast is easiest to see in an example. The weak wording below is illustrative; the stronger wording is the actual geomap_process_image description in the server schema.
| Description | Example | What the agent learns |
|---|---|---|
| Vague (illustrative) | Process an image. | No supported input, prerequisite, or expected behavior. |
| Specific (actual tool description) | Run HIE layout and legend extraction for one registered map. Requires map_processing.ready; persists crops and processing state for later resource reads. | Names the task, its readiness condition, and where resulting state can be read. |
How Does MCP Tool Schema Design Prevent Hallucinated Inputs?
An MCP tool schema can reduce malformed calls by making valid inputs explicit. Prefer typed fields, required properties for essential values, and bounded ranges where the domain has known limits; use enums or defaults only when they match the operation. Add a short description to each field so the model knows what a value means, and avoid free text when a narrower type works.
In Stratigraphic Amenity, the server validates tool arguments against the declared input schema before calling the adapter. For example, the bounds schema requires four coordinates and limits longitude to -180 through 180 and latitude to -90 through 90. These checks catch missing or out-of-range values; they do not establish that every coordinate relationship is meaningful or stop an agent from attempting an unsupported call. Clear property descriptions and actionable validation errors help the agent recover.
| Parameter | Loose Schema | Constrained Schema (Stratigraphic Amenity) | Failure Mode Prevented |
|---|---|---|---|
bounds | bounds: string | bounds: object with min_lon, min_lat, max_lon, max_lat in [-180, 180], [-90, 90] | Model passes malformed text or out-of-range coordinates. |
label | label: string (optional) | label: string with minLength: 1 in geomap_enrich_legend required list | Model passes empty strings or omits target label. |
Why Design One Tool per Task, Not One per Endpoint?
Design recommendations from Jonathan Ballard and JustDukkan advise structuring MCP tools around high-level agent tasks rather than individual API endpoints. Exposing fine-grained wrappers often requires multi-turn call chains, expanding context overhead and coordination errors. Consolidating steps into task-focused tools lets models complete goals in fewer turns while keeping large datasets out of an agent’s context window.
Stratigraphic Amenity applies this rationale across its ten tools: geomap_process_image combines layout analysis and legend extraction in one call, while geomap_georeference calculates affine transforms directly from ground control points without exposing intermediate math.
| Dimension | Endpoint Pattern (API Mirror) | Task Pattern (Stratigraphic Amenity) |
|---|---|---|
| Call Flow | May require chaining separate calls for loading, cropping, and extraction. | Consolidates related steps into cohesive operations (e.g. geomap_process_image). |
| Context & State | Passes intermediate payloads and raw arrays through model context. | Keeps working state in server memory; returns focused summaries and URIs. |
How Should You Handle Errors in MCP Tool Design?
Effective MCP error handling treats error payloads as instructional affordances rather than fatal termination signals. Because client hosts frequently expose only top-level error messages to the model context, an error must contain all the information an agent needs to diagnose what failed and take corrective action independently.
Put the Fix Inside the Error Message
Some client hosts display only an error’s message field, dropping structured details. If a message states only “Operation failed”, the model cannot deduce how to recover. In our tools, errors carry their remedy directly in the message text.
When an agent invokes map processing before detectors are loaded, the error message explains that dependencies are missing, names geomap_prepare_detectors as the recovery tool, and lists outstanding requirements.
The structured payload provides a typed code, a trace_id, recovery hints, and an allowlisted cause identifier, excluding stack traces and file paths. We also separate distinct failure cases: “no provider matched this name” and “provider exists but cannot serve this request” provide different instructions so the agent can adapt.
The Agent’s Shell Is Not the Server’s Environment
An agent with terminal access may attempt to fix a missing dependency by running installation commands in its own shell. That installs packages into the agent’s environment rather than the server’s, leaving the server broken.
Recovery hints explicitly warn agents not to run installation commands locally. Additionally, Stratigraphic Amenity provides dedicated tools—geomap_prepare_detectors and geomap_prepare_knowledge—to install assets within the server runtime.
These tools take zero arguments—no custom URLs or paths. This parameterless design prevents models from being steered into downloading unapproved files, enforcing server security in code rather than prompts.
Check Readiness Before Calling
Calling heavy computational tasks before assets are initialized risks execution failures or timeouts. To avoid this, geomap_list_capabilities reports the readiness of map registration, layout processing, georeferencing, overlay rendering, and each knowledge provider. Its summary provides explicit directives, such as “Do not call geomap_process_image until map_processing is ready.”
Readiness checks confirm that required files and modules exist locally; they do not verify external network reachability or credentials. Because initializing PyTorch can crash or emit unwanted terminal output, detector checks run in an isolated subprocess with a timeout, returning clean messages like “missing shared library libGL.so.1” without crashing the server.
Why Should You Treat Tool Results as Untrusted Input?
Tool results must be handled defensively because external tools frequently ingest third-party files, databases, or web content that could harbor adversarial instructions. If an agent interprets returned content as instructions rather than data, untrusted tool results can hijack its reasoning trajectory.
As architectural reviews by JustDukkan and Jonathan Ballard emphasize, agents should treat tool outputs as data, not instructions. Tool authors should also avoid echoing raw, unvalidated file or provider content into results; return only the fields needed for the task and label their provenance where useful. As detailed in our guide on trust boundaries for a local MCP server, this server validates inputs and outputs, restricts paths, redacts paths from errors, and uses allowlisted error causes. These controls reduce exposure, but do not eliminate prompt-injection risks in external text.
How Do You Test MCP Tools With an Agent, Not Just Unit Tests?
Real-agent runs test how hosts and models use MCP tools. Unit tests check schema validity, logic, and adapter behavior, but cannot show what a host passes into context or how a model interprets descriptions and results when structuredContent is absent.
Live testing of Stratigraphic Amenity exposed usability failures unit tests missed entirely: agents inventing rock unit labels when OCR fields were null, estimating coordinates from downscaled preview images, attempting package installations in local shells, and misinterpreting 86 records grouped into one response as a single item. Subsequent evaluation rounds with DeepSeek V4 further refined parameter schemas.
For each run, record the task, host, selected tool, arguments, and whether each critical warning appears in the text the model receives—not just in logs or structuredContent. Then compare the agent’s next action with the expected behavior. This helps distinguish a schema problem from a delivery or instruction problem and gives each regression check a concrete failure to reproduce.
As software architect Jonathan Ballard emphasizes, test iteratively: inspect tool choices and arguments, refine descriptions and schemas, then turn observed failures into regression checks for warnings in text and structured output.
How Do You Keep an MCP Server Clean?
Keeping an MCP server reliable requires clean isolation between communication protocols, domain execution logic, and external interfaces. Applying consistent MCP server best practices prevents common runtime failures.
stdout Belongs to the Protocol
A stdio MCP server communicates via JSON-RPC over standard output. A single stray print statement corrupts the stream. Because machine learning runtimes like YOLO log freely, model loading and inference must redirect standard output to standard error, ensuring all logs travel via stderr without corrupting transport communication.
Keep the Adapter Thin
Our architecture keeps the MCP layer separated from domain logic. The server validates payloads against JSON schemas, a single adapter method per tool delegates calls into the Python SDK, and all geological algorithms reside in the SDK. Designing clean MCP tools for agents keeps the protocol adapter thin while delegating execution to domain packages.
The server implementation and adapter are available in the public Stratigraphic Amenity repository.
What Real-Agent Testing Changed in Our MCP Tool Design
The practical lesson is to design around the information the model actually receives and to verify that assumption in the host where the tool will run. A schema can constrain arguments, but it cannot show whether the host forwards the fields an agent needs or whether the description leads to the right call. For our MCP tools, real-agent runs exposed missing text, confusing counts, and recovery steps aimed at the wrong environment. We turned those observations into clearer summaries, narrower inputs, and regression checks. Start with one realistic task, inspect the complete call and result, then make the smallest change that addresses the observed failure.
Frequently Asked Questions
What is MCP tool design?
MCP tool design is the practice of structuring Model Context Protocol tool metadata, input schemas, result payloads, and error messages for reliable consumption by autonomous AI agents. Unlike traditional software interfaces built for human developers, MCP tools treat names, descriptions, and parameter constraints as an agent-facing user interface, ensuring language models understand operational boundaries, avoid invalid invocations, and recover cleanly from execution failures.
How do MCP tool results reach the model?
MCP tool executions return a CallToolResult containing content items like text or images alongside optional JSON structuredContent. However, in tested client hosts, applications often forward only the plain-text content into the model turn while omitting structured fields. Servers ensure critical information reaches the agent by appending an evidence digest directly to the text payload, repeating identifiers, counts, coordinates, and warnings.
How should you write MCP tool descriptions?
Write tool descriptions as explicit, directive instructions rather than passive capability titles. Effective descriptions define exactly what the tool accomplishes, provide clear conditions specifying when to invoke it, establish negative boundaries detailing when not to use it, and state what output it returns. Clear instructional phrasing prevents ambiguous tool selection and helps models identify necessary prerequisites before initiating complex workflows.
How do you prevent hallucinated inputs in MCP tools?
Schemas do not stop an agent from proposing an unsupported value, but they can help reduce malformed calls and let the server reject inputs that fail declared constraints. Use explicit types, list required properties in required, and set numeric bounds such as longitude and latitude limits. In Stratigraphic Amenity, the server checks arguments against the input schema before the adapter runs, so invalid types or out-of-range coordinates return a validation error instead of reaching domain logic.
Should an MCP tool map to an endpoint or a task?
Structuring an MCP tool around a complete task rather than an individual API endpoint is a design pattern that can reduce multi-step call chains and context overhead. Fine-grained endpoint wrappers often require models to manage complex multi-turn sequences. Task-oriented tools encapsulate intermediate coordination within the server SDK, allowing agents to execute complete workflows in cohesive calls while keeping large intermediate working datasets local.
How should an MCP tool return errors?
When implementing MCP error handling, return structured errors whose top-level message contains complete, actionable instructions for recovery. Because client hosts frequently expose only error message strings to the model context, the text itself must state what prerequisite failed, caution against inappropriate local fixes, and specify the exact server tool or parameter adjustment needed to proceed safely.
How do you test MCP tools?
When testing MCP tools, execute realistic workflows with autonomous agents in target host environments, rather than relying solely on schema syntax checks or isolated unit tests. Live agent testing reveals whether models misinterpret tool descriptions, invent unsupported parameters, or stumble when structured fields are omitted. Observed failures should be converted into automated regression tests verifying that critical cues appear in both text and structured payloads.
Should you trust MCP tool results?
No, tool outputs should be treated with caution because external tools ingest files, databases, and third-party resources that may contain untrusted text. For robust MCP tool security, local servers apply defensive controls—validating file paths against approved roots, enforcing schemas, redacting internal filesystem traces, and restricting error causes. While these measures limit exposure, they do not eliminate prompt-injection risk, so agents must treat returned data cautiously.


