Skip to main content
Glama
README.md
# project-notes: an MCP server of your own

The complete code from the Code Craft Studio video **"How to Build an MCP Server of Your Own"**.
Video: (link goes here)

A personal MCP server over a folder of markdown notes. It exposes the three MCP primitives:

| Primitive | What you get | Where |
|-----------|--------------|-------|
| Tool | `search_notes(query)` and `list_notes()` | `@mcp.tool()` in `server.py` |
| Resource | any note, readable at `notes://<name>` | `@mcp.resource("notes://{name}")` |
| Prompt | `weekly_summary` template | `@mcp.prompt()` |

## Quickstart (under 5 minutes)

Requires Python 3.10+ and [uv](https://docs.astral.sh/uv/).

```bash
git clone <this repo> && cd mcp-notes
uv sync
```

Test it with the MCP Inspector before touching any client:

```bash
npx @modelcontextprotocol/inspector uv run server.py
```

The Inspector lists both tools. Call `search_notes` with `auth` and you should see hits from `auth-decision.md`.

## Wire it into Claude Code

```bash
# just you, this project (default: local scope)
claude mcp add notes -- uv run server.py

# every project you own
claude mcp add notes --scope user -- uv run server.py

# your whole team, via git
claude mcp add notes --scope project -- uv run server.py
```

Project scope writes `.mcp.json` (one is already included here). Commit it: teammates who clone this repo and open Claude Code get a one-time approval prompt, then they are connected too.

Check the connection inside Claude Code with `/mcp`, then ask: "What did we decide about auth?"

## Go remote

Stdio runs on your machine with no port and no hosting. To serve a team from one box:

```bash
uv run server.py --http
```

That switches the transport to streamable HTTP. Once it is on a network, treat it as production: TLS in front, OAuth for authentication (both supported by the protocol), and read `SECURITY-CHECKLIST.md` first.

## The gotcha to remember

On stdio, **stdout is the protocol channel**. One stray `print()` corrupts the JSON stream and the client reports "connection failed". This server logs to stderr; keep it that way.

## Files

```
server.py               the whole server, ~90 lines
notes/                  sample notes (replace with your own)
.mcp.json               project-scope config, committed for the team
pyproject.toml          pinned dependency (see checklist item 3)
SECURITY-CHECKLIST.md   harden it from day one
```

## License

MIT. Use it, fork it, ship it.