· mcp tutorial · beginner · april 2026 ·

How to Set Up an MCP Server from Scratch (2026)

CLAUDE CODE MCP filesystem github ← active supabase + memory + stripe + playwright
// FILED MCP Tutorial// DATE APR 28, 2026// SLUG /blog/how-to-set-up-mcp-server-from-scratch-2026.htmlcite this →

MCP (Model Context Protocol) gives Claude Code the ability to call external tools—read from your database, search GitHub issues, run Playwright browser tests—without those tools having to be built into Claude Code itself. If you've seen references to MCP servers and haven't set one up yet, this guide goes from zero to a working server in under 20 minutes.

This is a different angle from the MCP Server Tutorial 2026 post, which covers intermediate configuration and multi-server setups. This post starts earlier: what MCP actually is, how the config file works, and the exact error messages you'll see on the first attempt.

What MCP is in one paragraph

MCP is a JSON-RPC protocol that lets Claude Code communicate with external processes during a session. Each MCP server is a separate process that exposes "tools"—named functions Claude can call. When you configure a server, Claude Code starts it as a subprocess, maintains a persistent connection, and can invoke its tools the same way it invokes built-in tools like file reading or bash execution. The model doesn't know the difference between a built-in tool and an MCP tool. From Claude's perspective, it's just a function it can call.

This means: anything you can wrap in a function that takes parameters and returns text or structured data can become an MCP tool. Database queries, API calls, file system operations on a remote server, browser automation—all of it is in scope.

Before you start: the three things you need

  1. Claude Code installed and authenticated. You need claude in your PATH and a working API key. If you don't have this yet, run npm install -g @anthropic-ai/claude-code and then claude auth.
  2. Node.js 18+ or Python 3.10+, depending on which server you're installing. Most popular MCP servers are Node packages. A few (including the official filesystem server) also have Python versions.
  3. The server package name. MCP servers are distributed as npm packages or Python packages. The Anthropic-maintained ones live in the @modelcontextprotocol npm scope.
// NOTE

If you're on Windows and encounter path errors with MCP servers, the most common fix is using WSL2 rather than native Windows paths. The MCP server process spawner has historically had issues with Windows path separators in certain server implementations.

Шаг-by-step: installing your first MCP server

We'll use the GitHub MCP server as the example. It's maintained by Anthropic, well-documented, and immediately useful for most developers.

01

Install the server package globally

The GitHub MCP server requires a personal access token. First, install the package:

npm install -g @modelcontextprotocol/server-github

Verify the install by running mcp-server-github --version. If you see a version number, the binary is in your PATH.

02

Create or edit your MCP config file

Claude Code reads MCP server configuration from ~/.claude/claude_desktop_config.json (global, applies to all projects) or .claude/claude_desktop_config.json inside your project directory (project-scoped).

Create the file if it doesn't exist:

{
  "mcpServers": {
    "github": {
      "command": "mcp-server-github",
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    }
  }
}

Replace ghp_your_token_here with a GitHub PAT that has repo and read:org scope. Generate one at github.com/settings/tokens.

03

Restart Claude Code

Claude Code loads the MCP config at startup. If Claude Code is already running, you need to quit and relaunch. In a terminal session, press Ctrl+C to exit and then claude to restart.

There's no hot-reload for MCP server config. This is the most common mistake beginners make—editing the config while Claude Code is running and wondering why nothing changed.

04

Verify the server is connected

Inside a Claude Code session, run the slash command:

/mcp

You should see output listing github under "Connected servers" with a list of available tools like list_repositories, search_code, create_issue, and others. If the server isn't listed, jump to the troubleshooting section below.

05

Test a tool call

Ask Claude to use the server:

> List the open issues in the anthropics/claude-code repository

Claude will call the list_issues tool, retrieve the data from GitHub, and return it in the session. If you see a real list of issues, the server is working.

Adding a second server: Filesystem

The filesystem server gives Claude Code access to files outside your current working directory. It's scoped to specific paths you configure—Claude can't read /etc/passwd unless you've added /etc to the allowed paths.

Add it to the same config file:

{
  "mcpServers": {
    "github": {
      "command": "mcp-server-github",
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    },
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/Projects",
        "/Users/yourname/Documents"
      ]
    }
  }
}

