eswat2-mcp

Implementation Plan

Personal MCP + REST server — Python + FastMCP + FastAPI + uvicorn, single process on port 9100.

stack

FastMCP
MCP protocol layer
FastAPI
REST + auto docs
uvicorn
ASGI · :9100
00

Stack & Architecture

Stack

Everything is Python — server, scripts, and tests. No Node.js runtime in the hot path.

  • FastMCP — MCP protocol layer (@mcp.resource, @mcp.tool)
  • FastAPI — REST endpoint layer + auto OpenAPI docs at /docs
  • uvicorn — ASGI server, single process
  • pytest + FastMCP Client + FastAPI TestClient — full test suite
Architecture — one process, one port

FastAPI at root, FastMCP mounted at /mcp. Port default 9100, configurable via MCP_PORT env var.

mcp = FastMCP("eswat2", instructions="…")
# resources + tools registered on mcp…

app = FastAPI(lifespan=…)
app.mount("/mcp", mcp.http_app())

@app.get("/health")      # liveness
@app.get("/list_namespaces")
@app.get("/list_uris")
@app.get("/resolve")      # ?uri=namespace://slug
01

Modules

Canonical source of truth: Markdown files in modules/<namespace>/. Each namespace compiles to kbs/<namespace>-kb.json via task build. The server reads only the compiled KB files at runtime. Always run task build before deploying.
profile/
Biography, identity, resume, programming + UI journeys, podcast Q&A — 7 source files
7 filesphase 0.5
projects/
Shipped platforms and tools — notable public work from GitHub Pages source
varies
research/
PoCs, explorations, hypothesis-driven experiments from spec and doc sources
varies
vault/
Personal knowledge base — linked, tagged reference material with relationship graph
varies
art/
Art collection — Syd Mead lithographs and related acquisitions
varies
gallery/
Screenshots and visual proofs — project output documentation
varies
specs/
YAML component specs — real examples like color-picker-v8, icon-gallery-005 that LLMs discover and use via the Vercel deployment
LLM-discoverableVercel exposed
URI format

All content addressed as namespace://slug — e.g. profile://biography, specs://color-picker-v8, art://syd-mead-running-six.

The server manifest at eswat2://manifest lists every available URI across all namespaces — an LLM's starting point.

02

MCP Layer — Resources & Tools

Resources — Claude Code

Claude Code natively supports list_resources / read_resource via MCP. Resources are registered dynamically — one @mcp.resource handler per namespace covering all namespace://slug URIs.

eswat2://manifest is a server-level resource listing all available URIs with descriptions — the LLM's entry point for discovery.

Access matrix
ClientInterfaceTransport
Claude Codenamespace:// resourcesHTTP
Claude Desktoplist_uris / read_uriHTTP
Browser / REST/resolve?uri=…HTTP
MCP Tools — Claude Desktop

Six @mcp.tool handlers for clients that don't support resources. All backed by the same kb.py loader.

list_namespaces()
All namespaces with entry counts
list_uris(namespace?)
All URIs, optionally scoped to one namespace
read_uri(uri)
Resolve any namespace://slug URI and return content
list_tags()
All tags across the KB with entry counts
search_by_tag(tag)
KB entries matching an exact tag
get_graph()
Full URI relationship graph — powers kb-graph.html
03

REST Endpoints

MethodPathDescription
GET/healthLiveness check
GET/manifestServer manifest — name, version, all namespaces
GET/list_namespacesAll namespaces with entry counts
GET/list_urisAll URIs with descriptions, optional ?namespace= filter
GET/resolve?uri=<uri>Resolve any namespace://slug URI and return content
GET/graphFull URI relationship graph (consumed by kb-graph.html)
/mcpMCP protocol endpoint (FastMCP) — all MCP clients connect here
/docsAuto-generated OpenAPI docs (FastAPI)
MCP Registration — Claude Code
claude mcp add eswat2 \
  --transport http \
  http://localhost:9100/mcp
MCP Registration — Claude Desktop
{
  "mcpServers": {
    "eswat2": {
      "type": "url",
      "url": "http://localhost:9100/mcp"
    }
  }
}
04

Implementation Phases

0.5
Module Authoring
Writing task — no server code, no dependencies
Author the 7 canonical markdown files in modules/profile/ from _source reference material. Sources: podcast transcripts (biography, journeys), GitHub Pages (identity, projects, links), resume 2026 (career), spec + doc dirs (research).

Files: identity.md · biography.md · journey-programming.md · journey-ui.md · resume.md · projects.md · research.md
no code writing only 7 files modules/profile/
1
Foundation
Working Python package — correct structure, nothing runs yet
pyproject.toml — package definition, dependencies, dev extras, pytest config.
src/kb.py — KB loading logic: loads all kbs/*-kb.json at import time; exposes load_content(namespace, slug) → str and list_slugs(namespace) → list[str].
src/server.py — stub only, no endpoints yet.
modules/profile/ — seven placeholder markdown files.
pyproject.toml src/kb.py src/server.py stub
2
MCP Resources + Tools
MCP protocol working for Claude Code (resources) and Claude Desktop (tools)
Resources registered dynamically — one @mcp.resource handler per namespace covering all namespace://slug URIs. eswat2://manifest registered as a server-level resource.

Six @mcp.tool handlers provide equivalent access for clients that don't support resources. Both interfaces backed by the same kb.py loader. FastMCP server instructions describe the purpose so an LLM knows what it's connected to.
@mcp.resource ×7 @mcp.tool ×6 eswat2://manifest
3
REST API
HTTP endpoints in full parity with MCP resources — same process, same port
FastAPI handles /health, /manifest, /list_namespaces, /list_uris, /resolve, /graph. FastMCP mounted at /mcp. FastAPI auto-docs at /docs.

Phases 2 and 3 share server.py and can be completed in a single session.
/health /list_namespaces /list_uris /resolve /graph /docs
4
Tests
Automated coverage across content, MCP resources, MCP tools, and REST
tests/test_content.py — unit tests for kb.py, no server needed.
tests/test_resources.py — MCP resource tests via FastMCP Client.
tests/test_tools.py — MCP tool tests (list_uris, read_uri, etc.) via FastMCP Client.
tests/test_rest.py — REST endpoint tests via FastAPI TestClient.
test_content.py test_resources.py test_tools.py test_rest.py
5
Operational Readiness
Easy to run, register with clients, and maintain
start.sh / stop.sh — launch and kill the server by port.
README.md — setup, run instructions, MCP registration for Claude Code + Claude Desktop, REST reference, module editing guide.
CLAUDE.md updated with run/test commands, port, and endpoints.
start.sh stop.sh README.md CLAUDE.md
6
Vercel Deployment
Public-facing MCP + REST on Vercel with X-API-Key auth on all routes
Two-deployment model: Local (localhost:9100) — full access, no auth. Vercel — all namespaces, X-API-Key required on every route. Simpler than a public/private slug split; avoids classifying every new entry.

api/index.py is a separate server definition that imports the same kb.py but registers a narrower tool surface. No content duplication. MCP endpoint becomes https://<project>.vercel.app/mcp. Register as eswat2-public to distinguish from the local registration.

Requires Phase 5 — local ops must work before deploying.
api/index.py vercel.json requirements.txt X-API-Key eswat2-public
05

Final File Structure

eswat2-mcp/ ├── modules/ ← canonical markdown source │ ├── art/ gallery/ profile/ │ ├── projects/ research/ │ └── specs/ vault/ ├── kbs/ │ └── *-kb.json ← compiled via task build ├── src/ │ ├── kb.py ← KB loader — loads all kbs/ at import time │ └── server.py ← FastAPI + FastMCP app (full local server) ├── api/ │ └── index.py ← Vercel serverless entry point (public surface) ├── public/ │ ├── fonts/ ← self-hosted woff2 subsets │ ├── wiki.html kb-graph.html 3d-graph.html │ └── plan.html ← this file ├── assets/ │ └── gallery/ ← thumbnails served at /gallery ├── scripts/ │ ├── build_all.py build_kb.py │ └── build_thumbs.py subset-fonts.sh ├── tests/ │ ├── test_content.py ← kb.py unit tests (no server) │ ├── test_resources.py ← MCP resource tests via FastMCP Client │ ├── test_tools.py ← MCP tool tests via FastMCP Client │ └── test_rest.py ← REST endpoint tests via FastAPI TestClient ├── AGENTS.md CLAUDE.md PLAN.md README.md ├── pyproject.toml requirements.txt config.yaml ├── start.sh stop.sh └── vercel.json
06

Phase Dependencies

Phase 0.5
Module Authoring
Phase 1
Foundation
Phase 2
MCP Layer
Phase 3
REST API
Phase 4
Tests
Phase 5
Ops
Phase 6
Vercel
Phases 2 + 3 share server.py and can be completed in a single session — no need to split them.
Phase 6 requires Phase 5 — local ops must be working before deploying to Vercel.