mcp-lab
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-labrun the guided walkthrough on tools"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-lab
Learn the Model Context Protocol by reading a working server, then watching the protocol happen in your browser.
MCP's problem as a learning subject is that it's invisible: things work, and you never see why. This repository fixes that from two directions.
A teaching server built on the official Python SDK (
mcp1.x, FastMCP) — every MCP primitive exactly once, heavily commented, meant to be read. The domain is a notes store, chosen because tools, resources, and prompts each have an obvious distinct role in it.A local dashboard that connects to real MCP servers as a real client, runs guided lessons against them, and shows you the actual JSON-RPC frames in transit — not a reconstruction.
The comments are the product. This is a repository to read, not a library to
depend on. If you only open one file, opensrc/notes_server/server.py.
Quick start
Needs uv and Python 3.13. Docker is optional — you only need it for the Postgres server.
git clone https://github.com/nikhilpatil79/mcp.git
cd mcp
uv sync --group dev
uv run pytest -q # all green, no Docker or network neededThen generate your local credentials (this writes .env with fresh random
passwords on first run):
./scripts/setup-env.sh # macOS / Linux.\scripts\setup-env.ps1 # WindowsAnd start it:
docker compose up -d --wait # 1. Postgres
uv run mcp-lab-ui # 2. dashboard + UI → http://127.0.0.1:8765Or one command: ./scripts/start-ui.sh (.\scripts\start-ui.ps1 on Windows).
It's an ordinary local web app — no Claude account, no login, no browser
extension. Any browser opens it. There is no separate backend: mcp-lab-ui
serves the API and the page, and launches the MCP servers as child processes.
Full walkthrough, how to verify each layer, and what to do when something
breaks: docs/RUNNING.md.
Related MCP server: MCP-PIF Server
The dashboard
/ — guided walkthroughs (start here)
Four short lessons. Each runs real calls against the servers on your machine and narrates what happened in plain English, one step at a time:
What is a tool? — Claude discovers what a server offers, then uses one
Tools vs resources vs prompts — the one distinction that matters: who decides to use it
What happens when something goes wrong — why a failed tool isn't a crash
Talking to a real database — a real SQL query, then a refused
DELETE
Every step shows the plain-English explanation first, the result second, and the raw JSON-RPC messages last — behind a "show the actual messages" toggle. That ordering is deliberate: a protocol log only teaches you something once you already know what you're looking at.
Lesson 4 surfaces something genuinely worth knowing — servers don't agree on
how to report a refusal. The notes server raises, so the protocol's isError
flag gets set. postgres-mcp returns a normal result with an error message in
the text. The UI labels each case distinctly rather than flattening them.
/pipeline — what CI/CD runs, and where Claude sits in it
The four CI stages, each with a run it now button that executes the local equivalent so you can watch it pass or fail — then the two Claude Code jobs, side by side, showing what each one does and what it cannot do.
The flags, triggers and permissions on that page are parsed out of
.github/workflows/*.yml when you load it, so the page can't drift from the
YAML. The commentary is hand-written, because parsing never produces an
explanation.
/wire — the raw protocol dashboard
For once you know what you're looking at: every capability across all servers, an inspector to invoke anything, and a live JSON-RPC frame log.
The wire log is not a reconstruction. hub.py::_tap
inserts a pair of memory streams between stdio_client and ClientSession and
pumps messages across, logging each SessionMessage in transit — so you read
the literal frame:
{ "method": "tools/call",
"params": { "name": "search_notes", "arguments": { "query": "mcp" } },
"jsonrpc": "2.0", "id": 7 }The dashboard is unauthenticated and can invokeevery tool on every
connected server, including the Docker write tools. It binds to 127.0.0.1
deliberately — don't put it on a network interface. The
.claude/settings.json allowlist governs Claude Code, not this UI. See
SECURITY.md.
The connected servers
Server | What | Access |
| The teaching server in | Read-write (local file) |
| Postgres MCP Pro → local | Read-only, two enforced layers |
| Official GitHub server | Read-only, needs a PAT |
|
| Read + write ⚠️ |
The GitHub server is optional — leave the token unset and it reports as
skipped rather than failing. Full setup, security model, and troubleshooting:
docs/SERVERS.md.
docker compose up -d --wait # start Postgres
./scripts/setup-env.sh # or .\scripts\setup-env.ps1
uv run python scripts/drive_servers.py # smoke-test all four
# then FULLY restart Claude Code, and check /mcpdrive_servers.py connects to each server as a real MCP client and exercises
it, so you get the actual error instead of /mcp's connected/failed. It's also
wrapped as a project skill (.claude/skills/run-mcp-servers/) — just ask Claude
to run the MCP servers.
Permissions
.claude/settings.json pre-approves the read-only tools (all 9 Postgres, the 5
Docker list_*/fetch_*) and forces a prompt on the 14 Docker write tools and
delete_note. The Docker server has no read-only mode, so this allowlist is
the control — see docs/SERVERS.md.
Use it from Claude Code
.mcp.json is already wired up. Open this project in Claude Code, approve the
servers when prompted, then:
> what MCP tools do you have available?
> save a note titled "MCP basics" saying MCP is JSON-RPC with agreed nouns, tag it mcp
> what have I written about mcp?Check connection status any time with /mcp.
Poke at it in the Inspector
The fastest way to build intuition — a web UI that speaks the protocol, so you can list tools, call them, and read resources by hand:
uv run mcp dev src/notes_server/server.pyWhat's in the server
Tools (model-controlled — Claude decides to call these)
add_note— the minimal case; shows how docstring and type hints become the schemasearch_notes— structured output via a pydantic model, plusreadOnlyHintdelete_note— destructive annotations, and raising to signal failureretag_notes—Contextinjection for progress reporting and logging
Resources (application-controlled — the app loads these into context)
notes://stats— a static resourcenotes://note/{note_id}— a resource template: one declaration, many URIs
Prompts (user-controlled — surface as slash commands)
summarise_tag— the simple single-string formweekly_review— multi-message scaffolding
Subagents
Two, in .claude/agents/:
mcp-explainer— answers MCP concept questions from this repo's own code and docs. Read-only tools; grounded answers withfile:linecitations.notes-librarian— operates the notes store through the MCP server. Its allowlist includes search/add/retag but deliberately excludesdelete_note— destructive operations stay with the main agent where you can confirm them.
That exclusion is the point worth noticing: MCP tool annotations
(destructiveHint) are an advisory hint to the client, while a subagent's
tools: allowlist is actual enforcement. docs/CONCEPTS.md § Part 2 covers the
distinction.
CI/CD
.github/workflows/ holds a working pipeline, written to be read:
Workflow | Runs when | Does |
| every push and PR | lint → protocol tests (Ubuntu + Windows) → live MCP servers against real Postgres → build |
| nightly | boots the whole stack, runs every dashboard lesson, checks each behaved as advertised |
| you push a | re-verifies the tag, publishes the wheel, pushes the Postgres image to GHCR |
| someone types | Claude Code as a job, interactive mode |
| a PR opens | Claude Code as a job, automation mode, read-only |
The integration job asserts the read-only Postgres boundary with a grep — a
security control nobody tests is one you're only hoping about.
docs/CICD.md explains all of it: the CI/CD split, how to
test an MCP server properly, the three kinds of credential in a pipeline, and
what changes about Claude Code's permission model when there's no human to
approve a tool call.
What to read, in order
File | What it teaches |
Start here. All three primitives, one numbered section each, with the reasoning inline | |
The prose companion — architecture, message flow, primitive selection, and subagents | |
The pipeline — CI/CD concepts, testing MCP servers, and running Claude Code as a job | |
The same server seen from the client side — what the model actually receives | |
How to be an MCP client, and how to tap the wire | |
Plain storage, no MCP. Separate on purpose: an MCP server is a thin wrapper over capabilities you already have |
Layout
src/notes_server/
server.py ← the annotated reference implementation
store.py ← plain JSON-backed storage, no MCP
__main__.py ← `python -m notes_server`
src/mcp_lab_ui/
app.py ← Starlette routes; thin adapters over Hub
hub.py ← one live MCP session per server, and the wire tap
lessons.py ← the guided lessons, and how a refusal is classified
pipeline.py ← parses .github/workflows/ so the page can't drift
static/ ← learn.html, index.html, pipeline.html
tests/ ← protocol tests, store, hub, pipeline and route tests
docs/
CONCEPTS.md ← MCP concepts + subagents, explained
SERVERS.md ← the four connected servers, setup and security model
RUNNING.md ← starting and stopping it by hand
CICD.md ← the pipeline, and Claude Code running as a job
infra/postgres/init/
01-schema.sql ← seeded demo database
02-readonly-role.sql ← the mcp_ro role the Postgres server logs in as
scripts/
setup-env.{ps1,sh} ← generate .env, sync secrets into the environment
start-ui.{ps1,sh} ← Postgres + dashboard in one command
drive_servers.py ← smoke-test every server in .mcp.json as a real client
check_dashboard.py ← run every lesson, assert each behaved as advertised
.github/
dependabot.yml ← grouped weekly updates for actions and dependencies
workflows/ ← ci, nightly e2e, release, and two Claude Code jobs
ISSUE_TEMPLATE/ ← bug report and unclear-explanation forms
.claude/
settings.json ← permission allowlist (read vs write tools)
agents/ ← mcp-explainer, notes-librarian
skills/run-mcp-servers/SKILL.md ← how to run and debug the servers
CLAUDE.md ← guidance for Claude Code working in this repo
docker-compose.yml ← local Postgres
.mcp.json ← registers all four servers with Claude Code
.env.example ← credential template; .env itself is gitignoredNotes persist to notes.json at the project root; override with the
NOTES_DB_PATH environment variable.
Contributing
See CONTRIBUTING.md. The review bar has one unusual item on
it: because the comments are the product, a change that improves the code but
degrades the explanation is a regression.
License
MIT.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityFmaintenanceA Model Context Protocol (MCP) server that provides JSON-RPC functionality through OpenRPC.Last updated26743Apache 2.0
- Flicense-qualityFmaintenanceThis server implements the Model Context Protocol to facilitate meaningful interaction and understanding development between humans and AI through structured tools and progressive interaction patterns.Last updated57
- Flicense-qualityDmaintenanceA demonstration implementation of the Model Context Protocol server that facilitates communication between AI models and external tools while maintaining context awareness.Last updated
- Flicense-qualityDmaintenanceAn educational repository designed to practice and understand the Model Context Protocol through simple server implementations. It demonstrates core MCP concepts such as tools, resources, and communication via stdio and SSE transport methods.Last updated
Related MCP Connectors
A Model Context Protocol server for Wix AI tools
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
MCP Spec Compliance MCP — audits any MCP server.json against the official Model Context Protocol
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nikhilpatil79/mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server