devAlice
← AI Agents

MCP Servers — Connect External Tools to Claude Code / Cursor

Expose filesystem, GitHub, DB, Slack to AI agents via Model Context Protocol. Setup, debugging, security.

Model Context Protocol (MCP) is the standard for exposing external tools and data to AI agents. Anthropic's open spec, adopted by Claude Code, Cursor, Continue, and others — they share the same interface.

In plain terms: "I want GPT or Claude to directly touch my filesystem / DB / GitHub, without writing custom API wrappers each time."

This guide covers the core concepts, common server setups, debugging, and security.

TL;DR

  1. MCP is JSON-RPC over stdio/SSE — exposes tools via standardized RPC
  2. Official servers: filesystem, GitHub, Slack, Postgres, Puppeteer, etc. — @modelcontextprotocol/server-*
  3. One client config: Claude Code uses ~/.claude/settings.json, Cursor uses its Settings UI — same JSON schema
  4. Security rule #1: prefer read-only servers; for writable ones, explicit whitelist directories only

Prerequisites

  • Node.js 20+ (for npx)
  • One MCP-compatible client — Claude Code or Cursor
  • API tokens for any services you'll expose (GitHub PAT, Slack, etc.)

1. MCP Concepts in 30 Seconds

TermMeaning
HostAI agent (Claude Code, Cursor)
ServerA process that exposes tools/resources (filesystem, GitHub)
ClientThe adapter the host spawns to talk to each server
Transportstdio (local child process) or SSE (HTTP remote)
ToolA function the server exposes — AI can call it
ResourceData the server exposes — AI can read it
PromptA prompt template the server provides

2. Add MCP in Claude Code

2.1 Settings File

~/.claude/settings.json:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/me/projects",
        "/Users/me/notes"
      ]
    }
  }
}
  • Command args = the directories to expose. Whitelist — nothing else is reachable.
  • Absolute paths. ~/ doesn't expand.

2.2 Restart Claude Code

# After ending the previous session
claude

2.3 Verify

Inside Claude Code:

What tools are available?

If filesystem MCP's read_file, write_file, list_directory show up, you're good.

3. Add MCP in Cursor

Settings (⌘,) → Features → MCP → Add Server. JSON:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    }
  }
}

Same schema. You can share config with Claude Code — copy ~/.claude/settings.json.

4. Six Common Servers

4.1 Filesystem

"filesystem": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
}

Read / write / search files. Enforces a path whitelist.

4.2 GitHub

"github": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-github"],
  "env": {
    "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
  }
}

Issues, PRs, code search. PAT scopes: minimum required (repo, read:user).

4.3 Slack

"slack": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-slack"],
  "env": {
    "SLACK_BOT_TOKEN": "xoxb-...",
    "SLACK_TEAM_ID": "T..."
  }
}

Channel reads / sends. Prefer bot token over user token.

4.4 PostgreSQL (read-only)

"postgres": {
  "command": "npx",
  "args": [
    "-y",
    "@modelcontextprotocol/server-postgres",
    "postgresql://readonly_user:pass@localhost/mydb"
  ]
}

Connect as a read-only user — the AI can run arbitrary queries, so split privileges.

4.5 Puppeteer

"puppeteer": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
}

Real browser automation. Screenshots, DOM manipulation, JS execution.

4.6 SQLite

"sqlite": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-sqlite", "/path/to/db.sqlite"]
}

Great for local SQLite analysis.

5. Manage Secrets via 1Password

Don't write tokens as plaintext in JSON. Use the pattern from multi-os/password-manager:

Option A — chezmoi template

Place ~/.claude/settings.json under chezmoi and use {{ onepasswordRead "op://..." }}.

Option B — Wrapper script

# ~/bin/mcp-github.sh
#!/bin/bash
export GITHUB_PERSONAL_ACCESS_TOKEN="$(op item get GitHub --fields token --reveal)"
exec npx -y @modelcontextprotocol/server-github

settings.json:

"github": {
  "command": "/Users/me/bin/mcp-github.sh"
}

op CLI auto-unlocks via GUI biometric — smooth.

6. Write a Custom MCP Server

Ten minutes to expose your own tool. Node.js (my-server.js):

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
 
const server = new Server(
  { name: "my-tools", version: "0.1.0" },
  { capabilities: { tools: {} } }
);
 
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "echo",
      description: "Echo back input",
      inputSchema: {
        type: "object",
        properties: { msg: { type: "string" } },
        required: ["msg"],
      },
    },
  ],
}));
 
server.setRequestHandler(CallToolRequestSchema, async (req) => {
  if (req.params.name === "echo") {
    return { content: [{ type: "text", text: req.params.arguments.msg }] };
  }
  throw new Error(`Unknown tool: ${req.params.name}`);
});
 
await server.connect(new StdioServerTransport());
"my-tools": {
  "command": "node",
  "args": ["/Users/me/code/my-server.js"]
}

See the MCP SDK official examples.

7. Debugging

Tools Don't Appear

  • Fully restart the client (Claude Code/Cursor)
  • Verify npx is runnable — which npx / Node 20+
  • Server logs — for Claude Code, check system logs or stderr

MCP Inspector

Official debug tool:

npx @modelcontextprotocol/inspector npx -y @modelcontextprotocol/server-filesystem /tmp

A browser UI for direct RPC calls — visualize tool definitions and responses.

Slow Responses

  • First call: npx -y downloads the package — slow once, fast after caching
  • Permanent install: npm i -g @modelcontextprotocol/server-filesystem then command: "mcp-server-filesystem"

8. Security

Whitelist Folders Only

For filesystem, always pass explicit path arguments. Omit them and the entire home directory is exposed.

Read-Only DB Users

For Postgres/SQLite, create a separate readonly user. The AI shouldn't be able to DROP TABLE.

Minimal Token Scopes

GitHub PAT: repo + read:user. No admin:org.

Avoid Env Leaks

Don't commit settings.json. If you must, use chezmoi/secret integration (§5).

Don't Trust Random MCP Servers

Stick to official @modelcontextprotocol/* or OSS you can audit. Don't hand tokens to arbitrary npm packages.

Verification

  1. After editing settings.json, restart Claude Code → ask "show available tools" → new server tools appear
  2. "Show me files in the root" (with filesystem server)
  3. "Summarize the latest 5 PRs" (GitHub server)
  4. Verify tool definitions with MCP Inspector
  5. Attempt a path outside the whitelist → rejected

Troubleshooting

npx -y Can't Find the Package

  • Package name typo for @modelcontextprotocol/server-XXX is common. Check the official list
  • On corporate npm registries, set fallback to public registry in npmrc

Path Breaks on Windows

Escape \ or use / in JSON:

"args": ["-y", "@modelcontextprotocol/server-filesystem", "C:/Users/me/projects"]

Claude Code Doesn't Recognize It

  • Validate ~/.claude/settings.json syntax — jq . ~/.claude/settings.json
  • Confusion with other settings.json locations (~/.claude.json, .claude/settings.json in project)

Some Tools Missing in Response

Servers with nondeterministic tool listing can vary on restart. Make the listTools handler deterministic.

Token Accidentally Committed

Rotate immediately (GitHub → Personal access tokens → Revoke + reissue). Scrub git history with git filter-repo.

References

Changelog

  • 2026-05-12: First draft. Concepts + client setup + 6 servers + secrets management + custom server + debugging + security + five troubleshooting cases.

Comments