Skip to main content
Guide contents
Intermediate12 min

MCP Servers and Claude Code: A Practical Guide to Connecting and Building

How to expand Claude Code's capabilities with Model Context Protocol: connecting the filesystem, GitHub, PostgreSQL, Brave Search, and developing a custom server in TypeScript.

Published:

Out of the box, Claude Code can already inspect local files, run terminal commands, and edit project code. However, in real-world development workflows, that is rarely enough: you frequently need to query a PostgreSQL database, check open Pull Requests on GitHub, fetch the latest cloud documentation, or trigger internal corporate APIs.

To solve this problem, Anthropic introduced the Model Context Protocol (MCP) — an open standard that turns Claude Code from a local repository assistant into a full-fledged orchestration hub for external systems and services.

In this practical guide, we'll examine MCP architecture, configure official ready-made servers, build a custom TypeScript server from scratch, and verify our setup with hands-on practice tasks.


1. What is an MCP Server

Model Context Protocol (MCP) is an open communication protocol designed by Anthropic that standardizes how Large Language Models (LLMs) interact with external tools and structured data sources.

Instead of writing custom, proprietary integrations for every service, MCP introduces a unified client-server architecture:

text
┌─────────────────────────────────────────────────────────────┐ │ Claude Code (Client) │ └──────────────────────────────┬──────────────────────────────┘ │ JSON-RPC 2.0 (stdio / SSE) ▼ ┌─────────────────────────────────────────────────────────────┐ │ MCP Server (Adapter) │ └──────┬───────────────────────┼───────────────────────┬──────┘ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Local Files │ │ GitHub API │ │ PostgreSQL │ │ and Notes │ │ and Issues │ │ Database │ └─────────────┘ └─────────────┘ └─────────────┘

Every MCP Server exposes three fundamental primitives to the model:

  • Tools — Executable functions with typed JSON Schema parameters that Claude Code can invoke autonomously during problem solving (e.g., create_issue, execute_query).
  • Resources — Passive data or schemas that the assistant can read as input context (files, database schemas, application logs).
  • Prompts — Pre-configured prompt templates that simplify repetitive operational tasks.

Capability Comparison

ScenarioWithout MCP (Default Claude Code)With Connected MCP Servers
File AccessRestricted strictly to the current project directoryAccess to any permitted external folders and notes
Repository DataLocal files only via git diff / git logRead issues, pull requests, reviews, and GitHub APIs
DatabasesOnly if a local CLI client is manually runDirect schema inspection, table queries, and SQL execution
Information SearchLocal grep / ripgrep in project filesLive web search via Brave Search / Tavily
Internal ServicesUnavailable without custom shell scriptsDirect function calls to microservices via typed SDKs

2. Architecture and Request Lifecycle

MCP communication is built on the standard JSON-RPC 2.0 protocol. For local tools, communication takes place over standard input/output streams (stdio), while remote servers utilize Server-Sent Events (SSE) or HTTP.

Step-by-Step Request Lifecycle

  1. Initialization & Handshake: When a Claude Code session starts, it reads the configuration, spawns configured server processes, and requests their available tools (tools/list).
  2. Capability Publishing: Each MCP Server returns its supported methods, complete with JSON schemas for arguments and descriptions of what each tool does.
  3. Intent Detection: When you enter a natural language prompt, Claude compares your request against the registered tools.
  4. Tool Execution Request: If external data or actions are required, Claude sends a structured tools/call JSON-RPC request to the server with valid arguments.
  5. Server Execution: The server communicates with the external database, API, or disk, and returns the result to the client.
  6. Context Synthesis: Claude interprets the raw payload and crafts a coherent, formatted answer for you.
Note

The entire workflow is transparent to the developer: you don't need to memorize function signatures or CLI flags. Claude automatically selects the right tool based on the context of your task.


3. Connecting an MCP Server to Claude Code

MCP servers are registered using JSON under the mcpServers key. Claude Code supports two configuration tiers:

  1. Project-level (.claude/settings.json) — Scoped exclusively to the current project directory and safely commit-ready for your team.
  2. Global-level (~/.claude/settings.json) — Available across all projects for your local operating system user.
json
{ "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-filesystem", "./docs" ] } } }

Configuration Schema Parameters

Each server definition in mcpServers consists of three core properties:

ParameterTypeRequiredDescription and PurposeExample Values
commandstringYesExecutable binary used to start the server process"npx", "node", "uvx", "docker"
argsstring[]YesArray of startup arguments (package names, paths, flags)["-y", "@anthropic-ai/mcp-filesystem", "/path"]
envobjectNoEnvironment variables for authentication tokens and API keys{"GITHUB_TOKEN": "ghp_...", "DEBUG": "1"}
Tip

