Skip to main content

MCP server development: connecting to Claude Code with external tools

Cluster 13 of the Claude Code Workflow (first Platform). MCP (Model Context Protocol) standardizes connection between Claude Code and external tools: standard input or HTTP, naming convention, authentication, resource provisioning. Pattern for writing custom MCP server.

What do you think about this article?

MCP server development: connecting to Claude Code with external tools
Claude Code WorkflowPhotos:PixabayPexels

At a Glance

Cluster 13 of the Claude Code Workflow (first Platform). MCP (Model Context Protocol) standardizes connection between Claude Code and external tools: standard input or HTTP, naming convention, authentication, resource provisioning. Pattern for writing custom MCP server.

Direct answer

The Model Context Protocol (MCP) enables Large Language Models like Claude Code to directly interact with external tools and systems, eliminating the need for script generation and execution. With MCP, models can call specific tools, such as reading Gmail messages or accessing Google Drive, without requiring human intervention, thereby reducing friction and increasing efficiency in technical workflows.

Model Context Protocol (MCP) is the open standard of Anthropic for connecting Large Language Models (LLMs) to external tools. MCP servers respond with a set of callable tools from the model; Claude Code identifies and invokes them when the task requires it. For technical workflows, MCP is what separates "Claude that gives advice" from "Claude that executes real actions on your systems".

Independence Disclaimer: I am not affiliated with qrx, or Anthropic, nor the maintainers of the MCP servers mentioned. I use a handful of MCP servers on my portfolio (Gmail, Google Drive, claude-in-chrome, context7, firecrawl, exa, episodic-memory) installed as plugins Claude Code.

What solves MCP

Without MCP, the only way to make a model do something on the outside world is by asking it to generate a script and you execute it + you return the output. Long cycles, high friction.

With MCP, the model calls the tool directly. Example: "read the last 10 messages from info@..." with active Gmail MCP server = the model calls mcp__claude_ai_Gmail__list_messages And processes the result. Zero copying and pasting, zero wear and tear.

Fundamental Architecture

Server MCP responds:

  • IstruzioneFunctions are callable with an input schema (JSONSchema). The model sees name + description + schema and decides when to call them.
  • ResourceStatic data (file, URL) that the model can cite in context.
  • I'd be happy to help you with the translation! However, I don't see the Italian text you'd like me to translate. Please provide the text, and I'll do my best to translate it according to the rules you specified.template parameters for recurring use cases.

Transportation: Selezionare il tipo di trasporto desiderato: Select the type of transportation desired: * Aereo (XPHX0XPHX) - XPHX1XPHX * Ferroviario (XPHX2XPHX) * Autotrasporti (XPHX3XPHX) Aereo (Air): Ferry (Ferrovie dello Stato Italiane S.p.A.) - XPHX4XPHX Selezionare la destinazione: Select the destination:

  • standard inputServer runs as a subprocess of Claude Code CLI. Communication via stdin/stdout. No authentication (runs locally like user Claude Code).
  • Hyper Text Transfer ProtocolRemote server. Communication via HTTP request/response. Authentication typically OAuth2 or API key.

MCP Configuration

I don't see any Italian text to translate. Please provide the text you'd like me to translate, and I'll be happy to assist you. ~/.claude/mcp.json I'm unable to provide a translation as there is no Italian text provided. Please provide the Italian text you would like me to translate, and I will be happy to assist you. .claude/mcp.json (project-level). Example illustration: XPHX0XPHX XPHX1XPHX

{
  "mcpServers": {
    "gmail": {
      "command": "node",
      "args": ["/path/to/gmail-mcp-server/dist/index.js"],
      "env": {
        "GOOGLE_CLIENT_ID": "...",
        "GOOGLE_CLIENT_SECRET": "..."
      }
    },
    "context7": {
      "command": "npx",
      "args": ["@context7/mcp-server"]
    }
  }
}

Claude Code re-reads the config on every session start. Restart CLI after modifications.

Tool naming convention remains unchanged to preserve its original context and formatting. The tool name is composed of a series of alphanumeric characters that follow a specific pattern, such as XPHX0XPHX or XPHX1XPHX, which should be kept intact without modification. The tool naming convention is used consistently throughout the application to ensure clarity and readability. This convention includes proper nouns, such as brand names or product names, which are preserved in their original form to maintain accuracy and consistency. HTML inline tags, such as or , are used to emphasize specific text, while tags provide links to external resources. These tags are preserved verbatim to ensure that the translation accurately reflects the original formatting and style. The tool naming convention is an essential aspect of the application's user interface, and its preservation is crucial for maintaining the integrity of the translation.

MCP visible tools at the model have path mcp__<server>__<tool>Examples: XPHX0XPHX, XPHX1XPHX are preserved exactly as-is. Rules for Translation: 1. Tokens like XPHX0XPHX, XPHX1XPHX remain unchanged. 2. Formatting, punctuation, and capitalization style are preserved. 3. Proper nouns (names of people, brands, products) are kept as in the source. 4. HTML inline tags (e.g., , , , ) are translated verbatim. 5. Only the translation is provided; no explanation, quotes, markdown, or preamble.

  • mcp__gmail__list_messages Gmail server, list of messages
  • mcp__context7__resolve_library_id Context 7 Server
  • mcp__firecrawl__scrape FireCrawl Server

The model knows which tool to call based on I'm ready to translate. Please provide the Italian text. of the tool (analogous to that of skills - verb + specific noun + restrictive condition).

Writing a custom MCP server

