Skip to main content
Glama
modernvibecoding

starter-mcp-server

README.md
# starter-mcp-server

> **Course:** MCP & Tool Ecosystems
> **Path:** Agentic Coding Path · Position 11

A Gold Standard MCP server scaffold. Three working primitives (tools, resources, prompts)
wired to Claude Desktop in under 5 minutes. Extend it with your own tools using the
patterns in `agent.spec.md`.

---

## What Is MCP?

The **Model Context Protocol** is an open standard that lets Claude (and other AI models)
call code you write — fetching data, running calculations, querying databases — without
leaving the conversation.

```
You → Claude → calls your tool → tool runs → result back to Claude → Claude answers you
```

This server implements MCP over **stdio**, which means Claude Desktop spawns it as a
child process and communicates via stdin/stdout. No HTTP, no ports, no hosting needed.

---

## Quick Start

### 1. Install and build

```bash
npm install
npm run build
```

### 2. Find your absolute path

```bash
pwd
# → /Users/yourname/projects/starter-mcp-server
```

### 3. Configure Claude Desktop

Open (or create) your Claude Desktop config file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

Add the `mcpServers` block (replace the path with your real path from step 2):

```json
{
  "mcpServers": {
    "starter-mcp-server": {
      "command": "node",
      "args": ["/Users/yourname/projects/starter-mcp-server/dist/index.js"]
    }
  }
}
```

See `claude_desktop_config.json.example` for a full example with environment variables.

### 4. Restart Claude Desktop

Fully quit and reopen Claude Desktop. Look for the **🔨 hammer icon** near the chat input.
Click it — you should see `starter-mcp-server` listed with three tools.

### 5. Test it

Try asking Claude:

> *"Use the calculate_sum tool to add 847 and 293."*

> *"Read the system://info resource and tell me how much free memory this machine has."*

---

## What's Included

### Tools (Claude can call these)

| Tool | What it does |
|---|---|
| `calculate_sum` | Adds two numbers: `a + b` |
| `calculate_percentage` | `part` is X% of `whole` |
| `calculate_compound_interest` | Final balance after compounding |

### Resources (Claude can read these)

| URI | What it returns |
|---|---|
| `system://info` | Platform, Node version, memory, uptime (JSON) |
| `system://env` | Variables prefixed with `SAFE_` from your `.env` (JSON) |

### Prompts (appear in Claude's "/" menu)

| Prompt | What it does |
|---|---|
| `/explain_tool` | Ask Claude to explain any tool by name |

---

## Development Workflow

**Test without Claude Desktop** (uses the MCP Inspector UI):

```bash
npm run inspect
```

**Watch mode** (auto-restarts on file changes):

```bash
npm run dev
```

After editing source files, run `npm run build` before testing with Claude Desktop.
Claude Desktop caches the built output — it reads from `dist/`, not `src/`.

---

## Adding Your First Tool

1. Create `src/tools/weather.ts` — follow the exact pattern in `src/tools/math.ts`
2. Export `weatherTools: Tool[]` and `handleWeatherTool(name, args): string | null`
3. In `src/index.ts`, add two lines (marked with `// ADD NEW ...` comments)
4. Run `npm run build`
5. Restart Claude Desktop

The `agent.spec.md` file contains a copy-paste prompt you can give to Claude Code
to build a complete new tool for you.

---

## File Structure

```
src/
  index.ts              ← server setup + request routing
  tools/
    math.ts             ← 3 math tools (the pattern to copy)
  resources/
    system.ts           ← 2 system info resources
  prompts/
    index.ts            ← 1 sample prompt
dist/                   ← compiled JS (generated by npm run build)
claude_desktop_config.json.example
.env.example
agent.spec.md           ← AI prompt to extend this server
```

---

## Critical Rule: Never Use `console.log`

`stdout` is reserved for the MCP JSON-RPC protocol. Any `console.log()` call will corrupt
the stream and break Claude Desktop's connection to this server.

**Always use `console.error()`** for debug output. It writes to stderr, which is safe.

```typescript
// ✅ Safe — writes to stderr
console.error("debug:", someValue);

// ❌ Breaks the server — writes to stdout
console.log("debug:", someValue);
```