All posts

Mastering Claude Code (Part 4): MCP Protocol — Connecting AI to Your Entire Dev Stack

claude-codeaimcptutorial

When I first started using Claude Code, I realized something was missing: Claude could help me write code, but it was working blind. It couldn’t actually see my GitHub repos, peek at my database schema, or understand the real state of my codebase. I had to manually copy-paste errors, describe my setup, and explain what went wrong.

Then I discovered the Model Context Protocol (MCP), and everything changed.

MCP is like giving Claude a set of eyes and hands that can reach into your entire development stack. Your version control system, your databases, your file systems, your APIs — Claude can access them all in real time. It’s not magic, but it feels pretty close.

In this part of “Mastering Claude Code,” we’re diving deep into MCP: what it is, why it transforms your workflow, and how to set it up today.

What Is MCP? The Bridge Between AI and Your Tools

The Model Context Protocol is a standard for connecting large language models to external tools, data sources, and services. Think of it as a standardized way to say: “Hey Claude, here’s how you can read from GitHub. Here’s how you can query my database. Here’s how you can list files in my project.”

MCP servers act as adapters. They sit between Claude and your tools, translating Claude’s requests into actions your tools understand, and translating responses back into context Claude can use.

The beauty of MCP is that it’s standardized. Whether you’re connecting to GitHub, PostgreSQL, a custom API, or a local file system, the protocol works the same way. You’re not learning a different integration pattern for each tool — you’re learning one pattern and applying it everywhere.

Why This Matters: Real-Time Context Changes Everything

Before MCP, my workflow looked like this:

  1. Spot a bug
  2. Run tests locally
  3. Copy-paste the error message into Claude
  4. Manually describe my database schema
  5. Explain what my latest PR was trying to do
  6. Hope Claude had enough context to help

Now with MCP, I can ask Claude: “Review my latest PR, check the database schema, look at the test failures, and tell me what’s broken.” Claude can actually do those things and come back with a precise answer.

This isn’t just faster — it’s fundamentally different. Claude has real-time context. It sees your code as it actually is, not as you remember it. It can point to specific lines, reference actual schema constraints, and understand the real dependencies in your project.

For indie developers, this is a game-changer. You’re wearing all the hats — frontend, backend, DevOps, QA. MCP lets Claude wear some of those hats with you.

Setting Up Your First MCP Server: GitHub

Let’s start practical. I’ll walk you through connecting Claude Code to GitHub.

First, install the GitHub MCP server:

claude mcp add github -- npx -y @modelcontextprotocol/server-github

This command:

  • Creates a new MCP connection called “github”
  • Uses npx to run the official GitHub MCP server
  • Configures it for your Claude Code environment

Next, you’ll need authentication. The GitHub server uses your personal access token. Set it as an environment variable:

export GITHUB_TOKEN=ghp_your_token_here

You can create a personal access token in GitHub Settings → Developer Settings → Personal Access Tokens. Give it repo scope for full access, or limit it to public_repo if you want read-only on public repos.

Claude Code will now automatically have access to your GitHub repos. You can ask:

  • “What’s in my latest PR?”
  • “List all open issues in my project”
  • “Show me the commit history for this file”
  • “Did anyone comment on my code review?”

Project-Level Configuration: .mcp.json

For a more structured setup, create a .mcp.json file in your project root. This lets you version-control your MCP setup and share it with teammates.

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "GITHUB_REPO": "yourusername/yourrepo"
      }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
      "env": {}
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    }
  }
}

Claude Code reads this file and spins up all your MCP servers automatically. Environment variables are referenced with ${VAR_NAME} syntax — they’re loaded from your .env file or shell environment at runtime.

Never commit actual tokens to version control. Use .env (gitignored) or your CI/CD secrets management.

Common MCP Servers You’ll Want

The ecosystem is growing fast, but here are the essentials I use:

GitHub (@modelcontextprotocol/server-github) — PRs, issues, commits, code review. Essential for any collaborative project.

Filesystem (@modelcontextprotocol/server-filesystem) — Read and navigate your local file system. Claude can actually explore your project structure, read configs, and understand your architecture.

PostgreSQL (@modelcontextprotocol/server-postgres) — Query your database, inspect schemas, understand your data model in context.

SQLite (@modelcontextprotocol/server-sqlite) — For local/embedded databases.

File System Search — Built into most file system servers, but you can also use grep-like functionality to find patterns across your codebase.

Custom APIs — More on this later, but you can wrap any HTTP API in an MCP server.

You can enable multiple servers at once. Claude will use whichever tools are relevant to your question.

Real Workflow Example: Integrated Code Review

Here’s what an integrated workflow looks like. I open Claude Code and type:

“Review my latest PR. Check what tests are failing. Compare the new code against the database schema. What could break?”

Behind the scenes:

  1. Claude uses the GitHub server to fetch my latest PR diff
  2. Claude uses the filesystem server to find my test output
  3. Claude uses the PostgreSQL server to examine my schema
  4. Claude synthesizes all that context and spots the problem: “Your new users.email column is missing a UNIQUE constraint, but your code assumes it’s unique. This could cause bugs in production.”

I never had to manually check three different systems. Claude did it in parallel, in real time. That’s the power of MCP.

Building Custom MCP Servers

The built-in servers are great, but your stack is probably unique. Maybe you have a custom API, a specialized data source, or proprietary tools. That’s where custom MCP servers come in.

An MCP server is just a Node.js process that implements the protocol. At its core, you define “tools” — functions Claude can call. Here’s a minimal example:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({
  name: "my-custom-server",
  version: "1.0.0",
});

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "query_analytics",
      description: "Query custom analytics API",
      inputSchema: {
        type: "object",
        properties: {
          metric: { type: "string", description: "Metric name" },
        },
        required: ["metric"],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "query_analytics") {
    const metric = request.params.arguments.metric;
    // Call your API
    const result = await fetch(`/api/analytics?metric=${metric}`);
    return { content: [{ type: "text", text: JSON.stringify(result) }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

Add it to .mcp.json, and Claude can now query your analytics, call your proprietary APIs, or integrate with whatever custom tools you’ve built.

Security: Doing MCP Right

MCP gives Claude powerful access. You need to be thoughtful about security.

Use environment variables for secrets. Never hardcode tokens. Store them in .env (gitignored) or your deployment environment.

Apply the principle of least privilege. If Claude only needs to read your database, give it a read-only user. If it only needs to see public repos, use a token scoped to public repos only.

Audit what Claude accesses. MCP servers log what tools Claude calls. Review these logs periodically to make sure Claude isn’t accessing data unnecessarily.

Be cautious with write operations. Most of my MCP servers are read-only. If I need Claude to write code, I have it draft changes and I review them before running them. Only in trusted, automated workflows do I give Claude write access.

Keep MCP servers updated. Like any dependency, update them regularly for security patches.

What’s Next?

We’ve connected Claude to your entire stack. In Part 5, we’re diving into Hooks — the automation layer that triggers Claude to act on events. When a test fails, when a PR lands, when an error is logged — Claude can respond automatically.

Your development workflow is about to get a lot smarter.


What MCP servers would you set up first? Hit reply and let me know what tools you’d most want Claude to access. I read every response.

More from the studio.

Back to blog