Skip to content

Claude Code MCP Servers: How to Extend Your AI Agent with Custom Tools

Claude Code MCP Servers

I kept getting hallucinated package names. Claude would suggest imports that didn’t exist, reference APIs that were deprecated, and recommend tools that weren’t even real. The worst part? I couldn’t blame the model—it just didn’t have access to the right context.

Then I discovered MCP servers in Claude Code.

The Problem: AI Coding Assistants Lie

Not intentionally. They hallucinate because they lack real-time access to package registries, internal documentation, and tool catalogs.

I asked Claude to add a caching layer to my Node.js API. It suggested using node-cache-manager-redis-store. Sounded reasonable. I installed it, wrote the code, ran my tests… and got a wall of errors.

The package was deprecated. Had been for two years.

This isn’t unique to Claude. Every LLM-based coding assistant has this problem:

  • Hallucinated dependencies: Packages that don’t exist or are deprecated
  • Outdated API usage: Methods removed in newer versions
  • Missing context: No access to your internal tools or documentation
  • Generic suggestions: One-size-fits-all advice that misses your ecosystem

MCP: Model Context Protocol

MCP (Model Context Protocol) is the solution. It’s an open protocol that lets you connect external tools and data sources directly to Claude Code.

Think of it as giving Claude access to a library of real, verified information instead of relying on its training data alone.

┌─────────────────────────────────────────────────────────────────┐
│ Claude Code │
│ (AI Coding Agent) │
└─────────────────────────────────────────────────────────────────┘
│ MCP Protocol
┌─────────────────────────────────────────────────────────────────┐
│ MCP Server Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Package │ │ Context7 │ │ Custom │ │
│ │ Registry │ │ Docs │ │ APIs │ │
│ │ (npm/pypi) │ │ Database │ │ (Internal) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Verified Data Sources │
│ • Real package metadata │
│ • Official documentation │
│ • Internal company APIs │
│ • Tool catalogs (8000+ tools) │
└─────────────────────────────────────────────────────────────────┘

Why MCP Reduces Hallucinations

Traditional AI assistants work like this:

User Question → LLM Training Data → Best Guess Answer
(may be outdated/wrong)

With MCP servers:

User Question → MCP Server Query → Real Data → Verified Answer
(from live source)

The key difference: MCP servers provide ground truth data. When Claude needs to know if a package exists, it queries the actual package registry. When it needs to understand an API, it reads the actual documentation.

How to Configure MCP Servers in Claude Code

MCP servers are configured in your Claude Code settings. Here’s a practical configuration example:

claude-settings.json
{
"mcpServers": {
"context7": {
"command": "mcp-server-context7",
"args": ["--docs-path", "/path/to/your/docs"]
},
"fetch": {
"command": "mcp-server-fetch",
"args": []
},
"postgres": {
"command": "mcp-server-postgres",
"args": ["--connection-string", "${DATABASE_URL}"]
}
}
}

Each MCP server exposes specific capabilities:

ServerPurposeHallucination Reduction
context7Official documentation lookupNo outdated API usage
fetchWeb content retrievalReal-time data access
postgresDatabase schema awarenessCorrect table/column names
npm-searchPackage registry queriesNo fake packages

A Real Example: Before and After MCP

Before MCP - I asked Claude to implement rate limiting:

Claude: "Use the `express-rate-limit-middleware` package..."
Me: *installs package*
npm ERR! 404 Not Found - GET https://registry.npmjs.org/express-rate-limit-middleware

The package didn’t exist. Claude hallucinated a plausible-sounding name.

After MCP - With package registry access:

Claude: "Searching npm registry... Found `express-rate-limit` with 2M weekly downloads,
last updated 2 weeks ago. Here's the implementation..."

The difference? Claude verified the package exists before recommending it.

Agent Teams: The Killer Feature

MCP also enables something even more powerful: agent teams.

Instead of one Claude doing everything, you can have specialized agents coordinated through MCP:

