@centralcloud/purpose-agent-tools (0.6.37)
Installation
@centralcloud:registry=npm install @centralcloud/purpose-agent-tools@0.6.37"@centralcloud/purpose-agent-tools": "0.6.37"About this package
purpose-agent-tools-mcp
Purpose-First agent skills, workflow guidance, and redteam review tools over MCP.
Purpose: help human maintainers understand the package, public MCP surface, install flow, release process, and CentralCloud deployment.
Consumer: engineers operating or changing purpose-agent-tools-mcp. Agent behavior
is controlled by the MCP instructions, load_skill, install_skills, scoped
AGENTS.md files, and tests, not by this README.
purpose-agent-tools-mcp is a Model Context Protocol server that
exposes Purpose-First skills through a single load_skill MCP tool plus resources that
return skill text on demand (CALL-TO-LOAD — see below) and can be self-installed for
auto-activation (see Versioned self-install), plus
generic redteam_run panel/gate tool for adversarial review modes (review, plan,
decision, bughunt, architect, verify, hack, ultrareview, harvest). The MCP server
owns the redteam panel runner path; clients should not shell to local redteam bundles.
How skills work over MCP (CALL-TO-LOAD, not auto-activation)
Mounting this MCP server does NOT auto-activate skills in Claude or any other client. Skills are not Claude Code skills plugins; they are MCP tools that return guidance text when called.
The workflow is:
- The server's
instructionsfield (sent to the client atinitializetime) stays compact: it tells the agent to call the singleload_skilltool with the relevant skill name and uselist_skillsfor the full machine-readable index. - When the agent calls
load_skill({ name })(e.g.load_skill({ name: "brainstorming" })), the server returns that skill's fullSKILL.mdbody as text and asstructuredContent.guidancefor routers that prefer structured output. There is ONE dispatcher tool —load_skill— whose description embeds the whole catalog (name— when-to-use);list_skillsreturns the grouped index and each entry'snameis the value to pass toload_skill. - Nothing happens automatically — the agent must read the instructions field, recognize the trigger, and make the tool call.
This means skill effectiveness depends entirely on whether the client surfaces
the instructions field to the model and whether the model acts on it. Most
clients (Claude Code ≥ 0.2, Copilot CLI ≥ 1.5) do include the instructions
in context.
Discovery tools
| Tool | What it returns |
|---|---|
initial_instructions |
Current Purpose-First MCP bootstrap instructions, preferred skill loader, fallback skill/file tools, resource-tool names, registered skill count, instruction bundle hash, and instruction block hash. Use when a client missed or truncated MCP initialize instructions. |
list_skills |
{bundleHash, categories: {category: [{name, description, category, origin, hash}]}} — the machine-readable index. The hash (12 hex of sha256 over the whole skill package) and bundleHash drive versioned self-install |
skill_manifest |
Manifest for one skill package, including skill:// URIs for SKILL.md and auxiliary files such as templates, examples, scripts, references, and assets. |
skill_file_read |
Read one hosted skill package file by {name,path} when MCP resources are hidden or the client only exposes tools. |
install_skills |
{bundleHash, instructionsHash, installInstructions, installSteps, skills: [{name, hash, files: [{path, content}]}], agentsBlock: {begin, end, hash, body, full}} — full skill packages for self-install (raw SKILL.md with frontmatter + all aux files) plus executable install steps and a Beads-pattern managed AGENTS.md/CLAUDE.md block (HTML markers carrying bundleHash, body carrying instructionsHash, idempotent). Optional names selects a subset; bundleHash + agentsBlock always full-bundle. Consent + hash-verify before any write. |
server_info |
Full capability matrix, registered counts, and lazy self-update metadata |
check_update |
npm dist-tag check for npm-backed stdio clients; reports status:"ok" plus restartRequired when @latest is newer, or status:"unknown" when the registry cannot be reached or is older than the running package. Does not validate the cluster image. |
server_logs |
Recent server log lines (redacted) + counts — debug the server itself over MCP |
redteam_run |
Generic prepared-opposer panel gate: {mode,input,focus?,extra_args?} returns verdict + jobId |
redteam_list_jobs |
Recent panel jobs (id, kind, status, elapsed, summary) |
redteam_job_trace |
A job's panel.log trace tape (redacted) — pull-based span read |
redteam_job_result |
A job's stored final panel result |
purpose_research_to_implementation |
Purpose-First research-to-implementation evidence workflow: Stage 1 read-only research lanes, Stage 2 translation matrix, Stage 3 optional redteam gate |
purpose_research_to_implementation_list_jobs / purpose_research_to_implementation_job_trace / purpose_research_to_implementation_job_result |
Pull-based research-to-implementation job diagnostics and stored research packet reads |
load_skill |
Full SKILL.md body for one skill, selected by name or catalog alias |
Redteam tools
redteam_run is the panel/gate surface for cross-model adversarial review.
Pass mode as one of review, plan, decision, bughunt, architect,
verify, hack, ultrareview, or harvest. These tools are long-running
(30–120 s) and require model-provider API keys in the MCP server environment.
Purpose-First Research-to-Implementation
research-to-implementation is the Purpose-First research-to-implementation
gate for high-leverage work:
agent architecture, self-improvement loops, memory/context systems,
benchmark/eval design, role/persona design, planning systems,
policy/instruction surfaces, new reusable capability surfaces, and unclear
brownfield design. It is not for ordinary bugfixes.
purpose_research_to_implementation runs the executable research-to-implementation flow:
- Stage 1: read-only research lanes gather local source, local docs/tests, external official evidence, benchmark/eval signals, and skeptical review.
- Stage 2: the coordinator translates evidence into the matrix:
Pattern -> Source evidence -> Local existing capability -> Gap -> Purpose -> Success boost or failure prevention -> Success metric -> Smallest experiment -> Falsifier. - Stage 3: redteam gate guidance. Use
redteam_run(mode="decision")for adopt/reject pattern decisions,redteam_run(mode="plan")for the implementation plan, andredteam_run(mode="review")only after code/docs/skills/instructions changed.
Research lane sampling defaults to small/fast model hints (auto-fast,
auto-flash, mini/haiku/flash-class hints). Pass modelHints to request a
specific client-supported route such as sonnet, gpt-mini, or a gateway alias.
Versioned self-install
The MCP server is the single source of skills: clients pull the full skill package from the running server, never from a repo path. To get real auto-activation (skills trigger without an explicit tool call), an agent installs the complete skill packages into its skills dir and re-installs when they drift — all over MCP, no manual sync.
The model:
- On connect, call
list_skills. Each entry carries a contenthash(first 12 hex of sha256 over the whole skill package), and the response carries abundleHash(one fingerprint over all sortedname:hashlines). - Compare your installed skills' hashes to those. If any are missing or
stale (different hash), call
install_skills. install_skillsreturns{bundleHash, instructionsHash, installInstructions, installSteps, skills: [{name, hash, files: [{path, content}]}]}. FollowinstallStepsin order; each step carries an action and verification. Each file'spathis prefixed with the skill name (e.g.<name>/SKILL.md,<name>/references/foo.md,<name>/scripts/run.sh). Write each file'scontentto<your-skills-dir>/<path>verbatim — one of~/.claude/skills/,~/.copilot/skills/, or<repo>/.agents/skills/. Passnamesto install a subset; the returnedbundleHashalways reflects the full bundle so it still matcheslist_skills.- Once installed, the client's own frontmatter-driven loader auto-activates
the skills directly: the served
SKILL.mdis the raw file with itsname/descriptionfrontmatter intact (no reconstruction needed), and all auxiliary files (references/,scripts/,assets/, …) ship in the same package. Theload_skill({ name })dispatcher remains the call-to-load fallback if you cannot write to a skills dir.
The MCP server serves complete skill packages: the raw SKILL.md (with
frontmatter) plus every auxiliary file, recursively. Multi-file skills —
using-skills, writing-skills, brainstorming, systematic-debugging,
subagent-driven-development — install in full, companion files and all.
Bundled installer + managed AGENTS.md block
One install_skills call is the whole installer. Besides the skill packages it
also returns installInstructions, installSteps, and agentsBlock, a managed
instruction-file block the agent merges into the client's instruction file
(AGENTS.md / CLAUDE.md / GEMINI.md /
.github/copilot-instructions.md):
agentsBlock: {
begin: "<!-- BEGIN purpose-agent-tools skills (<bundleHash>) -->",
end: "<!-- END purpose-agent-tools skills -->",
hash: "<instructionsHash>",
body: "<the managed reminder: intro + grouped skill index + CALL-before rule + redteam usage>",
full: "<begin>\n<body>\n<end>" // exactly what the agent writes between the markers
}
This follows the Beads marker pattern:
HTML-comment BEGIN/END markers wrap the managed region, the begin
marker carries the bundleHash and the body starts with Instruction block hash: <instructionsHash> so instruction-only wording changes are detectable without
changing the skill package hash. The agent
replaces only the text between the markers — never touching hand-written
content. The block is therefore idempotent (re-running replaces in place),
removable (delete between the markers), and multi-tool-coexistent (each
tool's managed block uses its own markers). body is generated from the same
shared helper as the server instructions field, so the two never drift, and
agentsBlock always reflects the full bundle even when names filters the
returned files.
Trust boundary: CONSENT + hash-verify before any write
The MCP server is a trust boundary, not a backstop. The server can only direct the agent — it cannot write to the user's machine. So before any write the agent MUST:
- Ask the user's consent before writing skill files or merging the block.
- Verify the returned
bundleHashand filecontentagainstlist_skillsbefore trusting them. - Only then write each skill file at
<skillsDir>/<path>and mergeagentsBlock.fullinto the instruction file by replacing only the managed region. To stay idempotent across hash changes, locate the existing region by the stablebeginprefix<!-- BEGIN purpose-agent-tools skills(ignore the parenthesized hash, which changes on re-install) through the hash-freeendmarker, replace that whole region with the newagentsBlock.full, and append once at EOF under## Managed Tool Instructionsonly if no region is found. PutagentsBlock.fulldirectly below that heading. Never insert it inside an existing section, and never delete, rewrite, move, summarize, or replace hand-written content. Matching the new hash-bearingbeginas a literal would miss the old block and append a duplicate.
Sandboxing is not a substitute for this: a malicious or compromised server could ship hostile instruction text, and sandboxing does not fully isolate what an instruction-following agent will do once it reads that text. Consent + content verification is the actual control.
Default install uses instruction files, not hooks
install_skills defaults to MCP tools plus a managed instruction-file block.
Codex and Copilot use AGENTS.md; Claude Code uses CLAUDE.md. Local
skill-file installation is optional and only happens when explicitly requested.
Command hooks are executable lifecycle automation and are not installed by the
default flow.
Repo-local native skills are overrides in <repo>/.agents/skills/ — not
copies of Purpose-First skills. Put repo paths, verify commands, and org facts
there; keep generic workflow in purpose-agent-tools.
When you need one: a PAT base skill applies but lacks this repo's paths or commands (e.g. quarry-port donor/receiver tables).
How (maintainer):
load_skill({ name: "repo-skill-overlays" })+ the base skill.- Add
.agents/skills/<repo>-<topic>/SKILL.mdwithextends,repo_overlay,addon_forin frontmatter. - Body = facts only. On MCP hosts with the repo mounted, call
check_agents_block({ repoRoot })orinstall_skills({ repoRoot })for runtimeoverlayRoutes(not embedded in the managed block).
Agents load base from PAT first, overlay second when triggered. If the
gap is generic, improve purpose-agent-tools instead of growing the overlay.
Load repo-skill-overlays for the full contract (layout, invocation, templates).
Manual install (no MCP) still works — distribute the SKILL.md files as a
Claude Code plugin:
- Claude Code: drop each skill directory into
~/.claude/skills/<name>/SKILL.mdor publish a.claudepluginmanifest that lists the skill dir. Claude Code then auto-loads triggers from frontmatter. - Copilot CLI: use MCP plus
AGENTS.md/.github/copilot-instructions.mdby default. Sync into~/.copilot/skills/<name>/SKILL.mdor~/.agents/skills/<name>/SKILL.mdonly when native local skills are explicitly wanted.
The MCP server is complementary to plugin auto-activation, not a replacement. It provides:
- Redteam adversarial review tools unavailable as dotfile skills.
- Central skill text: update skills in one place, all clients pick them up on the next call (or listChanged notification).
- The
instructionsreminder for clients that read it. - The
list_skillsdiscovery endpoint for programmatic agents (grouped by category, with each skill'soriginprovenance).
Why
The dotfile skills pattern works but has known friction:
- new skills aren't discoverable mid-session (requires restart)
- 3-place sync (dotfiles →
~/.copilot/skills/→~/.claude/skills/) - per-client install dirs in activation scripts
- redteam's
jsonrepairdep needs annpm installdance on every HM switch
This server packages skills + redteam behind one MCP server with the
full modern feature surface (listChanged, subscribe, logging,
sampling, elicitation, and progress notifications). One image, one port (8931),
one config entry per client.
Capability Matrix
| Capability | Support | Notes |
|---|---|---|
tools |
✅ listChanged | initial_instructions + load_skill + list_skills + install_skills + server_info + check_update + redteam_run + research-to-implementation tools |
resources |
✅ listChanged, subscribe | skill://purpose_agent_tools/<name> package descriptors plus .../SKILL.md and package file URIs |
prompts |
✅ listChanged | No per-skill prompts; skill bodies are served through load_skill |
logging |
✅ server-initiated | RFC 5424 levels, client controls floor |
tasks |
❌ not advertised | Use progress notifications plus redteam_job_* / purpose_research_to_implementation_job_* pull-based resources until client support is verified |
sampling/createMessage |
✅ | via ctx.mcpReq.requestSampling from tool handlers |
elicitation/create |
✅ | via ctx.mcpReq.elicitInput from redteam handlers |
notifications/progress |
✅ | via ctx.mcpReq.notify for long redteam/research-to-implementation runs |
| Hot-reload | ⚠️ | sends listChanged on file change; load_skill, list_skills, initial_instructions, and resources read the live registry, so changed skills load without a restart |
Architecture
┌──────────────────────────────────────────────────────────┐
│ purpose-agent-tools-mcp (HTTP, port 8931) │
│ ┌────────────────────┐ ┌─────────────────────────────┐ │
│ │ Skills loader │ │ Redteam wrapper │ │
│ │ (chokidar watcher) │ │ (spawn node panel.mjs) │ │
│ └────────────────────┘ └─────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ MCP server (SDK v2 alpha) │ │
│ │ tools[] resources[] prompts[] logging │ │
│ │ ctx.mcpReq sampling / elicitation / progress │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Express + helmet + cors + rate-limit + req-id │ │
│ │ POST /mcp GET /mcp DELETE /mcp │ │
│ │ GET /healthz /readyz /info │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
Why redteam and redteam-result-handling exist in two places
skills/<name>/SKILL.md is the MCP-canonical copy the server loads (and the
only one carrying the metadata map with category/origin);
redteam/skills/<name>/SKILL.md is the
self-contained plugin distribution (plugin.json → "skills": "./skills/")
that uses paths relative to redteam/. A symlink to ../../skills/<name> would
point outside the plugin tree and break when the plugin is packaged alone, so
the two copies are kept separate by design.
Local dev
nix develop # enter dev shell (node + pnpm + biome + vitest)
nix develop --command pnpm install --frozen-lockfile # install deps
nix develop --command pnpm run build # compile TS to dist/
nix develop --command pnpm run test # run vitest
nix develop --command pnpm run start # run server on :8931
Npm-backed clients should launch the stdio server with online dist-tag resolution:
npx -y --prefer-online @centralcloud/purpose-agent-tools@latest
The package's managed installer also writes prefer-online=true beside the
CentralCloud registry mapping in .npmrc. That makes future launches refresh
metadata before reusing a cached package.
The stdio bin is a stable shim. It owns the client-facing MCP session and runs
the full MCP server in a stdio-worker.js child process. Rebuilt dist/**/*.js
code restarts the worker and replays the cached MCP initialize/initialized
handshake without requiring the MCP client to respawn the shim. Set
PURPOSE_AGENT_TOOLS_STDIO_NO_WORKER_RELOAD=1 to disable worker restarts.
Smoke test:
nix develop --command pnpm run build
nix develop --command pnpm run start &
curl localhost:8931/healthz
curl localhost:8931/info
Official MCP server conformance:
nix develop --command pnpm run test:mcp:conformance
nix develop --command pnpm run test:mcp:conformance -- --scenario tools-list
nix develop --command pnpm run test:mcp:conformance -- --suite active
The wrapper starts dist/server.js on 127.0.0.1, waits for /readyz, then
runs pinned @modelcontextprotocol/conformance@0.2.0-alpha.7 server tests
against /mcp, matching the v2 alpha MCP SDK packages used by this repo.
Override with PURPOSE_CONFORMANCE_PACKAGE=@modelcontextprotocol/conformance@0.1.16
to compare against the stable conformance line. Default is the generic
server-initialize scenario. The full active suite is available with
--suite active, but several scenarios expect fixture tools or resources such
as test_simple_text and test://static-text.
Nix build (binary + container)
nix build .#default # bundles node_modules + skills + redteam → ./result/bin/purpose-agent-tools-mcp
nix build .#container # nix2container OCI image JSON
nix run .#copy-container # low-level local copy app; Forgejo CI owns cluster tags
Image is purpose-agent-tools-mcp:latest, listens on :8931, env vars:
| Var | Default | Description |
|---|---|---|
PURPOSE_AGENT_TOOLS_PORT |
8931 |
HTTP listen port |
PURPOSE_AGENT_TOOLS_HOST |
0.0.0.0 |
HTTP bind address |
PURPOSE_AGENT_TOOLS_SKILLS_DIR |
bundled /lib/purpose-agent-tools-mcp/skills |
Path to skill directories containing SKILL.md files |
PURPOSE_AGENT_TOOLS_REDTEAM_DIR |
bundled /lib/purpose-agent-tools-mcp/redteam |
Path to the redteam/ directory containing scripts/panel.mjs |
PURPOSE_AGENT_TOOLS_ALLOWED_ROOTS |
unset (all local paths except denied secret/system roots) | Path-list of allowed roots for research-to-implementation/redteam local file reads |
PURPOSE_AGENT_TOOLS_NO_HOT_RELOAD |
stdio: unset (hot reload on); set to 1 to disable. HTTP image: disabled. |
Disables chokidar file-watching. Stdio hot reload updates stable skill read surfaces server-side without client listChanged/logging reload hooks. HTTP sessions keep listChanged notifications when hot reload is enabled by an embedding. |
PURPOSE_AGENT_TOOLS_STDIO_NO_WORKER_RELOAD |
unset (stdio worker restarts on built-code changes); set to 1 to disable |
Keeps the stable stdio shim running but disables restart-on-change for the child worker. |
PURPOSE_AGENT_TOOLS_STATELESS |
unset (stateful sessions, default); set to 1 to enable |
Stateless HTTP transport mode — each POST creates a fresh transport with no session tracking. Suitable for serverless runtimes and reverse-proxy deployments where sticky sessions are unavailable. GET and DELETE /mcp return 405 in this mode. |
PURPOSE_AGENT_TOOLS_RATE_LIMIT_PER_MINUTE |
600 |
Per-IP /mcp request limit. Keep high enough for router-backed discovery bursts; /healthz and /readyz are excluded. |
Tools reference
load_skill — the skill dispatcher
Skills are not exposed as per-skill load tools. A single dispatcher loads any skill's guidance by name.
- Name: call
load_skill. Skill names are now flat kebab-case (e.g.code-quality-tdd,workflow-discover) — no slashes, no__. - Compatibility alias: call
load_skillwith the same params if a client does not exposeload_skillor collides on that generic tool name. - Router-only fallback: if the client exposes only CentralCloud router
tools, call
mcp_tool_call(server=purpose_agent_tools, tool=purpose_agent_tools_load_skill, arguments={name,task?}). Do not hardcode promoted wrapper names such aspurpose_agent_tools__purpose_agent_tools_load_skill; direct wrapper names are client/session-specific. - Params:
name(required string — a skill name, or a backward-compatible alias, fromlist_skillsor the catalog in this tool's description) andtask(optional free-form context). - Returns: the full
SKILL.mdbody as text and asstructuredContent.guidancefor routers that surface structured output; an unknownnamereturns an error result. - Annotations:
readOnlyHint: true,idempotentHint: true,destructiveHint: false,openWorldHint: false. - Discovery:
load_skill's description embeds the whole catalog (- <name> (aliases: …): <when-to-use>);list_skillsreturns the grouped index (each entry'snameis what you pass); skill packages are also MCP resources atskill://purpose_agent_tools/<name>/…and enumerated inskill://index.json.
Skills follow the agentskills.io Agent Skills
standard: the only standard top-level frontmatter fields are name and
description. Any extra metadata lives in an optional free-form metadata:
map. Our two discovery keys live there:
---
name: <skill-name>
description: Use when <trigger phrases...>
metadata:
category: <category>
origin: <origin>
---
metadata.category: drives the grouping inlist_skillsand the generated instruction index.metadata.origin: provenance for review and distribution.
list_skills is the authoritative runtime skill index. It returns
{bundleHash, categories} where each entry includes name, description,
aliases, category, origin, hash, and toolName (always load_skill).
Use the entry name or one of its aliases as the load_skill.name argument.
If load_skill is not exposed by the client, call it through the router with
mcp_tool_call(server=purpose_agent_tools, tool=purpose_agent_tools_load_skill, arguments={name}).
Do not maintain a separate static skill table in docs; it
will drift from the MCP registry.
Utility tools
| Tool | Params | Returns |
|---|---|---|
initial_instructions |
none | Current Purpose-First MCP bootstrap instructions, preferred skill loader, fallback skill/file tools, resource-tool names, registered skill count, instruction bundle hash, and instruction block hash. Use when a client missed or truncated MCP initialize instructions. |
list_skills |
none | {bundleHash, categories: {category: [{name, toolName, description, aliases, category, origin, hash}]}}. The machine-readable skill index; toolName is load_skill, and name/aliases are valid load_skill.name values. hash/bundleHash drive versioned self-install. |
skill_manifest |
name |
One skill package manifest with skill:// resource URIs for SKILL.md and auxiliary files such as templates, examples, scripts, references, and assets. |
skill_file_read |
name, path |
One hosted skill package file. Use when MCP resources are hidden, unavailable, or routed through a tool-only gateway. |
install_skills |
names? (string[]) |
{bundleHash, instructionsHash, installInstructions, installSteps, skills: [{name, hash, files: [{path, content}]}], agentsBlock: {begin, end, hash, body, full}} — full skill packages for versioned self-install: raw SKILL.md with frontmatter + all auxiliary files (references/, templates/, scripts/, assets/), each path prefixed with the skill name; plus explicit ordered install steps and a Beads-pattern managed instruction-file block (agentsBlock.full = begin+body+end, HTML markers carrying bundleHash, body carrying instructionsHash). Default all; names selects a subset, bundleHash + agentsBlock always full-bundle. Content comes from the in-memory registry, never re-read from disk. The agent must get user consent and verify the bundleHash/content before writing files or merging the block; the server ships no hooks. |
server_info |
none | Full capability matrix, registered skill count, redteam mode list, transport info, and lazy self-update metadata. |
check_update |
none | {packageName,currentVersion,latestVersion,registry,status,updateAvailable,restartRequired,updateCommand,checkedAt,error?} from the npm registry. This is an npm-backed stdio freshness check only, not a cluster-image check. status:"unknown" with updateAvailable:null means the registry check failed or the registry metadata is older than the running package; read-only; never restarts the running server. |
server_logs |
none | Recent server log lines (redacted) + registered skill count + redteam modes — debug the MCP server itself over MCP. |
redteam_run |
mode, input, focus?, extra_args? |
Cross-model prepared-opposer panel gate. input may be an existing file/directory path or direct prose text; missing path-like inputs still error. Returns structured verdict + jobId for redteam_job_trace / redteam_job_result. |
redteam_list_jobs |
none | Recent panel jobs (id, kind, status, elapsed, summary). |
redteam_job_trace |
jobId, maxLines? |
A job's panel.log trace tape (redacted) — pull-based span/debug read. |
redteam_job_result |
jobId |
A job's stored final panel result. |
Redteam modes (redteam_run.mode)
| Mode | Description |
|---|---|
review |
General code/design review panel |
plan |
Adversarial plan review |
decision |
Architecture or approach decision review (ADR) |
bughunt |
Codebase-wide bug hunt |
architect |
Architecture adversarial review |
verify |
Verify a fix or validate a finding |
hack |
Adversarial attack-surface exploration |
ultrareview |
Deep multi-lens FIND -> VERIFY -> DEDUPE sweep |
harvest |
Harvest findings/patterns from a codebase |
Redteam tools:
- Params:
input(string, required) — absolute path to the file, plan, or directory under review.focus(optional enum) — one ofsecurity,performance,correctness,ux,all. If omitted, the tool elicits the focus from the operator (falling back toall). Free-form strings are rejected; put detailed review instructions ininput.extra_args(optionalstring[]) — extra flags passed straight topanel.mjsthrough the wrapper allowlist (for example["--models", "qwen,deepseek"]or["--package", "audit"]).
- Returns: structured content
{verdict, findings[], raw, jobId}plus the panel stdout as text when the panel finishes quickly. Long panels return early withverdict: Redteam <mode> running, empty findings, andjobId; pollredteam_job_trace/redteam_job_resultfor the final verdict. When a final verdict is returned directly,verdictis the panel verdict (random family), the runsummary(bughunt/ultrareview), or a synthesized mode + count line (scatter).findingsis the normalized list of findings across the mode's report shape, each rendered as[severity] title (file:line).jobIdis the background job id — pass it to the debug/trace tools below to pull the trace tape or stored result. - Annotations:
openWorldHint: true(they call external model providers). - Long-running: the panel may run for 30–120 s, but MCP calls return a job handle shortly after startup when the panel is still running. Progress notifications are emitted while the call is open.
- Keys required:
XAI_API_KEY,GEMINI_API_KEY,OPENAI_API_KEY(or whichever providers the panel is configured to use).
Debug / span-trace tools (pull-based)
Read panel job state, debug tapes, and the server's own logs over MCP — no Laminar export. The trace tape is each job's redacted run record, read from the job registry.
| Tool | Params | Returns |
|---|---|---|
redteam_list_jobs |
none | JSON list of recent panel jobs (id, kind, status, elapsed, summary). openWorldHint: true (reads the live job store). |
redteam_job_trace |
jobId (string), maxLines? (number, default 200) |
The job's panel.log trace/tape (redacted) — the span/debug read. |
redteam_job_result |
jobId (string) |
The job's stored final panel result. |
server_logs |
none | Recent server log lines (redacted) + registered skill count + redteam modes — debug the MCP server itself over MCP. |
All four are readOnlyHint: true, idempotentHint: true.
Debug / trace resources
Templated, read/subscribe-able URIs for the same per-job data:
| Resource URI | MIME | Content |
|---|---|---|
redteam-job://<id>/trace |
text/plain |
The job's redacted trace tape. |
redteam-job://<id>/result |
application/json |
The job's stored final panel result. |
Client config
For local stdio clients, prefer npm-backed launch over a repo-local path:
{
"mcpServers": {
"purpose_agent_tools": {
"command": "npx",
"args": ["-y", "--prefer-online", "@centralcloud/purpose-agent-tools@latest"]
}
}
}
check_update reports npm-backed stdio package freshness only. It does not
validate the CentralCloud cluster image, which is built and repinned through the
Nix container workflow. The stable stdio shim can restart its worker after
rebuilt local code changes, but it cannot replace the npm package already
selected by npx; reconnect/restart the MCP server so npx resolves the
latest package on process start. Current Codex CLI releases expose
codex mcp list/get/add/remove/login/logout; they do not expose a
codex mcp restart command.
Copilot CLI (~/.copilot/mcp-config.json)
{
"mcpServers": {
"purpose_agent_tools": {
"url": "http://127.0.0.1:8931/mcp",
"headers": { "X-Request-Id": "copilot-cli" }
}
}
}
Claude Code (~/.claude/mcp.json)
{
"mcpServers": {
"purpose_agent_tools": { "url": "http://127.0.0.1:8931/mcp" }
}
}
Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"purpose_agent_tools": { "url": "http://127.0.0.1:8931/mcp" }
}
}
Gemini CLI (~/.gemini/settings.json)
{
"mcpServers": {
"purpose_agent_tools": { "url": "http://127.0.0.1:8931/mcp" }
}
}
CentralCloud deploy
Forgejo CI builds the Nix container and pushes latest, git-<sha>, and the
root package.json semver tag to
registry.infra.centralcloud.com/centralcloud/purpose-agent-tools-mcp.
The live CentralCloud deployment is the purpose-agent-tools sidecar in
/srv/infra/clusters/default/tenants/centralcloud/apps/centralcloud-mcp-gateway/deployment.yaml.
CI repins it through /srv/infra/scripts/update-purpose-agent-tools-image.sh;
manual infra promotion follows /srv/infra/docs/runbooks/internal-image-promotion.md.
Service URL inside the gateway pod:
http://127.0.0.1:8931/mcp.
Tests
nix develop --command pnpm run test
23 test files covering:
tests/skills.test.ts— frontmatter parsing, missing-name skiptests/logging.test.ts— RFC 5424 level filteringtests/redteam.test.ts— mode schema validationtests/hot-reload.test.ts— chokidar add/change event capturetests/stdio-shim.test.ts— stable stdio shim restarts a changed workertests/server.test.ts—buildServerregistered tool counttests/http.test.ts— supertest-driven /healthz, /readyz, /info
Hard rules
- Read-only by default. Skill tools are read-only; redteam tools are read-only (they shell out to a read-only review process). No tool in this server mutates state.
- Open-world on redteam.
openWorldHint: truebecause cross-model panels hit external model providers. - Idempotent skills. Tool annotations advertise
idempotentHint: true. - Logging on every state change. RFC 5424 levels, structured JSON.
- No secrets in the container. Image contains no API keys; the server reads them from the environment at runtime (operator's responsibility).
Known limitations (v0.1)
check_updatecan detect npm package drift for stdio clients, but a running stdio shim still requires a client reconnect/restart before npm can launch the newer package. If npm registry metadata is older than the running package, the check reportsstatus:"unknown"instead of treating the registry as source of truth. Cluster image freshness is verified through GitOps/image state, not this npm check.- Hot-reload refreshes skill bodies,
list_skills, resources, and the explicitinitial_instructionstool. The MCP initialize-timeinstructionssnapshot is still fixed for the life of the connection; callinitial_instructionsafter listChanged/staleness notices to fetch the current bootstrap text. redteam_runandredteam_*alias tools require API keys for the model providers. The bundled redteam runsscripts/panel.mjs, which reads keys from the environment (e.g.,XAI_API_KEY,GEMINI_API_KEY,OPENAI_API_KEY). Configure these via ExternalSecret or envFrom in the helm chart.- No auth on the HTTP transport — relies on the CentralCloud auth proxy or k8s NetworkPolicy for ingress control. Add OAuth / OIDC for public deployment.
Credits
The Purpose-First skillset is forked and evolved from Superpowers by Jesse Vincent (@obra) — https://github.com/obra/superpowers (MIT, Copyright © 2025 Jesse Vincent). If Superpowers helps you, Jesse appreciates sponsorship.
These started from Superpowers and have since diverged substantially (not a
verbatim vendor — e.g. writing-skills, systematic-debugging, brainstorming,
and writing-plans are largely rewritten), so we maintain them as our own fork:
- Adapted from Superpowers (Obra):
brainstorming,dispatching-parallel-agents,executing-plans,finishing-a-development-branch,receiving-code-review,requesting-code-review,subagent-driven-development,systematic-debugging,test-driven-development,using-git-worktrees,using-skills(fromusing-superpowers),verification-before-completion,writing-plans,writing-skills. - Purpose-First-original (this project):
purpose-first(the 9-field purpose contract that the others now reference),quality-contracts,instruction-writing,human-writing,existing-capability-first,redteam,redteam-result-handling.
purpose-first is the umbrella discipline (purpose + falsifier for any change);
test-driven-development is the code-specific red-green practice nested under it — both
are kept intentionally.
The managed AGENTS.md/CLAUDE.md block (HTML BEGIN/END markers carrying a
version/hash, replace-between-markers idempotency, multi-tool coexistence) follows the
marker pattern from Beads by Steve Yegge.
License
MIT. Forked skill content adapted from Superpowers carries its original MIT license (Copyright © 2025 Jesse Vincent); see https://github.com/obra/superpowers.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @cfworker/json-schema | ^4.1.1 |
| @modelcontextprotocol/node | 2.0.0-alpha.3 |
| @modelcontextprotocol/server | 2.0.0-alpha.3 |
| ajv | ^8.20.0 |
| chokidar | ^3.6.0 |
| cors | ^2.8.5 |
| execa | ^9.6.1 |
| express | ^4.21.0 |
| express-rate-limit | ^7.4.0 |
| gray-matter | ^4.0.3 |
| helmet | ^7.1.0 |
| hono | ^4.12.26 |
| jsonrepair | ^3.14.1 |
| smol-toml | ^1.7.0 |
| uuid | ^10.0.0 |
| zod | ^4.4.3 |
Development dependencies
| ID | Version |
|---|---|
| @types/cors | ^2.8.17 |
| @types/express | ^4.17.21 |
| @types/node | ^22.7.0 |
| @types/supertest | ^6.0.2 |
| @types/uuid | ^10.0.0 |
| @typescript/native-preview | 7.0.0-dev.20260626.1 |
| esbuild | ^0.28.1 |
| prettier | ^3.9.4 |
| proper-lockfile | ^4.1.2 |
| supertest | ^7.0.0 |
| typescript | ^5.6.0 |
| vitest | ^2.1.0 |