The MCP (Model Context Protocol) server exposes pyrite tools to AI agents like Claude Code over stdio. Implemented as `PyriteMCPServer`, it uses the official `mcp` SDK to serve tools, prompts, and resources.
Three-Tier Tool Model
Each server instance runs at a single tier, which determines which tools are available:
| Tier | Access Level | Tools | |------|-------------|-------| | read | Safe for any agent | kb_list, kb_search, kb_get, kb_timeline, kb_backlinks, kb_tags, kb_stats, kb_schema, kb_orient, kb_batch_read, kb_list_entries, kb_recent, kb_qa_validate, kb_qa_status | | write | Trusted agents | read + kb_create, kb_bulk_create, kb_update, kb_delete, kb_link, kb_qa_assess | | admin | Full control | write + kb_index_sync, kb_manage, kb_commit, kb_push |
Tier is set at construction time via the `tier` parameter and validated against `VALID_TIERS`. Invalid tiers raise `ConfigError`.
Plugin Tool Merging
After core tools are registered, `_register_plugin_tools()` calls `registry.get_all_mcp_tools(self.tier)` to collect plugin-provided tools. Plugin tools are merged into the same `self.tools` dict, making them indistinguishable from core tools to MCP clients. Plugins register tools via the `get_mcp_tools(tier)` protocol method. Plugin loading failures are silently caught to avoid breaking the server.
Plugins receive a `PluginContext` with shared `config` and `db` references so they don't need to bootstrap their own connections.
Prompts
Four built-in prompts available at all tiers:
Each prompt returns MCP `PromptMessage` objects with pre-built user messages.
Resources
Static resources and URI templates for browsing:
Resources are read via `_read_resource()` which dispatches based on URI prefix matching.
SDK Integration
`build_sdk_server()` creates an `mcp.server.Server` instance and registers async handlers for all MCP protocol methods (list_tools, call_tool, list_prompts, get_prompt, list_resources, list_resource_templates, read_resource). The server runs over stdio via `anyio` in `run_stdio()`.
Post-Save QA Validation
Write tools (`kb_create`, `kb_update`) support opt-in QA validation via two mechanisms:
1. Per-request: Pass `validate: true` to run `QAService.validate_entry()` after save 2. KB-level: Set `validation.qa_on_write: true` in `kb.yaml` — all writes auto-validate
When triggered, the `_maybe_validate()` helper runs structural QA and appends `qa_issues` to the response if any issues are found. Clean entries return no `qa_issues` key.