┌────────────────────────────────────────────────────────────┐
│ Your Project │
└────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Planner │ │ Builder │ │ Reviewer │
│ Agent │───▶│ Agent │───▶│ Agent │
│ │ │ │ │ │
│ Uses: docs │ │ Uses: npm │ │ Uses: tests │
│ MCP server │ │ MCP server │ │ MCP server │
└──────────────┘ └──────────────┘ └──────────────┘

Each agent has access to specific MCP servers relevant to its task:

  • Planner agent: Reads documentation, searches web context
  • Builder agent: Queries package registries, accesses code templates
  • Reviewer agent: Runs tests, checks security databases

What Can You Connect via MCP?

The ecosystem is growing rapidly. Here are the most useful MCP servers I’ve configured:

Documentation & Context

  • context7 - Search official documentation databases
  • fetch - Retrieve web content and APIs
  • github - Access repositories, issues, and PRs

Package Management

  • npm-search - Query npm registry directly
  • pypi - Python package information

Data Sources

  • postgres / sqlite - Database schema awareness
  • filesystem - Local file operations
  • google-drive - Document access

Development Tools

  • puppeteer - Browser automation
  • docker - Container management

Setting Up Your First MCP Server

Let’s walk through adding a package registry MCP server:

mcp-config.json
{
"mcpServers": {
"npm-search": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-server-npm-search"]
}
}
}

Now when you ask Claude about a package:

You: "Add a Redis caching layer to my Express app"
Claude: *queries npm-search MCP server*
"Found `connect-redis` (express-session store) and `redis` (node-redis client).
The `redis` package has 4M weekly downloads and was updated 3 days ago.
Here's the implementation..."

The Architecture Deep Dive

Understanding how MCP works under the hood helps you debug issues:

┌─────────────────────────────────────────────────────────────┐
│ Claude Code Process │
│ ┌─────────────────┐ ┌─────────────────────────────┐ │
│ │ Your Request │───▶│ MCP Client (built-in) │ │
│ └─────────────────┘ └─────────────────────────────┘ │
│ │ │
└────────────────────────────────────│─────────────────────────┘
│ JSON-RPC over stdio
┌─────────────────────────────────────────────────────────────┐
│ MCP Server Process │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Tools ──────▶ Functions Claude can call │ │
│ │ Resources ──▶ Data Claude can read │ │
│ │ Prompts ────▶ Pre-defined templates │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ External Data Source │
│ (npm registry, docs database, etc.) │
└─────────────────────────────────────────────────────────────┘

The protocol is simple: JSON-RPC messages over stdin/stdout. This means any language can implement an MCP server—Python, Node.js, Go, Rust, even shell scripts.

Common MCP Pitfalls

I’ve made these mistakes so you don’t have to:

  1. Not exploring MCP after switching to Claude Code: The default setup works fine, but you’re missing the real power.

  2. Assuming hallucinations are unavoidable: They’re not. MCP servers provide ground truth data that eliminates many hallucination sources.

  3. Using generic prompts when custom MCP would help: If you work with internal APIs or specialized tools, build a custom MCP server.

  4. Ignoring the agent teams feature: Coordinated agents with specialized MCP access are far more powerful than a single general-purpose agent.

When to Build a Custom MCP Server

Consider building your own MCP server when:

  • You have internal APIs that Claude should know about
  • Your team uses proprietary tools or libraries
  • You work with private documentation databases
  • You need real-time access to company-specific data

The MCP SDK makes this straightforward. Here’s the skeleton of a custom server:

custom_mcp_server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("my-custom-server")
@app.list_tools()
async def list_tools():
return [
Tool(name="query_internal_api", description="Query our internal API")
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "query_internal_api":
# Your custom logic here
return await query_internal_api(**arguments)
async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream)
  • Model Context Protocol Specification: The open standard that MCP implements
  • Function Calling: The underlying mechanism MCP uses to expose tools
  • RAG (Retrieval Augmented Generation): Similar concept, but MCP is more structured
  • LangChain Tools: Comparable ecosystem, but MCP is language-agnostic

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments