MCP Servers
The gateway, per-skill servers, and the legacy aggregate bridge — plus what each harness supports.
processkit skills ship Python MCP servers that give agents
mechanical correctness on top of probabilistic reasoning. For entity
work, agents should use the MCP tools rather than hand-editing files:
write tools validate schemas, enforce state machines, and append
LogEntries where the server owns the side effect.
This Python implementation is intentional in v1. The native Rust CLI owns
release trust and content lifecycle; it does not replace the MCP servers.
Status
The exact server inventory is release-generated and validated by the MCP
manifest. Alpha.4 release acceptance exposes 199 gateway tools. Servers
ship across processkit’s primitive, workflow, projection, routing, gateway,
guard, and devops skills. Most
ship default mcp-config.json fragments. aggregate-mcp remains an
alternate compatibility entry point and does not register itself by
default; context-archiving also ships a server script without a
default config fragment.
Server scripts live under
context/skills/<category>/<skill>/mcp/server.py. Processkit
operation servers share a Python utility library at
context/skills/_lib/processkit/.
The current direction is gateway first for harnesses that pay startup
cost per stdio process. Per-skill servers remain canonical, but clients
may register one gateway process instead of the granular set when they
want one provider-neutral processkit tool surface.
processkit itself is usable without aibox. aibox is an installer and
supervisor that can fetch processkit content, merge harness config, and
manage a devcontainer. A user may also install the files by another
method and point any MCP-capable harness at the shipped Python server
commands directly.
Layer 0 — Foundation
| Server | Tools |
|---|
index-management | reindex, query_entities, get_entity, search_entities, query_events, list_errors, stats |
id-management | generate_id, validate_id, list_used_ids, format_info |
event-log | log_event, query_events, recent_events |
Layer 1 — Identity
| Server | Tools |
|---|
actor-profile | create_actor, get_actor, update_actor, deactivate_actor, list_actors |
role-management | create_role, create_role_template, get_role, update_role, list_roles, link_role_to_actor |
team-manager | TeamMember identity, active interlocutor, consistency, and agent-card helpers |
Layer 2 — Core entities
| Server | Tools |
|---|
workitem-management | create_workitem, create_process_instance, create_sep_handoff, transition_workitem, query_workitems, get_workitem, link_workitems |
decision-record | record_decision, transition_decision, query_decisions, get_decision, supersede_decision, link_decision_to_workitem |
artifact-management | create_artifact, get_artifact, query_artifacts, update_artifact |
note-management | prepare_hook_inbox_dirs, create_note, capture_inbox_item, claim_inbox_item, complete_inbox_item, fail_inbox_item |
scope-management | create_scope, get_scope, list_scopes, transition_scope |
gate-management | create_gate, create_gate_template, get_gate, list_gates, evaluate_gate |
binding-management | create_binding, create_time_window, create_budget_application, end_binding, query_bindings, resolve_bindings_for |
discussion-management | open_discussion, get_discussion, list_discussions, transition_discussion, add_outcome |
migration-management | list_migrations, get_migration, start_migration, apply_migration, reject_migration, migrate_context_to_v2 |
model-recommender | list_models, get_profile, query_models, compare_models, get_pricing, check_availability, get_config, set_config |
Layer 3 — Workflow and projections
Gateway
| Server | Tools |
|---|
processkit-gateway | list_gateway_tools, gateway_health, plus imported per-skill tools |
aggregate-mcp | list_aggregate_tools plus imported per-skill tools |
processkit-gateway is the provider-neutral gateway entry point. It can
run as a direct stdio server, as a streamable HTTP daemon, or behind a
lightweight stdio proxy for harnesses that only support command-backed
MCP. Eager stdio remains the simplest mode. Daemon mode can use a
catalog-backed lazy registration path so the gateway lists tools without
importing every backing skill server at startup.
aggregate-mcp is the legacy one-process compatibility bridge. Both
gateway surfaces keep unique tool names unchanged. If two source servers
expose the same helper name, later duplicates are registered as
<skill_slug>__<tool_name>.
Devops
| Server | Tools |
|---|
repo-management | detect_repo_provider, inspect_repo_state, list_repo_issues, list_repo_change_requests, plan_repo_reconcile, resolve_repo_issue, merge_change_request, commit_local_changes, push_current_branch, run_repo_reconcile |
Routing (cross-layer)
| Server | Tools |
|---|
skill-finder | find_skill, list_skills |
task-router | route_task — returns skill + process override + MCP tool in one call |
skill-gate | acknowledge_contract, check_contract_acknowledged, skip_decision_record |
A standalone smoke test (no MCP transport, just direct function calls)
runs all servers via:
uv run scripts/smoke-test-servers.py
Runtime requirements
Each MCP server is a standalone Python script using PEP 723 inline
dependency metadata:
#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.10"
# dependencies = ["mcp[cli]>=1.0,<2.0"]
# ///
from mcp.server.fastmcp import FastMCP
server = FastMCP("<skill-name>")
...
if __name__ == "__main__":
server.run(transport="stdio")
Consumers need only Python ≥ 3.10 and uv — both already present in
aibox containers. First run pays a small cost for uv to resolve and
cache dependencies; subsequent runs are near-instant.
Cold offline preparation is not yet a supported guarantee. See the
Python MCP runtime contract
.
Transport
Per-skill servers and aggregate-mcp use stdio. processkit-gateway
supports stdio and streamable HTTP:
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
serve --transport stdio
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
serve --transport streamable-http --host 127.0.0.1 --port 8000 \
--path /mcp
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
stdio-proxy --url http://127.0.0.1:8000/mcp
The streamable HTTP daemon binds to localhost by default. Do not expose
it on a non-local interface unless a deployment layer adds explicit
authentication and network policy.
Configuration
Most skills that ship an MCP server include an mcp/mcp-config.json
fragment:
{
"mcpServers": {
"<skill-name>": {
"command": "uv",
"args": ["run", "context/skills/processkit/<skill-name>/mcp/server.py"]
}
}
}
aibox init merges these fragments into the consuming project’s MCP
config file. Harnesses that support gateway mode may register
processkit-gateway instead of merging the per-skill fragments:
{
"mcpServers": {
"processkit-gateway": {
"command": "uv",
"args": [
"run",
"context/skills/processkit/processkit-gateway/mcp/server.py"
],
"env": {
"PROCESSKIT_MCP_MODE": "gateway"
}
}
}
}
The install path is
context/skills/processkit/<skill-name>/ — the processkit/
category subdirectory is part of the path. Provider-specific harness
files (e.g. .mcp.json for Claude Code) are written by aibox at the
right location for whichever harness the user picked.
Mode matrix
| Mode | Status | Process count | Best fit | Notes |
|---|
| Per-skill MCP servers | Canonical | Many | Fine-grained permissions and maximum compatibility | Each skill owns its server and config fragment. |
aggregate-mcp | Compatibility | One | Existing one-process configs | Legacy bridge; not the preferred new gateway name. |
processkit-gateway stdio | Current gateway | One | Claude Code, Codex, OpenCode, and other command-launching harnesses | Provider-neutral eager stdio server. |
| Daemon plus stdio proxy | Current gateway | One daemon plus lightweight proxies | Harnesses that restart stdio frequently | Requires a supervisor such as aibox or a user-managed daemon process. |
Which servers are mandatory
For per-skill registration, the following servers should always be
registered regardless of package tier. Without them, agents cannot use
the entity layer correctly:
| Server | Why mandatory |
|---|
index-management | Entity discovery and full-text search |
id-management | ID generation for all entity kinds |
workitem-management | Work tracking |
discussion-management | Structured deliberation |
decision-record | Decision capture |
event-log | Audit trail |
The same tools may be reached through processkit-gateway or
aggregate-mcp when a harness uses a one-process entry point.
Tier-specific servers (actor-profile, role-management,
scope-management, gate-management, binding-management,
model-recommender, and the workflow/projection servers) are registered
based on the installed package tier. artifact-management and
note-management are available in tiers that include their skills.
Compliance expectations
Agents should call route_task(task_description) before write-side
processkit tool calls and use find_skill when a processkit skill might
apply. Entity reads go through index-management; entity writes go
through the owning management server. If a state change is not already
logged by the MCP write tool, append a LogEntry with event-log.
1 - Harness Compatibility
processkit’s MCP servers are provider-neutral Python programs. They do
not require aibox at runtime. aibox can install processkit, merge MCP
configuration, pre-authorize processkit tools where a harness supports
that, and supervise a managed devcontainer. Those are convenience and
lifecycle features; they are not a processkit dependency.
The alpha.5 installer can project managed Codex and Claude configuration.
It owns only declared processkit keys and preserves unrelated harness settings
during install, update, and uninstall. Restart the harness after installation
so it reloads the projection.
For a direct install, point the harness at the desired server command
inside the installed context/skills tree. The recommended one-process
entry point is:
{
"mcpServers": {
"processkit-gateway": {
"command": "uv",
"args": [
"run",
"context/skills/processkit/processkit-gateway/mcp/server.py"
],
"env": {
"PROCESSKIT_MCP_MODE": "gateway"
}
}
}
}
Current modes
| Mode | Use when | Harness impact |
|---|
| Per-skill servers | You need fine-grained tool registration or the broadest compatibility. | The harness launches one stdio process per registered skill. |
aggregate-mcp | You already use the legacy aggregate server. | One stdio process, compatibility name, no daemon behavior. |
processkit-gateway stdio | You want the provider-neutral gateway surface now. | One stdio process, eager tool import, richer gateway metadata. |
| Daemon plus stdio proxy | You want a long-lived daemon with lightweight harness proxies. | One shared daemon plus one lightweight stdio proxy per harness. |
The current gateway command is equivalent to:
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
serve --transport stdio
Daemon mode starts a localhost streamable HTTP MCP server:
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
serve --transport streamable-http --host 127.0.0.1 --port 8000 \
--path /mcp
Harnesses that only support stdio can connect through the proxy:
{
"mcpServers": {
"processkit-gateway": {
"command": "uv",
"args": [
"run",
"context/skills/processkit/processkit-gateway/mcp/server.py",
"stdio-proxy",
"--url",
"http://127.0.0.1:8000/mcp"
],
"env": {
"PROCESSKIT_MCP_MODE": "gateway"
}
}
}
}
For lower daemon startup memory, generate a tool catalog and enable lazy
registration:
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
catalog --write
PROCESSKIT_GATEWAY_IMPORT_MODE=lazy-catalog \
uv run context/skills/processkit/processkit-gateway/mcp/server.py \
serve --transport streamable-http
Harness notes
| Harness | Recommended direction | Compatibility notes |
|---|
| Claude Code | Register processkit-gateway as an MCP stdio server, or keep per-skill servers when permission granularity matters. | Claude Code can launch command-backed MCP servers. aibox may also merge .mcp.json, settings, hooks, and preauthorization entries for managed projects. |
| Codex | Register processkit-gateway as an MCP stdio server. | Codex benefits from the one-process gateway because many per-skill stdio servers increase startup and approval overhead. Codex preauthorization support is narrower than Claude Code, so users may still see approval prompts depending on local policy. |
| OpenCode | Use stdio gateway mode when OpenCode is configured for MCP command servers. | Treat processkit as a normal MCP server command. aibox-specific supervision is optional and not required for direct use. |
| Hermes | Use stdio gateway mode when Hermes can launch MCP command servers. | The gateway is provider-neutral; Hermes-specific configuration should map the command and args exactly as shown above. |
| Aider | Use processkit skills and files directly; MCP gateway support depends on the surrounding Aider integration. | Aider is not a full MCP harness in the same sense as Claude Code or Codex. It may not enforce processkit tool-use contracts or call MCP tools without an adapter. |
Choosing a mode
Use processkit-gateway stdio for the simplest one-process harness
configuration. Use daemon plus stdio proxy when the environment can
supervise one long-lived gateway process and the harness frequently
restarts command-backed MCP servers. Use per-skill servers when a
harness policy model needs separate permission surfaces. Keep
aggregate-mcp only for existing configs that already depend on that
server name.
2 - Claude Code
Claude Code hooks, MCP configuration, and processkit routing behavior.
v1 alpha note: Install with --harness claude to create the managed
projection. The installer preserves unrelated Claude configuration. The
direct uv gateway remains the development and compatibility fallback.
This document captures how processkit surfaces itself inside the Claude
Code harness: which payloads land at session start vs. each turn, which
hooks fire, and which Claude Code settings we recommend for any
processkit project.
WorkItem: BACK-20260509_1317-DaringRaven (issue #19). Companion file:
settings.example.json
.
What the per-turn hook injects
scripts/emit_compliance_contract.py runs as both a SessionStart
and a UserPromptSubmit hook (wired in
/workspace/.claude/settings.json under hooks.SessionStart and
hooks.UserPromptSubmit). It now emits two different payloads:
- SessionStart — the full compliance contract from
context/skills/processkit/skill-gate/assets/compliance-contract.md
(~78 lines: 6 sections covering session start, sub-agent dispatch,
tool routing, entity writes, decisions, prohibitions). One-shot per
session. - UserPromptSubmit — the slim per-turn checklist (~14 lines):
3 positive actions (acknowledge, route, find skill), 3 prohibitions
(no hand-edit / no
ls/grep / no templates/), and a one-line
pointer to the full contract. Runs on every prompt.
The single source of truth is still
compliance-contract.md. The slim payload is the block delimited by
<!-- BEGIN HOOK --> … <!-- END HOOK --> markers in that file —
edit one file, both payloads update together. _extract_hook_block()
in emit_compliance_contract.py does the slicing.
If either marker is missing (e.g. partially-edited file), the slim
payload falls back to the full contract — safe by default.
How to use the full contract
Three reliable ways to load the full contract on demand:
- Start a fresh session —
SessionStart hook injects the full
text automatically. - Read the file —
context/skills/processkit/skill-gate/assets/compliance-contract.md
is plain Markdown, no preprocessing. - Call the MCP tool —
acknowledge_contract(version="v2") returns
the full contract text in its response (contract field).
Sub-agents dispatched mid-session inherit the parent’s context — they
get the slim payload from the most recent UserPromptSubmit plus the
full text the parent loaded at SessionStart, so the catalogue is
already in scope.
Recommended settings
See settings.example.json
for a copy-paste block. Two recommendations:
skillOverrides — name-only loading for verbose, rarely-used skills
The processkit ships ~30 skills under context/skills/processkit/.
Four of them are >400 lines and are creation/audit/setup skills, not
per-session workflow skills:
| Skill | Lines | When invoked |
|---|
skill-builder | 514 | Authoring a new skill |
skill-reviewer | 496 | Auditing an existing skill |
team-creator | 445 | Bootstrapping or rebalancing a team |
agent-management | 437 | Multi-agent orchestration setup |
Setting skillOverrides.<name>.mode = "name-only" for these tells
Claude Code to load a one-line description instead of the full
SKILL.md. The skill remains discoverable via /pk-* commands and
find_skill, and Claude Code loads the full body when the skill is
explicitly invoked.
Workflow-critical and routing skills (model-recommender,
team-manager, skill-finder, skill-gate) should stay fully loaded
— they are consulted by hooks and routing on most turns.
processkit installs the processkit-gateway MCP server, which exposes
130+ tools. By default Claude Code embeds every tool’s full JSONSchema
in the session prompt. ENABLE_TOOL_SEARCH=auto tells Claude Code to
hide tool schemas behind a ToolSearch tool until they are actually
needed, saving substantial per-turn tokens.
The trade-off is one extra round-trip the first time each tool is
called. With sticky caching (Claude Code 2.1+), the cost amortises
across the session.
Sub-agent dispatch
When dispatching a sub-agent, follow AGENTS.md ➜ “Before sub-agent
dispatch”:
- Call
route_task(task_description) to get
recommended_team_member_slug and recommended_model_class. - Pass the slug as Claude Code’s
subagent_type so the harness loads
the matching .claude/agents/<slug>.md adapter. - Pick the cheapest concrete model in the recommended class (Haiku <
Sonnet < Opus). Do not let the sub-agent inherit the parent’s
model — that defeats the team-dispatch token-efficiency strategy.
The adapter file written by team-manager.export_claude_subagent is
self-describing as of DaringRaven (rec 6): it carries a header comment
with the TeamMember ID, slug, role, seniority, model policy, and
resolved binding so a reader can audit .claude/agents/<slug>.md
against the live roster without re-resolving.
Verification
pk-doctor covers this surface with two checks:
preauth_applied — confirms the processkit MCP-tool allowlist
is preauthorised in .claude/settings.json so MCP calls don’t
prompt mid-turn.team_member_exports — reconciles active TeamMembers against
.claude/agents/<slug>.md adapter files. Detects stale or missing
exports.
Run /pk-doctor for a full report. To smoke-test the hook payload
without restarting:
echo '{"hook_event_name":"UserPromptSubmit"}' | \
python3 context/skills/processkit/skill-gate/scripts/emit_compliance_contract.py
Should emit the slim ~14-line payload. Same with
hook_event_name=SessionStart should emit the full contract.
The hook-script tests live in
context/skills/processkit/skill-gate/scripts/test_hooks.py (run with
python3 ... — no extra deps). Tests [2c] and [2d] cover the
slim/full split.
Common MCP calls + Claude Code shortcuts (v0.26.0)
The processkit-gateway aggregator exposes all processkit MCP tools
through a single server. The most frequently needed calls:
| Goal | Tool | Notes |
|---|
| Read entity by ID | get_entity(id=...) | Accepts prefix, word-pair, or full ID |
| Read entity by path | get_entity_by_path(path=...) | Path relative to project root |
| List entities | list_entities(kind?, state?, limit?) | All kinds; v1-penalty annotated |
| Search entities | search_entities(text) / hybrid_search_entities(text) | FTS + semantic |
| Create work item | create_workitem(...) | Route first via route_task |
| Transition state | transition_workitem(id, to_state) | Enforces state machine |
| Run health check | run_pk_doctor(check?, fix?) | Returns structured JSON |
| Run release audit | run_pk_release_audit(tree?) | Returns structured JSON |
| Route a task | route_task(task_description=...) | Required before write calls + Agent dispatch |
With ENABLE_TOOL_SEARCH=auto, tool schemas are deferred. You must call
ToolSearch(query="select:<tool_name>") before invoking a deferred tool.
Common selects:
ToolSearch(query="select:mcp__processkit-gateway__get_entity,mcp__processkit-gateway__route_task")
ToolSearch(query="select:mcp__processkit-gateway__create_workitem,mcp__processkit-gateway__transition_workitem")
Recommended enabledMcpjsonServers
Only processkit-gateway needs to be in enabledMcpjsonServers. The
gateway proxies all other processkit MCP servers without requiring each
one to be individually listed.
{ "enabledMcpjsonServers": ["processkit-gateway"] }
Entity-read BLOCK behavior (v0.26.0)
A new check_entity_read.py PreToolUse hook blocks Read on
canonical entity paths:
context/{workitems,decisions,artifacts,team-members,scopes,
gates,actors,roles,bindings}/**/*.md
Blocked → use get_entity(id='...') or get_entity_by_path(path='...').
Not blocked (gray area): skill source code under
context/skills/<skill>/, log entries, schemas, applied migrations,
TeamMember sub-files (persona.md, card.json, knowledge/, etc.),
and anything outside context/.
If you see BLOCKED: <path> is a canonical entity file, the remediation
is always one of:
get_entity(id="<derived-id>") # by ID
get_entity_by_path(path="<rel-path>") # by path
list_entities(kind="WorkItem", state="open") # browse
search_entities(text="<keyword>") # search
Agent dispatch validation (v0.26.0)
A new check_route_task_before_agent.py PreToolUse hook blocks
Agent and Task dispatch without a prior route_task call in the
same turn.
Correct pattern:
route = route_task(task_description="summarise the release notes")
# read route["recommended_team_member_slug"] and route["recommended_model_class"]
Agent(prompt="...", model="<recommended model>")
If the context/.state/skill-gate/ directory does not exist (first run
before any processkit MCP call), the hook warns but does not block
(graceful degradation).
Open items
.claude/settings.example.json was the natural home for the
recommended-settings JSON, but the harness sandbox currently blocks
unattended writes under .claude/. The file lives at
docs-site/content/en/docs/mcp-servers/claude-code/settings.example.json
instead and must be copied into .claude/settings.json (or the
user-level config) by hand. If/when sandbox policy permits, the
canonical location is .claude/settings.example.json.skillOverrides schema validation: Claude Code accepts the
name-only mode but the project hasn’t yet wired schema acceptance
into pk-doctor. Track in a follow-up if drift is observed.