Skip to content

MisakaNet MCP Server

MisakaNet exposes its lesson knowledge base via the Model Context Protocol, enabling AI assistants to search and retrieve engineering lessons in real time.

Quick Start

1. Prerequisites

cd MisakaNet
# Homebrew/Debian/Fedora Python refuse a system-wide install (PEP 668), so this
# creates a virtualenv first. Harmless everywhere else.
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt

2. Test the server

# Start the MCP server (stdio transport)
python3 scripts/mcp_server.py

3. Connect from Claude Code

Add to ~/.claude.json (user/local scope) or .mcp.json at the project root (project scope, committable):

{
  "mcpServers": {
    "misakanet": {
      "command": "python3",
      "args": ["/path/to/MisakaNet/scripts/mcp_server.py"]
    }
  }
}

不是 settings.json。 Claude Code 从 ~/.claude.json(local/user scope)和项目根的 .mcp.json(project scope)读 MCP servers;~/.claude/settings.json 放的是 hooks、 permissions、env。这一页此前写错成 settings.json(安装器 npx @misaka-net/misakanet-setup 写的是 ~/.claude.json,两边对不上);把 mcpServers 放错文件的症状是 /mcp 里什么都看不到。 官方 scope 表:https://docs.claude.com/en/docs/claude-code/mcp

更省事的路径:整仓都不用 clone —— claude mcp add --transport http misakanet https://misakanet.org/mcp 直接接远端端点(托管工具集,读不限次数免注册)。

4. Connect from Cursor

Create .cursor/mcp.json in your project root:

{
  "mcpServers": {
    "misakanet": {
      "command": "python3",
      "args": ["/path/to/MisakaNet/scripts/mcp_server.py"],
      "env": {}
    }
  }
}

5. Connect from Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "misakanet": {
      "command": "python3",
      "args": ["/path/to/MisakaNet/scripts/mcp_server.py"]
    }
  }
}

Which surface?

This page documents the local stdio server, because that is what the install steps above configure. It is not the same surface as the hosted endpoint that most agents are pointed at by the README and AGENTS.md, and the difference is the thing a reader gets wrong:

surface how you reach it tools resources prompts
local stdio — what this page installs python3 scripts/mcp_server.py 11: misakanet_search, misakanet_get_lesson, misakanet_submit_usage, misakanet_submit_intake, misakanet_write_lesson, misakanet_preflight, misakanet_usage_status, misakanet_register, misakanet_memory_context, misakanet_me_events, misakanet_me_inbox 5 (below) 3 (below)
local HTTP (optional) python3 scripts/mcp_http_server.py 6: misakanet_search, misakanet_get_lesson, misakanet_submit_intake, misakanet_submit_usage, misakanet_usage_status, misakanet_register 3 2
hosted — what agents usually call https://misakanet.org/mcp 8: the stdio set minus the three local-only tools misakanet_submit_usage, misakanet_usage_status, misakanet_memory_context none none

The hosted endpoint exposes tools only. It handles tools/list and tools/call and nothing else (measured 2026-09-25), so an MCP client that calls resources/list or prompts/list against misakanet.org/mcp gets an error rather than the tables below. misaka://… URIs and prompts are a local-only feature; the hosted surface's tool set is the eight names above.

