DPC Zettelkasten MCP server
Commit Nov 12, 2026Allows an AI client to query a knowledge graph and access commit-pinned citations for claims about Minecraft plugin functionality.
Also known as Dans-Plugins/dpc-mcp-server
- Stars
- 0
- Tools
- 6
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 12, 2026
- License
- MIT
What is DPC Zettelkasten MCP?
DPC Zettelkasten allows an AI client to query a knowledge graph and access commit-pinned citations for claims about Minecraft plugin functionality. It exposes 6 tools, such as search_notes, get_note, list_maps.
Summary generated from the project's README
About DPC Zettelkasten MCP server
Querying technical documentation for Minecraft plugins with verifiable citations is what this server enables. It provides an AI client with direct access to the Dan's Plugins Community knowledge base, allowing for structural queries and precise information retrieval. Users can interact with the data through a local stdio connection or via a remote Streamable HTTP transport, making it suitable for both desktop applications and containerized environments.
The server includes specialized tools such as search_notes for full-text discovery, get_note for retrieving Markdown content with backlinks, and graphql for complex structural questions. A standout feature is the ability to provide commit-pinned citations, which include GitHub permalinks tied to specific commit SHAs. This ensures that every claim made by the AI can be manually verified against the source code. Because the data is vendored directly into the server, it operates without external network dependencies at runtime, serving a consistent and immutable snapshot of the knowledge graph.
What you can do with it
- 1Verify plugin functionality claimsAsk the AI how a specific faction power works and receive a response backed by a GitHub permalink to a specific commit.
- 2Deploy in isolated environmentsRun the server inside a Docker container using HTTP transport for clients on different machines.
Written from the project's README. Every use case is checked against a quote from it.
DPC Zettelkasten MCP tools 6
Detected from the READMEsearch_notesget_notelist_mapsget_citationsgraphqlget_schema
| search_notes | — | |
| get_note | — | |
| list_maps | — | |
| get_citations | — | |
| graphql | — | |
| get_schema | — |
Automated checks
Ran Nov 15, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachabledans-plugins/dpc-mcp-server is public and reachablegithub.com/dans-plugins/dpc-mcp-server ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-11-12github.com/dans-plugins/dpc-mcp-server ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model6 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubDPC MCP Server
An MCP server for the DPC Zettelkasten — the knowledge base describing how the Dan's Plugins Community Minecraft plugins work.
It gives a model two things it does not otherwise have: structural queries over the collection, and the citation behind every claim. Ask it how faction power works and the answer comes back with a GitHub permalink pinned to a commit SHA, so the claim can be checked rather than trusted.
Install
Requires Node 18 or later. No runtime dependencies.
git clone https://github.com/Dans-Plugins/dpc-mcp-server.git
cd dpc-mcp-server
npm run sync # optional — a snapshot is already committed
There is nothing to build. node src/server.js is the whole thing.
Claude Code
claude mcp add dpc -- node /absolute/path/to/dpc-mcp-server/src/server.js
Claude Desktop, or any client using mcpServers
{
"mcpServers": {
"dpc": {
"command": "node",
"args": ["/absolute/path/to/dpc-mcp-server/src/server.js"]
}
}
}
Over HTTP
The same server also speaks MCP's Streamable HTTP transport, for the cases where a subprocess is not an option — a container, or a client on another machine:
node src/server.js --http --port 8080 # POST /mcp, health at /healthz
It binds 127.0.0.1 unless --host says otherwise, and it has no
authentication of its own, so it is a local and private-network transport
until it grows one. stdio remains the default and the right choice for a local
client.
claude mcp add --transport http dpc http://127.0.0.1:8080/mcp
In a container
The Dockerfile builds the HTTP transport into an image. There is no
npm install in it and no node_modules in the result — copying package.json,
src/, and vendor/ is the whole build, which is what having no runtime
dependencies buys. It runs as the base image's node user, binds 0.0.0.0
inside the container because nothing outside the network namespace could
otherwise reach it, and carries a HEALTHCHECK that probes /healthz with
node rather than assuming a slim image ships curl.
docker build -t dpc-mcp-server .
docker run -d -p 8080:8080 --name dpc dpc-mcp-server
curl -s http://127.0.0.1:8080/healthz
docker stop dpc
docker stop returns as soon as the server exits, because the server handles
SIGTERM: it stops accepting, finishes what is in flight, and leaves — rather
than ignoring the signal and being killed ten seconds later.
The image binds a public interface inside the container and still has no authentication of its own, so publish it behind something that does — the gateway, or anything else that terminates auth in front of it.
A container does not refresh itself. The image bakes in
vendor/dataset.json, so it serves whatever commit of the collection was
vendored when the image was built — deliberately, since that is how the server
already works and it keeps the container from depending on the network at boot.
Updating the served collection is npm run sync, a commit, and a redeploy. The
pinned commit comes back from /healthz and from list_maps, so a stale
deployment is visible rather than silent.
Tools
| Tool | For |
|---|---|
search_notes |
Full-text search. Start here when you have a topic, not an id. |
get_note |
One note in full — Markdown, links, backlinks, and every citation. |
list_maps |
The hierarchy: each Map of Content and the concepts under it. |
get_citations |
Sources of truth, filterable by note, repository, or path. |
graphql |
Structural questions the other tools cannot answer. |
get_schema |
The GraphQL schema as SDL. |
Full reference: TOOLS.md.
The collection is also exposed as resources at
dpc-zettelkasten://note/<id>, one per note, so a client can attach a note to a
conversation without spending a tool call.
The GraphQL tool
{
notes(orderBy: degree, first: 5) {
title
degree
moc { title }
}
}
The schema travels in the tool's own description, so a model can write a correct query without a round trip — and a failed query gets the schema back in the error, which is usually enough to fix it on the next attempt. Read-only by construction: mutations, fragments, and variables are refused with an explanation rather than a parse error.
Where the data comes from
The graph and the query engine are vendored — committed into vendor/ — so
the server starts with no network and always serves a known snapshot. The cost
is that it goes stale, which is what npm run sync is for.
npm run sync # latest commit on the collection's main
npm run sync -- --ref <sha> # a specific commit
npm run sync -- --from ../dpc-zettelkasten # a local checkout
npm run sync -- --check # is the snapshot behind main?
Syncing resolves the branch to a commit SHA and fetches at that SHA,
recording it in vendor/SOURCE.json. The server then reports which commit it is
serving, both in its startup line and in list_maps, so a stale snapshot is
visible rather than silent.
That pinning is not decoration. raw.githubusercontent.com caches branch paths,
and an early version of this script fetched main and vendored a copy that was
a commit behind — while --check cheerfully reported it current. Paths under a
commit SHA are immutable and cache correctly. It is the same rule the collection
applies to its own citations, for the same reason: a branch is not a version.
A sync that produces a broken snapshot is refused rather than written. The
script loads the fetched engine against the fetched data, runs a query, and
checks they agree before touching vendor/.
Override the source at runtime if you would rather point at a checkout:
| Variable | Effect |
|---|---|
DPC_ZK_PATH |
Path to a dpc-zettelkasten checkout; uses its site/dataset.json and lib/zk-graphql.js |
DPC_ZK_DATASET |
Path to a specific dataset.json |
DPC_ZK_ENGINE |
Path to a specific zk-graphql.js, used with DPC_ZK_DATASET; ignored without it |
See CONFIG.md.
One schema, not two
vendor/zk-graphql.js is not a reimplementation. It is the same file the
zettelkasten's offline explorer inlines into its own page — the schema and
engine live in
lib/zk-graphql.js
over there, and both consumers load it.
That is deliberate. A schema maintained in two places drifts, and a model given a stale schema writes queries that fail for reasons it cannot see.
No dependencies
The server implements MCP's transports — JSON-RPC 2.0 over newline-delimited
stdio, and Streamable HTTP over node:http — directly, rather than through the
SDK. The official SDK is a dev dependency, used by the test suite to drive
this server as a real client would.
That is the claim worth testing, so the tests make it: over a hundred
assertions across the vendored data, the raw wire protocol, usage reporting, and
live sessions on both transports with @modelcontextprotocol/sdk.
npm install # dev dependencies, for the tests
npm test
Usage reporting
Usage reporting is on by default: the server sends its name, its version, the
transport it started on (startup), and the name of each tool called
(tool-call) to trace. Tool arguments,
notes, queries, and anything about the client or the person using it are never
sent — only names from the server's own tool list, so a name a client made up is
not sent either. The server says which way it is set on stderr every time it
starts.
Every event also carries a random installation ID (the tag install), so
trace can count installations rather than events. It is a UUID made on first
run, derived from nothing about the machine or you, and kept in
<user data dir>/dpc-mcp-server/trace-install-id — $XDG_DATA_HOME (or
~/.local/share) on Linux, ~/Library/Application Support on macOS,
%APPDATA% on Windows. Delete the file to reset it, or set TRACE_INSTALL_ID
to pin your own value (useful in a container, whose filesystem does not
outlive it). On Node 18 (anything before 20.16 or 22.3) the file cannot be used and the ID lasts
for one run only. Every opt-out below also stops the ID: with reporting off the
file is never read or created.
To turn it off, any one of these:
TRACE_USAGE_REPORTING=offin the server's environment (theenvblock of your MCP client's config)DO_NOT_TRACK=1in the server's environment"enabled": falseinsrc/usage-reporting.json
Details: https://github.com/Stephenson-Software/trace#usage-reporting
Support
Contributing
See CONTRIBUTING.md.
License
MIT.
DPC Zettelkasten MCP questions
What tools does DPC Zettelkasten MCP provide?
It exposes 6 tools, including search_notes, get_note, list_maps, get_citations, graphql.
How can I search for specific topics in the knowledge base?
You can use the search_notes tool to perform a full-text search when you have a topic but no specific note ID.
Does the server require any runtime dependencies?
No, the server requires Node 18 or later but has no other runtime dependencies.
How can I verify the claims made by the AI?
The server provides the citation behind every claim, including a GitHub permalink pinned to a specific commit SHA.
Can I run this server over HTTP?
Yes, the server supports MCP's Streamable HTTP transport for use in containers or on other machines.