For Python-based MCP servers, you can run uvx instead of npx, for example: "command": "uvx", "args": ["mcp-server-git"].


4. Catalog of Ready-Made MCP Servers

Anthropic and the open-source community provide production-ready servers for common developer tools. You don't need to write code from scratch — simply install and run the appropriate npm or python package.

ServerOfficial PackageAuthentication / AccessCore Capabilities
Filesystem@anthropic-ai/mcp-filesystemPermitted directory pathsRead, write, and search files outside project roots
GitHub@anthropic-ai/mcp-githubPersonal Access Token (GITHUB_TOKEN)Search repositories, read issues, review & open PRs
PostgreSQL@anthropic-ai/mcp-postgresConnection string URIInspect schemas, read tables, execute SQL queries
Brave Search@anthropic-ai/mcp-brave-searchSearch API Key (BRAVE_API_KEY)Live internet search without hallucinations

1. Filesystem Server

Gives Claude Code access to directories outside the repository (e.g., a shared notes directory or Obsidian vault):

json
{ "mcpServers": { "docs": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-filesystem", "/Users/username/Developer/knowledge-base" ] } } }

2. GitHub Server

Enables the assistant to interact directly with GitHub issues, PR reviews, and commit history:

json
{ "mcpServers": { "github": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-github" ], "env": { "GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } } }

3. PostgreSQL Server

Allows Claude Code to run analytical or diagnostic SQL queries against your local or remote database:

json
{ "mcpServers": { "postgres": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-postgres", "postgresql://postgres:password@localhost:5432/my_app_db" ] } } }

4. Brave Search Server

Integrates a real-time web search engine so Claude can check recent library release notes, patch advisories, and documentation:

json
{ "mcpServers": { "brave-search": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-brave-search" ], "env": { "BRAVE_API_KEY": "BSAu_your_brave_search_api_key" } } } }

5. How Claude Code Uses Tools in Conversation

Once a server is registered, you do not need special commands or flags. Claude Code inspects your natural language prompt and autonomously decides when to trigger a tool.

Workflow Example: Interacting with GitHub

User Prompt:

"Check the open issues assigned to me in the acme/platform repository and summarize the most urgent ones."

Internal Claude Code Lifecycle:

  1. Claude identifies that local repository files lack this remote metadata.
  2. It generates a mcp__github__search_issues call with filters repo:acme/platform state:open assignee:@me.
  3. The GitHub server returns structured JSON records.
  4. Claude synthesizes the data into clean, readable output:
markdown
Found 3 open issues assigned to you: 1. **#42 — Fix login redirect loop** (Priority: High, Created: 2 days ago) 2. **#38 — Add rate limiting to auth API** (Priority: Medium, Created: 5 days ago) 3. **#35 — Update user profile settings page** (Priority: Low, Created: 1 week ago) Would you like to examine the codebase to patch the redirect loop in #42?

6. Building a Custom MCP Server in TypeScript

When ready-made servers don't cover your proprietary internal APIs or domain-specific workflows, you can build a custom MCP Server in minutes using @modelcontextprotocol/sdk.

Step 1. Project Initialization and Dependencies

Create a dedicated directory and install the necessary libraries:

bash
mkdir my-mcp-server && cd my-mcp-server npm init -y npm install @modelcontextprotocol/sdk zod npm install -D typescript @types/node tsx

Step 2. Server Implementation (server.ts)

Create server.ts defining the server and a custom tool:

typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; // 1. Initialize server with descriptive metadata const server = new McpServer({ name: "internal-crm-server", version: "1.0.0", }); // 2. Register a tool with typed Zod input validation server.tool( "lookup-user", "Look up a customer profile by their email address", { email: z.string().email().describe("Registered user email address"), }, async ({ email }) => { // Replace with real database or microservice query const mockUser = { id: "usr_99812", email, name: "Alex Kowalski", plan: "Enterprise", status: "active", createdAt: "2024-03-15T10:00:00Z", }; return { content: [ { type: "text", text: JSON.stringify(mockUser, null, 2), }, ], }; } ); // 3. Connect the server via stdio transport async function run() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Internal CRM MCP server started on stdio"); } run().catch((error) => { console.error("Server startup error:", error); process.exit(1); });

Step 3. Registering the Server in Settings

Register your script in .claude/settings.json:

json
{ "mcpServers": { "crm": { "command": "npx", "args": [ "tsx", "/Users/username/Developer/my-mcp-server/server.ts" ] } } }
Tip

Running TypeScript with tsx avoids having to pre-compile your files with tsc during development.


7. Security and Sandbox Isolation

MCP gives Claude Code significant autonomy, but also allows code execution and data access on your machine. Follow these security rules:

1. Servers Inherit Your Permissions

MCP servers run under your operating system user account. A buggy or malicious server has the same file and network permissions as your shell.

2. Secret and Token Isolation

Never commit secrets to git. Store sensitive credentials in ~/.claude/settings.json or source them via .env files added to .gitignore.

3. Audit Third-Party Packages Before Launch

Before connecting community servers:

  • Verify that the source code is public and active.
  • Inspect network requests initiated during startup.
  • Review what directories the server accesses.

4. Configuration Level Separation

text
┌─────────────────────────────────────────────────────────────┐ │ ~/.claude/settings.json │ │ Global Tools: GitHub, Web Search, Browser Automation │ └──────────────────────────────┬──────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ .claude/settings.json │ │ Project Tools: Local Dev DB, custom repository scripts │ └─────────────────────────────────────────────────────────────┘
Warning

Do not connect MCP servers with write access to production databases during interactive development sessions. Use read-only database replicas or isolated Docker containers instead.


8. Hands-On Practice: Step-by-Step Setup

Follow these two exercises to connect and test MCP servers in your environment.

Task 1. Connecting the GitHub MCP Server

  1. Generate a GitHub Personal Access Token (repo and read:org scopes).
  2. Add the server to ~/.claude/settings.json:
json
{ "mcpServers": { "github": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-github" ], "env": { "GITHUB_TOKEN": "ghp_your_token_here" } } } }
  1. Launch a new Claude Code session and run a test prompt:
bash
claude

Test Prompt:
"Show my 5 most recently updated repositories on GitHub and their current status."

  • Claude Code calls the GitHub tool without authentication errors.
  • Returns your repository list accurately.

Task 2. Connecting the Filesystem Server for External Notes

  1. Configure the filesystem server in .claude/settings.json:
json
{ "mcpServers": { "external-docs": { "command": "npx", "args": [ "-y", "@anthropic-ai/mcp-filesystem", "/path/to/your/notes/folder" ] } } }
  1. Test with the following prompt:

Test Prompt:
"Find all markdown files in external-docs discussing API architecture and give me a high-level summary."

  • Claude accesses files outside the current project root.
  • Successfully synthesizes information from external files.

9. Quick Knowledge Check

Test your understanding of Model Context Protocol architecture.

Question 1. What is the primary purpose of an MCP Server?

  • A. A cloud VM for hosting Claude foundation models
  • B. An adapter process giving LLMs standardized access to external tools and data
  • C. A library for compressing vector embeddings
  • D. A web server for hosting compiled frontend code
Tip

Correct Answer: B.
An MCP Server acts as an adapter bridging models and external tools, exposing standard Tools, Resources, and Prompts.


Question 2. Where is repository-specific MCP configuration stored?

  • A. ~/.claude/settings.json
  • B. package.json
  • C. .claude/settings.json in the project root
  • D. CLAUDE.md
Tip

Correct Answer: C.
Project-specific configuration lives in .claude/settings.json, whereas ~/.claude/settings.json houses machine-wide developer tools.


Question 3. How does Claude Code decide which tool to trigger?

  • A. The user must supply a --tool=name CLI flag with every query
  • B. You must first run /mcp select
  • C. The model evaluates the prompt against registered JSON schemas and chooses autonomously
  • D. All tools run simultaneously and redundant results are discarded
Tip

Correct Answer: C.
Claude compares the user's intent with registered tool descriptions and schemas, dispatching requests with valid parameters when needed.


10. Architecture Summary and Checklist

Model Context Protocol elevates Claude Code into an extensible AI development environment. Instead of manually pasting file contents or schema dumps into chats, you establish persistent, secure communication channels once.

Environment Readiness Checklist

  • Configuration Tiers: Global tools live in ~/.claude/settings.json; project-specific servers live in .claude/settings.json.
  • Security Guardrails: Tokens are excluded from version control; databases use read-only privileges.
  • Verification: Server tools are verified with targeted prompts upon session startup.
  • Extensibility: Custom servers can be scaffolded rapidly in TypeScript using @modelcontextprotocol/sdk.
This guide is completely free. If it saved you an evening, you can support the project's growth.
Support the author