The paths after the package name are the allowed directories. Add as many as you need. Restart Claude Code and run /mcp again to confirm both servers appear.

Five servers worth installing in your first week

The Anthropic-maintained registry has 20+ servers. These five cover the use cases that come up most often for developers:

  1. @modelcontextprotocol/server-github — issues, PRs, code search, file reading from repos. Daily use.
  2. @modelcontextprotocol/server-filesystem — read/write files outside the CWD. Required for multi-project work.
  3. @modelcontextprotocol/server-memory — persistent key-value store Claude can write to across sessions. Useful for projects where you want Claude to "remember" decisions between runs.
  4. @modelcontextprotocol/server-fetch — HTTP fetch with optional browser-like rendering. Lets Claude read documentation URLs you paste in.
  5. @modelcontextprotocol/server-postgres (or server-sqlite) — read-only database access. Useful for debugging and writing queries against your actual schema.

Troubleshooting: the errors you'll actually see

ErrorWhat it meansFix
Server "github" failed to start The binary isn't in PATH, or the command is wrong. Run which mcp-server-github. If nothing returns, the global install failed. Try sudo npm install -g or add --prefix ~/.npm-global and update PATH.
Authentication failed Your PAT is invalid, expired, or missing the required scope. Generate a new token at github.com/settings/tokens with repo scope. Check that the token starts with ghp_ (fine-grained tokens may not work with all MCP servers).
Server not listed in /mcp Claude Code didn't pick up the config change. Confirm the config file path is exactly ~/.claude/claude_desktop_config.json. JSON must be valid—run it through a linter. Restart Claude Code completely.
Tool call returned empty result The server connected but the tool returned nothing. Check the server's stderr. In Claude Code, server logs appear in the session output with a [MCP] prefix. Usually a scoping issue (wrong repo name, no matching results).
EACCES permission denied The filesystem server is trying to read a path outside its allowed list. Add the path to the args list in your config. The filesystem server only reads paths you explicitly allow.

Project-scoped vs global MCP config

The global config at ~/.claude/claude_desktop_config.json applies to every Claude Code session. If you work on multiple projects and some need different servers (e.g., a Supabase server for one project, a PostgreSQL server for another), use project-scoped config files.

Create .claude/claude_desktop_config.json in your project root. Claude Code merges project config with global config, with project config taking precedence on conflicts. This means you can have GitHub and Filesystem globally, and add a project-specific database server only to the projects that need it.

// SECURITY NOTE

Project-scoped config files containing API keys or database connection strings will be committed to version control if you're not careful. Add .claude/claude_desktop_config.json to your .gitignore. Use environment variables for secrets, not hardcoded values in the config. See the credentials leak prevention post for the full pattern.

Writing your own MCP server

If you need a tool that doesn't exist in the registry, writing a minimal MCP server is about 60 lines of TypeScript. The pattern:

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: "0.1.0" },
  { capabilities: { tools: {} } }
);

server.setRequestHandler("tools/list", async () => ({
  tools: [{
    name: "my_tool",
    description: "Does the thing",
    inputSchema: {
      type: "object",
      properties: { query: { type: "string" } },
      required: ["query"]
    }
  }]
}));

server.setRequestHandler("tools/call", async (req) => {
  const { query } = req.params.arguments;
  // your logic here
  return { content: [{ type: "text", text: `Результат for: ${query}` }] };
});

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

Build this with tsc, point your config at the compiled JS file, and Claude Code will call my_tool the same way it calls any built-in tool. The MCP SDK handles all the protocol boilerplate.

What to do after your first server is working

Once you have one server running, the next step is understanding the security surface you've opened up. MCP servers run as subprocesses with the same system privileges as your Claude Code session. A malicious or compromised MCP server can read anything in your allowed paths and make outbound network calls. Read the MCP Server Vulnerability Checklist before you add servers to production workflows.

Septim Tether: session state that persists

If you're setting up MCP specifically to give Claude persistent memory across sessions, Septim Tether is a pre-built context-management toolkit for Claude Code workflows. It handles session state, cross-project context, and the CLAUDE.md patterns that keep long sessions on track. Pay once, без подписки.

Get Septim Tether — $19 →