My Learning MCP Server
# ๐ค My Learning MCP Server
A hands-on MCP (Model Context Protocol) server built with **TypeScript** to learn the three core MCP primitives: **Tools**, **Resources**, and **Prompts**.
---
## ๐ What is MCP?
The **Model Context Protocol** is an open standard by Anthropic that lets AI models (like Claude) connect to external data sources, APIs, and custom logic in a standardized way.
```mermaid
graph LR
subgraph Hosts["AI Hosts"]
A["Claude Desktop"]
B["MCP Inspector"]
C["Gemini LLM Client"]
end
subgraph Server["๐ข MCP Server โ this project"]
E["src/index.ts"]
subgraph T["๐ง Tools"]
F["calculator"]
G["get_weather"]
end
subgraph R["๐ Resources"]
H["notes://all ยท 1 ยท 2 ยท 3"]
end
subgraph P["๐ฌ Prompts"]
I["code-review ยท explain-concept"]
end
E --> F & G & H & I
end
A & B & C -->|"MCP Protocol / stdio"| E
classDef host fill:#3b82f6,stroke:#1d4ed8,color:#fff
classDef server fill:#22c55e,stroke:#15803d,color:#fff
classDef prim fill:#f0fdf4,stroke:#16a34a,color:#166534
class A,B,C host
class E server
class F,G,H,I prim
```
---
## ๐๏ธ Project Structure
```
my-mcp-server/
โโโ src/
โ โโโ index.ts โ Main MCP server entry point
โ โโโ client/
โ โ โโโ index.ts โ ๐ค Gemini LLM client
โ โโโ tools/
โ โ โโโ calculator.ts โ ๐ง Calculator tool
โ โ โโโ weather.ts โ ๐ง Weather lookup tool
โ โโโ resources/
โ โ โโโ notes.ts โ ๐ Notes resource
โ โโโ prompts/
โ โโโ templates.ts โ ๐ฌ Prompt templates
โโโ spec/
โ โโโ README.md โ Spec index
โ โโโ 01-architecture/ โ Server architecture design
โ โ โโโ why-mcp.md โ "N ร M" problem breakdown
โ โโโ 02-llm-client/ โ LLM client design
โโโ .env โ API keys (gitignored)
โโโ package.json
โโโ tsconfig.json
โโโ README.md
```
---
## ๐งฉ Core MCP Primitives
| Primitive | Purpose | Example |
|-----------|---------|---------|
| ๐ง **Tools** | Actions the AI can execute | Calculate math, fetch weather |
| ๐ **Resources** | Data the AI can read | Notes, files, DB records |
| ๐ฌ **Prompts** | Reusable message templates | Code review, explain concept |
---
## ๐ Getting Started
### 1. Install dependencies
```bash
npm install
```
### 2. Set up your API key (required for LLM client)
```bash
cp .env.example .env
```
Then open `.env` and add your Gemini API key:
```
GEMINI_API_KEY=your_key_here
```
> Get a free key at [aistudio.google.com/app/apikeys](https://aistudio.google.com/app/apikeys).
> See `spec/02-llm-client/design.md` for detailed setup steps.
>
> โ ๏ธ The MCP Inspector and server work without the key. Only `npm run client` needs it.
### 3. Run in dev mode (with hot reload)
```bash
npm run dev
```
### 4. Open the MCP Inspector (visual debugger in the browser)
```bash
npm run inspector
```
This opens a web UI where you can:
- Call tools interactively
- Browse and read resources
- Try out prompt templates
### 5. Run the Gemini LLM client (requires API key from step 2)
```bash
npm run client
```
Chat in plain English โ Gemini will automatically call tools as needed.
### 6. Build for production
```bash
npm run build
```
---
## ๐ง Tools
> Tools let the AI execute actions (like making an API call or calculating math).
**How to use:**
- **In MCP Inspector** (`npm run inspector`): Go to the **Tools** tab, select a tool, enter the JSON arguments, and click "Run Tool".
- **In Gemini Client** (`npm run client`): Ask natural language questions like *"What is 25 x 4?"* or *"What's the weather in Tokyo?"* Gemini will automatically call the tool for you.
### `calculator`
Perform basic arithmetic operations.
**Input:**
```json
{
"operation": "add" | "subtract" | "multiply" | "divide",
"a": number,
"b": number
}
```
**Example:** `{ "operation": "multiply", "a": 12, "b": 7 }` โ `12 multiply 7 = 84`
---
### `get_weather`
Get current weather for a city (uses mock data for learning).
**Input:**
```json
{
"city": "London",
"unit": "celsius" | "fahrenheit"
}
```
**Example response:**
```json
{
"city": "London",
"temperature": "12ยฐC",
"humidity": "80%",
"condition": "Cloudy",
"timestamp": "2025-01-01T10:00:00.000Z"
}
```
---
## ๐ Resources
> Resources provide read-only data (like a file or database) for the AI to read.
**How to use:**
- **In MCP Inspector** (`npm run inspector`): Go to the **Resources** tab and click "List Resources" to see all available notes. Click on a specific URI (like `notes://1`) and click "Read Resource" to see its contents.
- **In Gemini Client**: *(Coming soon - currently the client only supports Tools, not Resources).*
Resources are accessed via URI:
| URI | Description |
|-----|-------------|
| `notes://all` | Summary list of all notes |
| `notes://1` | Note #1: "What is MCP?" |
| `notes://2` | Note #2: "MCP Transport Types" |
| `notes://3` | Note #3: "Why use Zod for validation?" |
---
## ๐ฌ Prompts
> Prompts are reusable templates (like slash commands) that generate structured instructions for an LLM.
**How to use:**
- **In MCP Inspector** (`npm run inspector`): Go to the **Prompts** tab, select `code-review` or `explain-concept`, fill out the required arguments (e.g., `language: "TypeScript"`), and click "Get Prompt". It returns a highly detailed, ready-to-use prompt template.
- **In Claude Desktop**: These appear as slash commands. You type `/code-review` and it prompts you for the arguments.
### `code-review`
Generates a structured code review prompt.
| Argument | Required | Values |
|----------|----------|--------|
| `language` | โ
| TypeScript, Python, Go, etc. |
| `focus` | โ | `security` \| `performance` \| `readability` \| `all` |
### `explain-concept`
Explains a technical concept at a chosen level.
| Argument | Required | Values |
|----------|----------|--------|
| `concept` | โ
| e.g. "MCP Resources", "async/await" |
| `level` | โ | `beginner` \| `intermediate` \| `expert` |
---
## ๐ฅ๏ธ Connect to Claude Desktop
Add to your Claude Desktop config file:
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["/Users/YOUR_USERNAME/workspace/Personal/my-mcp-server/dist/index.js"]
}
}
}
```
Then run `npm run build` and restart Claude Desktop.
---
## ๐ Key Learnings
1. **stdio transport** โ the server communicates via stdin/stdout; always log to `stderr`
2. **Always validate inputs** โ use Zod's `safeParse` to catch bad data before it crashes your server
3. **Three primitives** โ Tools (do), Resources (read), Prompts (template)
4. **McpError** โ throw typed errors so the client receives structured error responses
5. **Capabilities** โ declare what your server supports in the Server constructor
---
## ๐ Further Reading
- [Official MCP Docs](https://modelcontextprotocol.io)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
TDQS
Scored across 2 tools
Calculator and get_weather are completely unrelated and clearly distinguishable. There is no possibility of confusion between arithmetic operations and weather retrieval.
The names use mixed conventions: 'calculator' is a noun while 'get_weather' follows a verb_noun pattern. Both are readable, but the naming style is not consistent across the set.
With only two tools, the server feels very thin, especially for a vaguely named 'Learning MCP Server.' The tools are also unrelated, making the small count feel arbitrary rather than focused.
The domain is unclear, so it is difficult to define full coverage. Calculator covers basic arithmetic but no advanced operations, and weather only returns current conditions without forecast or location management, leaving notable gaps.