warden
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| vet_mcp_serverA | Run WARDEN's ordered gate chain (static-scan → threat-feed → origin → pinning) over a server identity plus its advertised tools/list payload and return a recordable verdict (allow/block, 0..1 product score, findings, allowedTools/blockedTools, ruleset digest). When to use: you have a complete server record and want the same decision a host should make before any of those tool definitions reach the model. Prefer this over calling the four gates yourself. When NOT to use: inspecting descriptions only (call static_scan_tools — no origin/pinning); splitting tools by operator glob (classify_sensitive_tools); checking one outbound URL (check_egress_url); producing RFC 8785 bytes (canonicalize_json). Behaviour: local, deterministic, no network. This stdio process uses the built-in 11-record threat floor (it does not fetch a signed feed) and a durable local pin store. First contact is TOOL_DEF_UNPINNED/advisory until explicitly approved. Origin defaults to allowUnknownServers=true so catalog-discovered servers are not fail-closed. Override policy when you need the host's real knobs. Does not connect to, start, or approve the target server. Returns structured JSON matching outputSchema. Example: vet_mcp_server({ server: { id: "demo@0", name: "demo", transport: "stdio", command: "npx" }, tools: [{ name: "add", description: "Add two integers.", inputSchema: { type: "object" } }] }). |
| static_scan_toolsA | Run only the static-scan gate (ruleset v14, 36 signatures with context guards, text folded first) over every advertised tool field: name, description, input schema, title, output schema, annotations and extension metadata. Returns findings, a 0..1 gate score, and the published ruleset digest. When to use: you have a tools/list dump and want injection / credential / hidden-Unicode hits without origin, pinning, or the threat feed. Cheaper and narrower than vet_mcp_server. When NOT to use: you need the full host decision (vet_mcp_server); you want operator glob classification (classify_sensitive_tools); you want the published rule table itself (list_scan_rules). Behaviour: local regex+guard evaluation, no network, no mutation. Advisory-tier hits are reported with advisory=true and do not reduce the score. Does not launch servers or send tool output to a model. Returns structured JSON matching outputSchema. Example: static_scan_tools({ tools: [{ name: "add", description: "Add two integers.", inputSchema: { type: "object" } }] }). |
| classify_sensitive_toolsA | Split advertised tool names into sensitive vs safe using the operator's case-insensitive * globs (the same policy.sensitiveToolPatterns a host would use). Sensitive tools stay advertised; they require per-call approval — this tool does not run them. When to use: show the user which names will need confirmation before they approve a server, or to preview a glob set. This is policy over identifiers, not an injection scan. When NOT to use: scanning descriptions for poisoning (static_scan_tools or vet_mcp_server); checking whether a URL is allowed out (check_egress_url). Behaviour: local glob match, no network. An empty patterns array marks every tool safe. Patterns match the whole name; "delete" hits create_delete_repo. Does not call Warden.vet and does not persist anything. Returns { sensitive, safe }. Example: classify_sensitive_tools({ tools: [{ name: "delete_repo", description: "Delete a repository.", inputSchema: { type: "object" } }], patterns: ["delete"] }). |
| check_egress_urlA | Ask EgressGuard whether a URL's hostname is on an operator allowlist. A tool reaching a host you never listed is the classic phone-home tell. Empty allowlist blocks everything (fail-closed), not everything-allowed. When to use: a tool is about to fetch/post and you want the same check a host should wrap around that request. Hostnames match case-insensitively; "*.example.com" matches subdomains, not the apex. When NOT to use: vetting tool definitions (vet_mcp_server / static_scan_tools); canonicalizing JSON (canonicalize_json). This does not fetch the URL and does not inspect tool text. Behaviour: local URL parse + hostname match. Unparseable URLs are refused. No DNS, no HTTP. Idempotent. Returns { allowed, host?, reason? }. Example: check_egress_url({ url: "https://api.github.com/repos", allowlist: ["api.github.com", "*.internal.example.com"] }). |
| canonicalize_jsonA | Return the RFC 8785 JSON Canonicalization Scheme serialization WARDEN uses for threat-feed signatures and tool-def pins, so another implementation can byte-check against it. Integers only inside ±(2^53−1); lone surrogates and non-integers are refused with a reason code, not escaped. When to use: you are publishing or verifying a signed threat feed, hashing tool defs, or comparing two JSON documents that must agree regardless of key order. Subpath @aimarket/warden/jcs is the same function. When NOT to use: scanning tool defs (static_scan_tools); pretty-printing for humans (this output is for bytes, not display). Behaviour: local, no network. Pass either a parsed JSON value or a JSON string (string is parsed with parseJsonStrict first). Failure returns isError with CanonicalizationCode — it does not emit partial bytes. Returns { canonical } or an error. Example: canonicalize_json({ value: { b: 1, a: 2 } }) → {"a":2,"b":1}. |
| list_scan_rulesA | Return the in-force static-scan ruleset: version, digest, and every rule's code, severity, tier (block vs advise), surfaces (name / description / inputSchema / title / outputSchema / annotations / metadata), optional regex source, and named guards. A recorded verdict is only reproducible together with this identity. When to use: explain a finding code, confirm you are on ruleset v14, or re-run a scan with the same table. include_source=true adds the regex source and flags for an independent re-implementation. When NOT to use: evaluating a live tools/list (static_scan_tools or vet_mcp_server — those apply the table). This tool does not scan anything. Behaviour: local snapshot of the compiled rule table, no network, no mutation. Digest is sha256 over the RFC 8785 form of {version, fold, rules} (each rule carries its Returns the ruleset object. Example: list_scan_rules({ include_source: false }). |
| status_mcp_serverA | Read the approval WARDEN has stored for one server id and compare it with the tools/list payload and launch identity you pass in. Returns the stored approval (or null), its revision, the hashes of what you passed, whether they differ, what changed field by field (words added and removed in descriptions, schema values before and after, changes made only of numbers marked), and whether this process may change approvals at all. When to use: before an operator decides to approve or revoke a server, to see what changed since the last approval; show the operator reviewText. It is the only source of the values approve_mcp_server and revoke_mcp_server ask for (currentToolsHash, currentIdentityHash, previousRevision). When NOT to use: deciding whether a server is safe to expose (vet_mcp_server runs every gate; this tool runs none). It does not scan descriptions and never blocks. Behaviour: read-only. Reads one file from the local state directory (WARDEN_STATE_DIR, default ~/.local/state/warden/pins); writes nothing, no network, never starts the target server. Works whether or not WARDEN_ALLOW_PIN_CHANGES is set. Returns structured JSON matching outputSchema. Example: status_mcp_server({ server: { id: "demo@0", name: "demo", transport: "stdio", command: "npx" }, tools: [{ name: "add", description: "Add two integers.", inputSchema: { type: "object" } }] }). |
| approve_mcp_serverA | Store an operator approval for exactly the tool definitions and launch identity the operator reviewed, so later vet_mcp_server calls treat them as approved and report any change as drift. The server must still pass every WARDEN gate; an approval cannot override a block. When to use: after a human reviewed the output of status_mcp_server and agreed. Pass back the currentToolsHash, currentIdentityHash and previousRevision it returned; if the payload or the stored approval changed in the meantime, the call is refused and the review must be repeated. When NOT to use: on your own initiative or to make a blocked server pass (the gates run again and the call fails); to remove an approval (revoke_mcp_server); to look at the stored state (status_mcp_server). Behaviour: writes one file in the local state directory and replaces any earlier approval for this server id. Refused unless the operator started this process with WARDEN_ALLOW_PIN_CHANGES=1. No network; never starts the target server. Repeating the same call is refused because the revision it names is no longer current. Returns { approved: true, pin }. Example: approve_mcp_server({ server, tools, reviewed_tools_hash: "", reviewed_identity_hash: "", previous_pin_revision: null }). |
| revoke_mcp_serverA | Delete the stored approval for one server id. Afterwards vet_mcp_server treats the server as never seen: its tools are unpinned again until someone approves them anew. When to use: an operator no longer trusts a server, or wants its next approval to start from a clean review. Take previousRevision from status_mcp_server first; the call is refused if the approval changed after that. When NOT to use: to approve a changed server (approve_mcp_server replaces the old approval directly); to block a server for everyone (a revoked server is unpinned, not blocked — use a threat feed or policy for that); to inspect state (status_mcp_server). Behaviour: deletes one file in the local state directory; cannot be undone except by approving again. Refused unless the operator started this process with WARDEN_ALLOW_PIN_CHANGES=1. Needs no tools payload. No network. Returns { revoked: true, serverId }. Example: revoke_mcp_server({ server: { id: "demo@0", name: "demo", transport: "stdio", command: "npx" }, previous_pin_revision: "" }). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 9 tools
Each tool has a clearly distinct purpose, and the descriptions go further by including explicit 'When NOT to use' sections that cross-reference the alternatives, e.g. static_scan_tools vs vet_mcp_server (single gate vs full chain), list_scan_rules (the table) vs static_scan_tools (applying it), and classify_sensitive_tools (operator globs) vs scanning. The pin lifecycle trio (status/approve/revoke) is cleanly separated by read/write/delete semantics.
Most names follow a predictable verb_object pattern: check_egress_url, canonicalize_json, classify_sensitive_tools, list_scan_rules, vet_mcp_server, approve_mcp_server, revoke_mcp_server. A couple deviate — status_mcp_server lacks a verb (would be get_mcp_server_status) and static_scan_tools is adjective_verb_noun — but the convention is still readable and largely uniform.
Nine tools is well-scoped for a vetting/pinning server. Each earns its place: the individual gates, the full chain, the ruleset snapshot for reproducibility, the canonicalization helper, operator glob classification, and the three-verb pin lifecycle.
The pin lifecycle (status/approve/revoke) is complete and CRUD-like, and the scanning/gate surface is thoroughly covered with reproducible identity (ruleset digest, canonicalization). Minor gaps: no tool to enumerate all stored approvals/servers in one call, and no explicit threat-feed management tool (the stdio process uses a built-in floor), though agents can work around both.