An assistant reviewing a bug needs more than the question in the chat. It may need the issue, the relevant source files, the library’s documentation, and a failing test. Without tools, you become the person copying all of that into the conversation.
Model Context Protocol (MCP) gives applications a common way to expose those tools and data. It reduces the integration work needed to make a server usable by compatible assistants. It does not decide which tool is appropriate or whether the assistant’s answer is correct.
The useful question is simple: what information or operation is the assistant missing? Start there, then connect the smallest server that provides it.
What MCP connects
The MCP architecture (opens in a new tab) has three parts. The host is the application coordinating the conversation and permissions. It creates a client for each server connection. The server exposes capabilities backed by a filesystem, API, database, or another system.
Servers can expose tools, resources, and prompts. Tools are callable operations. Resources provide addressable content. Prompts provide reusable message templates. A host may support only some of these capabilities, so check more than a product’s “supports MCP” label.
The June 2025 specification defines two standard transports (opens in a new tab): stdio and Streamable HTTP. With stdio, the client starts a local subprocess and exchanges protocol messages over its input and output. Streamable HTTP connects to a server through an HTTP endpoint. Older integrations may use the earlier HTTP+SSE transport.
An MCP connection is not long-term memory. The host decides what results to retain and pass to the model. Nor does a separate server process imply an operating-system sandbox: a local program can still access whatever its process credentials permit.
Start with one local server
A disposable directory is a useful first test. Put a small README in it and connect the reference filesystem server (opens in a new tab). Its documentation lists the supported operations and directory controls. It includes write operations, so an allowed directory should not be mistaken for read-only access.
{
"mcpServers": {
"filesystem-demo": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/absolute/path/to/mcp-demo"
]
}
}
}This configuration shape is host-specific, not part of the MCP wire protocol.
Replace the path with an existing test directory and follow your host’s
instructions for where to put the configuration. The command requires Node.js
and npm; npx -y can download and execute the package without an installation
prompt. For a repeatable setup, select and pin a reviewed package version.
Reload the connection, inspect the discovered tools, and ask the assistant to read the test README. Check which tool it called and the path it used. Then try a path outside the allowed directory and verify that the server rejects it. That checks a useful boundary before you attach real project data.
A coding assistant may already have native file access. In that case, another filesystem integration may add little. Use MCP for a missing capability rather than connecting every available server.
Choose a server for the task
I would start with the system that holds the evidence you need. These examples serve different purposes:
- GitHub’s official MCP server (opens in a new tab) exposes repository operations. Its documentation covers toolsets and read-only configuration. Use repository-scoped credentials and enable only the operations the task needs.
- Context7 (opens in a new tab) retrieves library documentation and code examples. It can help answer questions about a dependency’s API; it does not replace searching your own repository for its implementation.
- Figma’s MCP server (opens in a new tab) provides design context such as components, variables, and layout information. Use that alongside the project’s existing components, then inspect the rendered result. Design context does not establish that generated code handles every interaction state.
- A database integration can expose schema information and query execution. Judge it by its actual permission model, result limits, and supported database, not by a generic “SQL” label.
Before adding a server, inspect who maintains it, how it authenticates, what
operations it exposes, and where data is sent. Package names and configuration
keys come from that server’s documentation. Adding an environment variable named
READ_ONLY does nothing unless the implementation explicitly supports it.
Follow one task through the tools
Consider a synthetic bug report: a table stops preserving its sort order when a filter changes. The assistant could retrieve the issue from GitHub, inspect the table component through file tools, and look up the table library’s controlled-state API through Context7.
Each result answers a different question. The issue describes the observed behavior. The source shows the current implementation. The documentation explains the dependency’s contract. None of those alone proves that a proposed fix works.
Read the issue and locate the table's filter and sort state.
Check the documentation for the installed library version.
Explain the likely cause with file references.
Propose a small fix and a test that reproduces the bug.
Do not publish a comment or open a pull request yet.The host may use native tools to edit files and run tests. MCP does not require every step to use an MCP server. What matters is that the final explanation distinguishes what the assistant inspected, what it changed, and what it actually verified.
Design a small custom tool
An internal service may have no existing integration. Start by exposing one operation whose inputs and output you can explain. For example, a build-status tool is easier to reason about than a tool that accepts arbitrary shell commands.
{
"name": "get_build_status",
"description": "Read the status of a build by its exact ID.",
"inputSchema": {
"type": "object",
"properties": {
"buildId": {
"type": "string",
"minLength": 1,
"description": "The build ID returned by the build service."
}
},
"required": ["buildId"],
"additionalProperties": false
}
}The
tools specification (opens in a new tab)
defines discovery through tools/list and execution through tools/call. Use
an SDK to handle the protocol; keep the service-specific validation and
authorization in your handler.
The handler should verify access to the requested build, call the build service with a deadline, and return a bounded result. Include the build ID, status, and a source link where appropriate. If the service cannot be reached, return a tool error. An unavailable service and a failed build are different outcomes.
Test denied access, unknown IDs, timeouts, and oversized results as well as the successful response. A precise tool description helps the model choose it; tests establish what the implementation actually does.
Make permissions explicit
The host controls which tools are available and when to request confirmation. The server and the underlying service must still authorize every operation. A confirmation dialog cannot compensate for a backend that accepts another user’s record ID unchecked.
Keep read access separate from actions such as posting a comment or changing a record. Where a write needs approval, show the target and proposed content before executing it. Store credentials using the host or deployment environment’s supported secret mechanism, and keep them out of tool responses and committed configuration.
Tool results can contain untrusted text. A retrieved issue telling the assistant to upload credentials is part of the issue content, not an instruction from the user. Restricting available tools and credentials reduces what such content can cause the system to do.
Debug the failing layer
“The assistant cannot use the tool” can mean several different things. Find the first failed step before changing the prompt.
- The process never starts. Check the executable, absolute paths, and environment visible to the host. A desktop application may have a different PATH from your terminal.
- The connection fails. Check the transport and authentication configuration. For stdio, reserve stdout for MCP messages and send diagnostic logs to stderr.
- No tools appear. Inspect initialization and
tools/list. Check host capability support and whether the server advertises the expected tools. - A tool call fails. Inspect its arguments and the underlying service’s error. Separate validation, permission, rate-limit, and network failures.
- The call works but the answer is wrong. Inspect the returned evidence and the model’s interpretation. A successful transport does not establish a correct answer.
Keep a small, known request for each integration. Being able to list one directory or read one build makes it much easier to tell whether a later failure is in the connection, the service, or the task itself.
Continue reading
More from the journal.
AI Development
6 min read
AI Agents in the Enterprise: Where to Start
A practical approach to enterprise AI agents: tool access, memory, orchestration, evaluation, and a bounded first deployment.
Agentic AI
8 min read
Building Agent Systems with Gemini, ADK, A2A, and A2UI
What each part of an agent system is responsible for, how they fit together, and where application code still needs to make the decisions.