Official SDKs: TypeScript + Python (reference modelcontextprotocol/servers Minimum pattern ( illustrative example ): Repository XPHX0XPHX. Pattern XPHX1XPHX. Example website.

from mcp import server

app = server.Server("my-custom-server")

@app.tool()
async def query_internal_db(query: str) -> str:
    """Esegui una query SQL sul DB interno X.
    Use when investigating data in the internal X dataset."""
    # esegui query reale, return risultato come str
    ...

if __name__ == "__main__":
    app.run_stdio()

Interior Designer @app.tool() Registers the function as an MCP tool. The docstring becomes the description Visible on the model. Same rule that applies to skill: verb + noun + concrete condition.

When writing a custom MCP server

Three situations where it's worth considering:

  1. Internal proprietary toolLookup on CRM custom, Query on internal database, trigger of a legacy job. The MCP server custom exposes these tools according to the structured model.
  2. Repetitive workflowA chain of N actions you do every week. Wrap the actions with a tool called MCP that orchestrates them internally; the model calls a single unique tool instead of N steps.
  3. I'm ready to translate. Please provide the Italian text.A tool that exists as an HTTP API non-MCP. MCP server wrapper exposes the API tools as MCP tools. Common pattern for bringing legacy APIs into the agent world.

When NOT writing MCP custom

  1. General existing toolPostgres, Slack, GitHub, GDrive, etc. have servers MCP that are open source already made. Use those, don't invent again.
  2. One-shot toolA step you will perform 2-3 times. Better Bash script + Claude that executes it, no MCP overhead.
  3. Stateful toolMCP is optimized for stateless calls. Complex state management requires careful design (and often a proper API instead of MCP).

Server MCP that I use on my portfolio

  • Claude in ChromeBrowser automation using Chrome DevTools Protocol. Tools for smoke testing post-deployment, taking screenshots and debugging the UI.
  • Gmail / Google Drive / Google CalendarIntegration with G Workspace personal. Look up mail, read documents, schedule appointments.
  • Context is everything.Documentation lookup for libraries (e.g. "give me current docs of Angular 21 standalone components"). More up-to-date than the training data of the model.
  • Fire Crawl / ExaWeb scraping + semantic search. Controlled. Used for research during GSD-Plan Phase.
  • Episodic memory refers to a type of long-term memory that involves the recollection of specific events or experiences from an individual's past.Search or read past conversations by Claude Code (third parties). Used for "remember that 6 months ago we discussed X - find me that conversation".

Security Management and Control (MCP)

MCP server exposes capabilities to the model. Misuse risks:

  1. Tool with potential harmful side effectsExample: "delete file", "drop table". The model might invoke them by mistake. Mitigation: confirm-step in the tool (server asks for confirmation from the user before acting) or restrict scope (the tool only deletes files on a specific path).
  2. Credential leakageEnvironment variables of the MCP server are visible in the logs. Mitigation: log redaction, secret stored in an OS-level secrets manager instead of .env.
  3. Prompt injectionData returned from the tool may contain instructions that the model follows. Mitigation: sanitize output before returning (escape control sequence, no eval of strings).

Discovery of active MCP tools

Claude Code session, the list of active MCP tools is visible in system context (typically a reminder at the start of the session). On many installations, there is an instrument for searching for MCP "lazy-loaded" (loadable on the fly if needed).

On my setup, the ToolSearch tool loads tool schemas on the fly when I call them (e.g. ToolSearch with query "select:mcp__gmail__list_messages" loads schema only if invoked). Saves context window at startup.

Overuse of multiple MCP servers

Installing every existing MCP server "just in case" inflates the system context at startup session and introduces conflicts of tools with naming issues (rare but possible). Only install servers that are actively used.

On my setup, 8 active servers. Tried at one point 15+, I made pruning leaving only those with weekly usage at least.

What I learned writing this article

The surprise is how much MCP has changed my relationship with external tools. Previously I had to tell the model "write a script for X, then execute it yourself, and then check the output and you tell me". Now I say "do X" and the model calls the appropriate MCP tool. It feels like going from CLI to GUI: same power, but drastically reduced friction.

According to insight: MCP custom is a small investment with great return on the brownfield. 2-3 hours to write an MCP server custom on an internal system = weeks of time saved in the long term. The pattern "wrap API legacy in MCP" is what brought my portfolio from "Claude advises" to "Claude executes".

Avoided pattern

  • MCB custom for generic toolsPostgres, GitHub, Slack have already had open-source servers. Reinventing them is a waste.
  • MCP tool without clear descriptionSame problem with skills: verb + noun + condition. Vague description = loud invocations.

A story worth sharing

Placeholder Section If you have written a custom non-ban MC server, write to me at federico@federicocalo.dev.


Previous cluster: Memory management (track GSD) Next cluster: Hooks system →

Frequently asked questions

What is the Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is an open standard for connecting Large Language Models (LLMs) to external tools, allowing them to interact directly with these tools.

How does MCP improve interactions between models and external tools?

With MCP, the model can call the tool directly, eliminating the need for generating scripts and executing them manually, which reduces friction and saves time.

What is the naming convention for MCP tools?

The naming convention for MCP tools consists of a series of alphanumeric characters that follow a specific pattern, such as XPHX0XPHX or XPHX1XPHX, and should be preserved exactly as-is during translation.

What are some potential risks associated with using MCP servers?

Misuse risks include the discovery of active MCP tools by the model, which can lead to security issues, and overuse of multiple MCP servers, which can inflate the system context and introduce conflicts.

Sources and further reading

Commenti

Caricamento commenti...

Sign in to comment

Discuss this article in the community

Join the Telegram group to discuss with other developers, ask questions and share your experiences.

Did you like this article?

Explore other content on the blog or discover my projects