notes-lite
by team-humaki
README.md
# MCP Server Starter Lite
A minimal, tested [Model Context Protocol](https://modelcontextprotocol.io) server in Python. It's built on the official [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) v2 and is small enough to read in two minutes. It is one stdio server with two typed tools over an in-memory notes list, plus tests that call it in-process and as a real subprocess.
```
src/mcp_server_lite/server.py the server: add_note, search_notes
tests/test_server.py in-process tests through the SDK's Client (fast)
tests/test_stdio.py launches the server as a subprocess, like a host does
```
## Quick start
Requires [uv](https://docs.astral.sh/uv/) and Python 3.10+.
```bash
git clone https://github.com/team-humaki/mcp-server-starter-lite
cd mcp-server-starter-lite
uv run pytest # 5 passed
uv run mcp-server-lite # starts on stdio and waits silently: that is correct (Ctrl+C to stop)
```
### Use it from Claude Code
```bash
claude mcp add notes-lite -- uv --directory /ABSOLUTE/PATH/TO/mcp-server-starter-lite run mcp-server-lite
claude mcp list # notes-lite: ... ✔ Connected
```
Then ask Claude to "save a note titled X". The tools appear as `mcp__notes-lite__add_note` and `mcp__notes-lite__search_notes`.
### Other hosts
Any MCP host that launches stdio servers can use the same command and args: `uv --directory /ABSOLUTE/PATH/TO/mcp-server-starter-lite run mcp-server-lite`. (Only Claude Code was tested; see below.)
## What it shows
- **Typed inputs.** `Annotated[..., Field(min_length=..., le=...)]` becomes the JSON Schema the model sees, and bad input comes back as a tool error instead of a crash.
- **Structured output.** Return a Pydantic model or a list of them and the client gets both text and `structured_content`.
- **Model-facing errors.** `ToolError("...")` reaches the model as `is_error: true`, so write it as an instruction.
- **stdio hygiene.** Log to stderr and never `print()`, because stdout is the protocol wire.
- **Testing without a host.** `async with Client(mcp) as client:` runs the real protocol in-process.
## Make it yours
1. Rename the server (`MCPServer("notes-lite")`) and the package.
2. Replace `NOTES` with your database or API client.
3. Replace the two tools. Keep the docstrings specific, because they're what the model reads to decide when to call a tool.
4. Update the tests, then `uv run pytest`.
## Tested
- `uv run pytest`: 5 passed on Python 3.13 and 3.10, with `mcp` 2.3.0 (pinned in `uv.lock`).
- **Claude Code 2.1.310** (Linux): `claude mcp add` (the command above) and `claude mcp list` showed it as `✔ Connected`. A session called `add_note` and got `{"id":1,"title":"Hello from Claude Code","body":""}` back. The model side was a scripted local API, not a real model.
- Not tested: Cursor, Claude Desktop, VS Code, macOS, Windows.
## What the full version adds
[**Python MCP Server Starter**](https://humaki.gumroad.com/l/python-mcp-server-starter) (paid, $12) adds:
- A full "notes" server showing every building block: resources and URI templates, prompts, a Pydantic model as tool input, tool annotations (read-only/destructive), `Context`, and error handling for each type.
- **Streamable HTTP with OAuth 2.1 bearer auth** as a resource server. It covers Protected Resource Metadata, 401/403 challenges, per-tool scopes, a JWT/JWKS verifier and DNS-rebinding protection, with a dev-key script for local testing.
- A **Dockerfile**, and config snippets for Claude Code, Cursor, Claude Desktop and VS Code.
- 32 tests: in-process, stdio subprocess, a real uvicorn HTTP server with auth, and the JWT verifier. Plus documented SDK and spec gaps and an upgrade guide.
## License
MIT. See [LICENSE](LICENSE).
TDQS
B3.4/5.0
Scored across 2 tools
Disambiguation5/5
The two tools serve clearly distinct purposes: one writes a note, the other queries existing notes. There is no overlap or risk of misselection.
Naming Consistency5/5
Both names follow a consistent verb_noun snake_case pattern (add_note, search_notes). The convention is predictable and readable.
Tool Count3/5
Two tools is thin for a notes server; creation and search alone leave little room for a full workflow. The count itself is not excessive, but it feels under-scoped.
Completeness2/5
The surface covers only create and search; there is no way to fetch a note by id, list all notes, update content, or delete a note. These significant gaps will block common agent tasks like editing or cleanup.
Maintenance
ActivityMaintained
ResponsivenessNo issues