Since 2026-09-30 (owner decision D4=A, issue #2000) the hosted set is a subset of the local one: the local stdio server registers misakanet_me_events too, as a proxy of the hosted tool (the evidence it returns is aggregated server-side), and the only difference left is the three tools that read the local checkout — misakanet_submit_usage, misakanet_usage_status, misakanet_memory_context. Before that, misakanet_me_events was hosted-only, so the skill's reuse-evidence step answered "Unknown tool" on a local install. .codex-plugin/plugin.json declares both sets, and tests/test_mcp_capability_parity.py checks them against this server and the worker.

misakanet_me_inbox is a proxy too, and for the same reason: intake status lives in the worker's D1/KV stores. The local server answers an intake that is still in this checkout's contribution queue from the queue, and forwards everything else to the hosted tool — so the same id gets the same answer on both surfaces. Before 2026-11-03 it called a /api/inbox route that does not exist and answered not_found for every hosted lookup (#3577).

The three sets are pinned against their sources by tests/test_mcp_doc_surface.py, so a tool added without a line here fails the suite rather than leaving a reader with a wrong map.

Available Tools

The three below are the ones with parameters people ask about; the full set is in the table above (which also says which surface has which).

Tool Description Parameters
misakanet_search Search lessons by query query (required), domain?, top? (default 5)
misakanet_get_lesson Get a specific lesson path or id (required)
misakanet_submit_usage Report lesson usage — outcome feeds live reuse signals (solved → helpful vote; partial/not-helpful → feedback) lesson_id (required), tool?, outcome?

Reading and searching need no node. The write tool (misakanet_write_lesson) needs a node and a token — one registration gets both. misakanet_preflight is read-only and open, so an anonymous connector can call it (rate-limited): https://misakanet.org/register/

The registration response's identity fields

misakanet_register answers with {node_id, token, registered_at, agent_type, reused} and reused is always present — it is the one field that says whether the client_id you sent was recognised:

reused Meaning What to do
true an existing node was found for this client_id, and its token was renewed keep using it; this is the renewal path
false this call minted a new node the client_id you sent was not recognised, so this token is not attached to whatever history you thought you were reusing

The false case used to be indistinguishable from a server that never implemented the field, because it was simply omitted (#4072). The server cannot tell you which id was the right one — that mapping lives on your side — so a client that stores its client_id somewhere durable (not in a hint header, which the endpoint treats as a hint and never as identity) is the only way to keep one node across token expiries.

The name is not the key (2026-10-31). A renewal now expects the token it was given, sent the normal way:

# renewal: the same client_id AND the token you already hold
curl -sS https://misakanet.org/mcp -H "Authorization: Bearer $MISAKANET_TOKEN" ...   -d '… "misakanet_register", "arguments": {"client_id": "8f14e45f-…"} …'
what you send what happens
client_id + a valid token for that node renewed, reused: true — the supported path
client_id alone, during the grace window renewed, reused: true, plus deprecated telling you to add the token
client_id alone, strict mode {error, code: "client_id_proof_required"} and no token
a fresh client_id a new node, as before

The reason is one sentence: an agent's client_id appears in configs, transcripts and tutorials, so a value that appears in prose cannot be the only thing standing between a stranger and a 30-day write token.

Reading errors

misakanet_get_lesson answers {error, code} when it cannot return a lesson, and the code is what says what to do next:

Code Meaning
lesson_not_found No such lesson (id or path, on main or data). Search instead of retrying.
invalid_lesson_path The argument is not a lesson reference. path must be a file under lessons/ ending in .md — other repository files are not readable through this tool.
internal_error A service fault. Retrying is reasonable.

Added 2026-09-25 (B35), because those last two were one code: a missing lesson answered internal_error — the message for a transient fault — so a caller that obeyed it retried a 404 forever, and a caller that quoted it reported MisakaNet as down for its own typo. In the same call path went into the GitHub contents URL unvalidated, so path=docs/CI.md returned that file.

When a call fails: fetch failed is not the same as "the service is down"

A client-side transport error (fetch failed, UND_ERR_HEADERS_TIMEOUT, a JSON-RPC timeout) is the client giving up. Measured on 2026-10-29 (#4052): one agent's whole session reported "the endpoint does not work" while initialize answered in ~2 s, submit_intake succeeded, and misakanet_search swung from 1.3 s to 62 s on the same query. Every one of those calls reached the server; the client stopped waiting.

What to do with that knowledge:

  • retry the call once, a few seconds later. misakanet_search, misakanet_get_lesson and misakanet_me_inbox are idempotent reads — a retry cannot double-apply anything. A single fetch failed is not evidence about the service; two in a row after a wait is worth reporting.
  • do not conclude the endpoint is down, and do not degrade to "I could not find anything" — that is a different claim from "the search did not answer in time".
  • the server-side numbers are in GET /api/search-signals/stats (latency histogram, buckets <1s / 1–3s / 3–10s / 10–30s / 30–60s / ≥60s), and python3 scripts/bench_search_latency.py --remote reproduces the client's own view in one command.

Resources

Local stdio surface only — the hosted endpoint exposes no resources (see Which surface?).

URI Description
misaka://lessons/index Browse all published lessons (core + contrib)
misaka://protocol/overview failure-memory protocol config (trust tiers, rings, scoring)
misaka://docs/readme Project overview and quickstart
misaka://docs/faq Troubleshooting FAQ
misaka://docs/changelog Latest release notes

Prompts

Local stdio surface only — the hosted endpoint exposes no prompts (see Which surface?).

Name Description Arguments
search_lesson Guided lesson search query (required), domain?
triage_failure Structured failure triage error (required), context?
release_audit Release readiness check version (required)

Search Scopes

By default, the server searches core and contrib lessons only. Drafts are excluded to avoid surfacing unverified content.

Search Sources

The server uses two search backends (auto-detected):

  1. SAG-Lite (SQLite) — fast, pre-built index at data/sag.db
  2. BM25 (fallback) — real-time search via misakanet.search.engine

If neither is available, the server returns an error suggesting index rebuild:

python3 scripts/build_sag_index.py

Smoke Test

Run the built-in smoke test to verify your setup:

python3 tests/test_mcp_server.py

This tests: - search returns results with path and status at every detail level, plus freshness (fresh / recent / aging / stale) at compact and summary. There is no badge field — an earlier version of this line promised one, and the surface never sent it; the freshness tier is a plain label. (The offline CLI's search_knowledge.py --json does emit a badge, inside a freshness object — but that is a score, not this age bucket, so the two freshness fields are not comparable: see docs/cli-reference.md.) - get_lesson returns lesson content - Default scope excludes drafts

Security & Boundaries

  • Not a skill marketplace. MisakaNet is a failure memory network — lessons come from real debugging sessions, not curated skill packs.
  • Read-only by default. Tools like misakanet_search and misakanet_get_lesson are read-only. misakanet_submit_usage reports the lesson outcome to the public worker endpoint (/api/helpful for solved, /api/feedback for partial/not-helpful) — offline-safe: it falls back to local logging when the worker is unreachable.
  • No raw sensitive content uploaded. Search queries stay local. Lesson content is public (open-source repo). Usage reports contain only lesson ID + outcome, not source code or error logs.
  • Write operations require explicit confirmation. misakanet_write_lesson and misakanet_submit_intake create GitHub issues only when called — nothing is sent without an explicit tool call.

Glama

MisakaNet is listed on Glama.ai for MCP server discovery.