MCP-Demo
by SiNBooty
README.md
# mcp-demo
A minimal Python MCP server, built in phases so each commit teaches one concept.
End state: Claude Code can call local Ollama models (gemma3:4b / 3:12b) as a tool,
routing low-stakes work off the API and onto the homelab.
## What is MCP, really?
**Model Context Protocol** is a standardized JSON-RPC 2.0 protocol that lets an
LLM client (Claude Code, Claude Desktop, Cursor) discover and invoke tools,
fetch resources, and load prompt templates from separate processes called
**MCP servers**. MCP is to LLM tooling what LSP is to IDE language support:
one protocol, many interoperable implementations.
### The moving pieces
```
┌───────────────────┐ stdio / HTTP ┌──────────────────┐
│ MCP Client │ ◄──JSON-RPC──► │ MCP Server │
│ (Claude Code) │ │ (this repo) │
└───────────────────┘ └──────────────────┘
│ │
│ spawns as child │ hits
│ process (stdio) │ localhost:11434
▼ ▼
your shell env Ollama / gemma3
```
- **Client** — embedded in the LLM app
- **Server** — any process that speaks MCP
- **Transport** — `stdio` (client spawns server as child, pipes JSON-RPC) or
`streamable-http` (server is a web service). This repo uses stdio.
### Three primitives an MCP server exposes
| Primitive | What it is | This repo's use |
|-----------|--------------------------------------|----------------------------------------|
| Tools | Functions the LLM can call | `echo`, `ollama_ask` |
| Resources | Read-only blobs the client can fetch | `ollama://models` (list pulled models) |
| Prompts | Pre-canned prompt templates | (not used — kept minimal) |
## Phase progression
Each phase is one commit — `git log` shows the evolution.
1. ✅ **scaffold** — pyproject, README, .gitignore.
2. ✅ **hello-world server** — one `echo` tool + smoke-test client.
Proves the full lifecycle: client spawn → handshake → tool discovery → tool call.
3. ✅ **ollama_ask tool** — async tool that POSTs to `localhost:11434/api/generate`
and returns Gemma's reply.
4. ✅ **polish** — adds `system` parameter to `ollama_ask` and exposes a
resource at `ollama://models` (list of pulled models).
## Install & run
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
# Phase 2+ only: run the server by hand to smoke-test
python -m mcp_demo.server
```
The server reads JSON-RPC off stdin and writes to stdout — if you run it
directly in a terminal it will just sit there waiting for input. That's
expected. The client (Claude Code) is what actually feeds it.
## Registering with Claude Code
Add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"mcp-demo": {
"command": "/home/booty/mcp-demo/.venv/bin/python",
"args": ["-m", "mcp_demo.server"]
}
}
}
```
Restart Claude Code. Tools appear as `mcp__mcp-demo__<tool_name>`.
## Further reading
- Spec: https://modelcontextprotocol.io/specification
- Python SDK: https://github.com/modelcontextprotocol/python-sdk
- Inspector (a debug UI for poking at any MCP server): `npx @modelcontextprotocol/inspector`
This server cannot be deployed