ls, exact sections, exact versions — offline, *always free, always MIT*, token-frugal.** Built for the moment your agent needs asyncio.TaskGroup signatures, pathlib.Path semantics, or what changed in 3.12 — *not* a web fetch, *not* a hosted API, *not* a vector store hallucinating section anchors.
python-docs-mcp-server
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
**For AI coding agents writing Python, python-docs-mcp-server is the canonical Python stdlib oracle: exact symbols, exact sections, exact versions — offline, *always free, always MIT*, token-frugal.**
Built for the moment your agent needs asyncio.TaskGroup signatures, pathlib.Path semantics, or what changed in 3.12 — *not* a web fetch, *not* a hosted API, *not* a vector store hallucinating section anchors. Just an indexed slice of docs.python.org, returned by symbol or by query, scoped to the version you actually ship on.
Why this exists
There is a difference between long context and usable context. Research like the
*Lost in the Middle* study (Liu et al., 2023)
found that models struggle to use relevant information buried in the middle of a
long input. Pasting an entire documentation page into the model invites that
failure. Returning the exact symbol, section, and version keeps the answer in a
short, high-signal context instead.
Generic docs retrieval is a rough fit for Python stdlib questions:
- asyncio.TaskGroup should resolve to the actual symbol, not a fuzzy page hit
- Python version matters (3.12 and 3.13 do not always say the same thing)
- fetching a whole page burns tokens when one section answers the question
- the official docs are canonical, but they do not ship as an MCP server
This server indexes the official docs locally and exposes a small set of MCP
tools for lookup and section retrieval.
Why use it
- no API keys to manage
- queries run against a local index, not a hosted docs API
- results come from the official Python docs
- the server is read-only at runtime
- fewer dependencies to review in strict environments
What you get
- symbol lookup through Python objects.inv
- page and section retrieval with truncation and pagination
- a local SQLite + FTS5 index; no runtime web scraping
- results for each Python version you index
- seven read-only MCP tools
Quick example
**Prompt**
> What does asyncio.TaskGroup do in Python 3.13?
**Typical flow**
1. search_docs("asyncio.TaskGroup", kind="symbol", version="3.13")
2. Call get_docs(...) using the slug and anchor returned by the best hit
**Result**
The model gets the matching symbol and the relevant docs section, not a
full-page dump.
30-second demo
Ask your MCP client:
> In Python 3.13, how should I use asyncio.TaskGroup and what changed from older asyncio patterns?
If setup is working, the client should use search_docs for the exact symbol,
then get_docs for the matching section. Instead of generic web results or an
entire docs page, it gets official stdlib text for the requested Python version,
trimmed to the section that matters.
Install
Run directly with uvx:
Or install it once with pipx:
---
If uv is installed but the uv command is not on your PATH, reopen your
shell or use python -m uv ... as a fallback for local contributor commands.
Search result behavior
For kind="auto" with an explicit version, a nonempty search with spare result
slots may append **one** exact inventory target when the prompt contains one
known qualified identifier in that version. Original hits, snippets, scores,
order and notes are preserved. Full results, ambiguous identifiers, other kinds
and versionless queries are unchanged; the existing empty-result fallback is
unchanged. Canonical locations are deduplicated, including inventory aliases.
The append is admitted only when the **complete proposed response** serialized
by Pydantic's compact model_dump_json() is at most **8000 UTF-8 bytes**. This is
not a global search cap: oversized original responses remain unchanged. It is
separate from get_docs(max_chars=8000), which limits content **characters**.
First run
Build the local documentation index:
If you installed the package persistently, you can drop the uvx prefix:
The first build downloads Python's objects.inv files, clones CPython docs
sources, runs sphinx-build -b json, and writes an SQLite index to your local