Skip to main content
Glama

veilform

Let an AI agent ask for, store and use credentials — without ever seeing them.

Español · Threat model · Security policy · Changelog

veilform is an open-source Model Context Protocol server (stdio, TypeScript). When the agent needs an API key, a password or any sensitive data, it sends only metadata (a form schema). A page served on http://127.0.0.1 opens in your browser; you type the values there; they go straight to a destination you configured (OS keychain, encrypted file, .env, remote server over SSH, Vault/Infisical/1Password/OPS, an HTTP API, a Postgres table…). The agent only gets back {request_id, status, stored:[names]}.

Later the agent says ${secret:STRIPE_KEY} and this server resolves it inside its own process, at the moment of use, after you approve the exact action on another local page.

 agent ──metadata──▶ veilform ──opens──▶ http://127.0.0.1:PORT/p/<one-time token>
   ▲                       │                                  │ you type values
   │  names / status       │◀──────────── values (local) ─────┘
   └───────────────────────┤
                           ├──▶ keychain / encrypted file / .env / ssh / Vault / Infisical / 1Password / OPS
                           ├──▶ secret_use: exec / http with ${secret:x}  (approval page shows the literal action)
                           └──▶ secret_write: .env, JSON/YAML, systemd, GitHub Actions, clipboard

Tools

Tool

What the model sends

What the model gets

secret_request

title, fields (secret/text/select/textarea), destination

{request_id, status, stored}

blind_input

rich schema (sections, number/money/date/select/multiselect/boolean/file, showIf, repeaters with CSV/spreadsheet paste) + sink (store, http, sql, file, ops-dataload, callback)

{status, rows_written, ids, field_errors:[{field, code}]}

blind_input_preview

schema (+ sink)

validation result + local mock-up URL

secret_list / secret_delete / secret_rotate

name / filters

names + metadata (created, last used, expiry, rotation due, tags, project)

secret_use

exec (argv or approved shell) / http, with ${secret:name}

exit code + redacted output

secret_write

names + target (env-file local/SSH, json, yaml, systemd, github, clipboard), dry_run

{written, target, keys:[{key, action: created/updated}]}

secret_wait

id

final structural result

web_capture / web_login

site, steps (navigate/click/wait/fill/press), extractor

{stored:[name]} or {failed_step, error_code} — never page text

ssh_key_provision / ssh_exec

host alias, key alias / command + env with ${secret:x}

fingerprints, access test / redacted output

Related MCP server: PhantomAuth

Install

Requirements: Node ≥ 20.11. Linux needs secret-tool (package libsecret-tools) for the keychain destination; macOS uses the built-in security. Optional: playwright-core + Chromium for web_capture, psql for SQL sinks, gh for GitHub secrets, OpenSSH for SSH features.

# from a clone (not published to npm yet)
pnpm install && pnpm build

# Claude Code
claude mcp add veilform -- node /path/to/veilform/dist/cli.js
# once published:  claude mcp add veilform -- npx -y veilform

Optional environment: VEILFORM_HOME (default ~/.config/veilform), VEILFORM_CONFIG, VEILFORM_AGENT (label written to the audit log).

Configuration is an allowlist: copy examples/config.example.json to ~/.config/veilform/config.json and keep only what you need. Without a config file there is one destination, local (OS keychain). Check it with veilform check-config.

Recommended Claude Code hardening (.claude/settings.json): deny the agent's own tools access to what this server protects, e.g. "deny": ["Read(~/.config/veilform/**)", "Bash(secret-tool:*)", "Bash(security:*)", "Read(**/.env)"].

Examples

Stripe key, then a call:

“I need your Stripe secret key.” → secret_request({title:"Stripe", fields:[{name:"STRIPE_KEY", label:"Secret key", pattern:"sk_(live|test)_[A-Za-z0-9]+"}]}) → you paste it in the local page → {stored:["STRIPE_KEY"]} → secret_use({action:"http", method:"GET", url:"https://api.stripe.com/v1/balance", headers:{Authorization:"Bearer ${secret:STRIPE_KEY}"}}) → approval page shows exactly that request → {http_status:200, body:"…"} (the key is redacted if the API echoes it).

Mercado Pago token to production .env over SSH:

{"name":"MP_ACCESS_TOKEN","target":{"kind":"env-file","host":"prod-vps","path":"/etc/myapp/myapp.env","key":"MP_ACCESS_TOKEN"},"dry_run":true}

→ {changes:[{key:"MP_ACCESS_TOKEN", action:"updated"}]}; without dry_run, after your approval, the server reads the remote file over SSH, changes only that key (comments and other keys kept), uploads it on stdin to a temp file, chmod 0600, optional chown/backup, and mv atomically. The model gets {written:true, target, keys}.

Capture the token from the Mercado Pago panel without the model seeing it: web_capture({site:"mercadopago", name:"MP_ACCESS_TOKEN", steps:[{wait:"text=Credenciales de producción", timeout_ms:600000},{click:"text=Mostrar"}], extract:{selector:"[data-testid=access-token]", regex:"(APP_USR-[\\w-]+)"}}) — a Chromium window owned by this server opens; you log in (password/2FA never touch the model); you can edit the steps on the approval page; the value goes DOM → store.

SSH key for a new VPS: ssh_key_provision({host:"prod-vps", alias:"deploy_key", password:true}) → the page shows the host-key fingerprint to compare with your provider, asks the one-time root password, installs the public key, tests access. Then ssh_exec({host:"prod-vps", command:"systemctl restart myapp"}).

Batch of USD prices into Postgres: blind_input with a repeater rows:[sku, price(money USD)] and sink {type:"sql", database:"appdb", table:"public.product_prices", mode:"upsert", rows:"rows", columns:{sku:"${sku}", price_usd:"${price}", list:"wholesale"}, dry_run:true}. You paste the rows from a spreadsheet; values travel as COPY … FROM STDIN data into a typed temp table and INSERT … SELECT in one transaction; the model gets {rows_validated: 120} and then {rows_written:120, ids:[…]}.

Sensitive customer data: blind_input with fields name, email, rfc (pattern), phone and an http sink to your CRM; the model receives only the created ids.

Security flow

  1. The model calls a tool with metadata only. Destinations, hosts, paths, tables, sites must be in your config.

  2. A one-time link http://127.0.0.1:<port>/p/<256-bit token> is delivered by MCP URL elicitation when the client supports it, otherwise returned for the client/agent to show (and opened with xdg-open/open if ui.openBrowser). The first browser that opens it binds it with an HttpOnly cookie; it expires in 10 min.

  3. You fill/approve. CSRF token + Origin/Host checks + strict nonce CSP; nothing third-party; no autocomplete.

  4. Values go to the destination from this process (stdin/env, never argv; never logged).

  5. Tool results are structural; a last-line scrub removes any handled value and its encodings.

  6. Every use is audited (hash-chained JSONL: session, agent, client, action, fingerprint, names). veilform verify-audit checks the chain.

Read THREAT-MODEL.md for what is not protected — notably: an approved command that exfiltrates the value, same-user malware, and using another browser the model can see (e.g. a browser extension the agent drives) to open a page that shows a secret.

Development

pnpm install
pnpm typecheck && pnpm lint && pnpm test   # vitest: unit, property, simulated APIs, sshd loopback, Postgres (docker) if available
pnpm test:e2e                              # Playwright: form, repeater/CSV, approval, clipboard, preview, single-use link
SHOTS_DIR=/tmp/shots pnpm test:e2e         # also writes screenshots

Deviations from the original design brief (documented): the keychain uses the platform CLIs instead of @napi-rs/keyring (no native addon); encrypted-file uses Node's AES-256-GCM + scrypt instead of age/libsodium; property tests use a small seeded PRNG instead of fast-check. All three because the build had to work offline with the cached dependencies, and they keep the runtime dependency list to the MCP SDK and zod.

License

MIT

Available Tools

13 tools
blind_inputCollect any values blindly (forms, tables, CSV)A

Generic blind input: send ONLY a schema (sections, typed fields, validations, showIf conditions, repeaters/tables with CSV import) and a sink (store, http, sql, file, ops-dataload, callback). The person fills the local page; values go directly to the sink. You receive {request_id, status, rows_written, ids, stored, keys, field_errors:[{field, code}]} and never values. Non-store sinks need the person's explicit approval on the same page (it shows the template with ${field} placeholders). Use blind_input_preview first to validate a complex schema.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinkYes
titleYes
schemaYes
metadataNo
descriptionNo
submit_labelNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does it well: it discloses that values never reach the agent, that only metadata ({request_id, status, rows_written, ids, stored, keys, field_errors}) is returned, and that non-store sinks surface a template with ${field} placeholders requiring the person's approval. These are exactly the behavioral facts an agent needs for a no-annotation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the core mechanic and closing with the preview recommendation. Dense but every sentence carries information; only the sink enumeration slightly bloats the opener.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, deeply nested tool with no output schema, the description supplies the return shape and the approval behavior, which is essential. It omits any mention of metadata/expiry or size limits, a minor residual gap against the very large schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does for the two key parameters: it enumerates schema capabilities (sections, typed fields, validations, showIf, repeaters with CSV import) and sink types (store, http, sql, file, ops-dataload, callback). It adds no meaning for metadata, description, or submit_label, leaving those to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: send a schema and a sink to collect values blindly, with a named list of sink types. It distinguishes itself from the sibling blind_input_preview and from value-returning tools by emphasizing 'you never receive values,' so an agent can tell what this tool is for without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operational guidance: 'Use blind_input_preview first to validate a complex schema' and notes that non-store sinks require explicit approval on the page. It lacks explicit when-not guidance relative to other capture siblings like secret_request or web_capture, so no full alternatives mapping.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

blind_input_previewValidate a blind_input schemaB
Read-only

Validates a schema (and optional sink) and returns a structural summary plus a local preview URL with a disabled mock-up of the form. No values involved.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinkNo
titleNo
schemaYes

TDQS

B3.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already establishes the safety profile, but the description adds real context beyond it: the tool performs validation only, no input values are collected or sent, and the mock-up form is explicitly disabled. It does not describe failure behavior (what a structural summary contains when validation fails), which keeps it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two lean sentences with the verb front-loaded and no padding; both sentences carry information. Slightly terse for the depth of what is being validated, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a 3-param, deeply nested schema and no output schema, the description does explain the return shape at a high level (summary + preview URL), which is the key missing piece without an output schema. However it says nothing about validation semantics, error reporting, or the sink configuration space, leaving the agent under-informed for a complex input.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% top-level schema description coverage, the description must carry the load but only mentions 'a schema (and optional sink)' — two of three parameters, omitting title entirely. It gives no guidance on the sink variants (store/http/sql/file/systemd/github/clipboard/ops-dataload/callback) that dominate the nested schema, so the parameter meaning gap remains large.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Validates a schema') and the concrete artifacts returned ('structural summary plus a local preview URL with a disabled mock-up of the form'). It never names the sibling blind_input, so an agent must infer that this is the safe preview counterpart rather than the real submission tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use statement, no prerequisites, and no routing against siblings such as blind_input or secret_write. The phrase 'No values involved' hints that this is a non-committal dry-run, but the agent is left to infer that it should be called before creating an actual form.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_deleteDelete a stored secretB
Destructive

Deletes a secret by name (optionally only from one destination).

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
destinationNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, so the agent knows this is a destructive operation. The description usefully adds that deletion can be scoped to a single destination ('optionally only from one destination'), which is meaningful context beyond the annotation, but it says nothing about irreversibility, permissions, or effects on other destinations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with the scope qualifier folded into a parenthetical. Nothing is wasted and the core action is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a destructive mutation tool with no output schema and 0% parameter description coverage, so the description should carry more weight. It leaves open whether the deletion is reversible, what happens if the named secret or destination does not exist, and how the destination scope interacts with the name.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the param burden. It does map both parameters at a basic level ('by name' for name, 'only from one destination' for destination), but provides no format, syntax, or default details, so it only partially compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Deletes a secret by name'), which is precise and unambiguous. It does not, however, explicitly differentiate itself from sibling mutation tools like secret_rotate, secret_write, or secret_use, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives such as secret_rotate or secret_write, and no prerequisites or exclusions are stated. The parenthetical only clarifies scope, not when-to-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_listList stored secrets (names only)A
Read-only

Lists secret names with metadata (destination, created/updated/last used, expiry, rotation due, tags, project) and what this server is allowed to use (destinations, ssh hosts, databases, web sites, write targets). Never values.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNo
projectNo
destinationNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=true; the description adds the material disclosure that values are never returned and enumerates the metadata and allowed-usage surfaces that are returned. It does not cover auth/permission requirements or result limits, but the 'never values' guarantee is real added context beyond the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded with the core action and closed by the key constraint 'Never values'. The long parenthetical of metadata fields is dense but every item earns its place in describing the return surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully documents what is returned and explicitly excludes secret values, and the read-only annotation covers safety. However, it leaves the three filter parameters unexplained, which is a meaningful gap for a tool an agent will use to scope down secrets.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden for tag, project, and destination. It names all three, but frames them as returned metadata rather than as filters, which leaves their input semantics ambiguous and potentially misleading for an agent trying to narrow results.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (lists) and resource (secret names) plus the scope boundary 'Never values', which immediately separates it from secret_use/secret_request. An agent can tell it apart from siblings like secret_delete or secret_rotate without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: listing is naturally the discovery step before secret_use or secret_request, but the description never states when to prefer this tool or which sibling to use instead. No exclusions or prerequisites are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_requestAsk the person for credentialsA

Opens a LOCAL page (http://127.0.0.1) with the given fields so the person can type API keys, tokens or passwords. Values go straight from the browser to the configured destination (OS keychain, encrypted file, .env, remote store...). Returns {request_id, status, stored:[names]} (plus url when the client cannot open it: show the url to the person, then call secret_wait). Use the stored names later as ${secret:name}. You will NEVER receive secret values: only names, statuses, counts, ids and fingerprints. Do not ask the person to paste secrets in chat; use these tools instead. Do not try to read the stores, the .env files written by this server, or the veilform directory with other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
fieldsYes
metadataNo
descriptionNo
destinationNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover openWorldHint=false and destructiveHint=false, so the description carries the real burden and delivers: values flow browser-to-destination directly, the agent never sees secret values, only names/statuses/counts/ids/fingerprints. It also discloses the return shape and the URL fallback path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, then behavior, return shape, and restrictions; every sentence carries information. It is dense but not padded, though slightly long.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the return shape and the workflow around it, plus safety constraints. The remaining gap is the parameter-level detail of fields and destination, which the description leaves to an undocumented schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 5 parameters with nested objects, so the description must compensate and largely does not. It hints at the field content (API keys/tokens/passwords) and the destination concept, but never explains the fields item shape (name/label/kind/help/options/pattern/required), destination formats, or the metadata expiry/rotation options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it opens a LOCAL page at 127.0.0.1 for a person to type API keys, tokens or passwords. The scope (human-facing credential capture) is unmistakable and clearly distinct from siblings like secret_write and secret_list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use these tools instead of asking the person to paste secrets in chat, call secret_wait when the client cannot open the URL, and reference stored names later as ${secret:name}. It also gives negative guidance (do not read the stores or .env files).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_rotateAsk the person for a new value of an existing secretA

Re-opens the intake page for an existing secret (same label, destination and metadata). Use when secret_list shows expired or rotation_due.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
titleNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden. It usefully reveals this is a human-interactive flow (re-opening an intake page, 'ask the person') and that only the value changes while label/destination/metadata persist. However, it never says whether this blocks, whether the old value is destroyed or retained, or what permissions are needed — meaningful gaps for a secret-mutating operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the action front-loaded and the trigger condition second; nothing is wasted and the parenthetical scoping detail adds value rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations, no output schema, and 0% schema coverage, the description leaves important things unaddressed: what happens to the prior secret value, whether the caller must follow up with secret_wait, and the meaning of the input parameters. It is minimally adequate for a 2-param tool but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description does not explain the two parameters at all. Worse, it references 'label, destination and metadata' while the schema exposes only 'name' and 'title', leaving the reader unable to map the described fields onto the actual inputs or infer the required 'name'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific action ('re-opens the intake page') with a specific resource (an existing secret) and reinforces it with the title. It implies the distinction from secret_request (which presumably creates a new secret) by scoping to 'an existing secret', but does not name that sibling to make the boundary explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit trigger condition: 'Use when secret_list shows expired or rotation_due' — a concrete, checkable state that names another tool. It stops short of stating when-not-to-use or naming secret_request/secret_write as alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_useUse secrets without seeing them (exec / http)A

Runs an action with secrets resolved inside this server at the moment of use. exec: argv without shell (secrets via env or stdin), or a shell script where ${secret:name} becomes an env var. http: request to an allowlisted https host with ${secret:name} in url/headers/body. Every NEW action (exact fingerprint) needs the person's approval on a local page that shows the literal action; they may choose to remember it. Output is redacted (raw, base64, hex, url-encoded, quoted variants) and size-limited.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNo
envNoexec: env vars for the child; values may contain ${secret:name}
urlNohttp: https URL on an allowlisted host
bodyNohttp: body; may contain ${secret:name}
namesNosecrets used (optional; derived from ${secret:...} references)
shellNoexec: POSIX sh script; ${secret:name} becomes an env var reference inside the child
stdinNoexec: stdin for the child; may contain ${secret:name}
actionYes
methodNohttp: method (default GET)
commandNoexec: argv, run WITHOUT a shell; ${secret:..} not allowed here
headersNohttp: headers; values may contain ${secret:name}
timeout_msNo
redact_env_filesNo

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: approval requirement on a local page, exact-fingerprint matching and optional remembering, redaction across raw/base64/hex/url-encoded/quoted variants, size-limiting, and the allowlisted-host constraint. These are the operational traits an agent must know before invoking an egress-with-secrets tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: it leads with what the tool does, then mode-specific mechanics, then the approval and redaction behaviors. Every clause is information-bearing for a 13-param tool, though the mode syntax could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description adequately covers the return contract (redacted, size-limited) and the approval lifecycle. For a 13-param, no-annotation tool it leaves minor gaps around timeout behavior, cwd, and the names/redact_env_files params, but nothing that would cause a misinvocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is a moderate 69%, and much of the description's parameter detail (exec argv without shell, env/stdin secret injection, http url/headers/body) mirrors what the schema's own field descriptions already state. It adds little for cwd, names, timeout_ms, and redact_env_files, so it neither amplifies nor compensates substantially.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action ('runs an action with secrets resolved inside this server') and enumerates the two concrete modes, exec and http, each with its mechanics. An agent can tell this is the secret-injection egress tool. It does not explicitly differentiate itself from siblings like ssh_exec or web_capture, keeping it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operative context: which mode to use for process execution vs HTTP, how ${secret:name} interpolates per mode, and the approval condition for any new action. It lacks explicit exclusions or named alternatives (e.g., 'use web_login for captured logins'), so it is clear context without routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_waitWait for the personC
Read-only

Waits (default 120 s) for a pending request/approval and returns its structural result.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
timeout_secondsNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already tells the agent this is a safe read, so the bar is lower. The description usefully adds the default 120 s blocking behavior, but it does not disclose what happens on timeout (error, empty result, retry) or whether polling occurs — meaningful gaps for a blocking call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no padding; the default timeout is placed immediately after the verb. It is efficient, though 'structural result' is an unclear phrase that costs a little precision.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 0% schema coverage, the description should cover both the `id` meaning and the timeout/return contract. It covers neither adequately, so an agent cannot reliably construct a call or anticipate failure behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning. It explains the timeout default (120 s) but says nothing about the required `id` — presumably the request identifier — leaving the one required parameter entirely undefined.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (waits) and resource (a pending request/approval) and notes the returned result, so an agent can tell it blocks until an approval completes. It does not, however, differentiate itself from siblings like secret_request or secret_list, and 'structural result' is vague jargon.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use, when-not-to-use, or named alternative. The agent must infer that this is called after issuing a request, and nothing says what to do if the wait is unnecessary or how it relates to secret_request.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

secret_writeCopy a stored secret to a file or serviceA

Writes stored values to an allowlisted target without exposing them: env-file (local or ssh host; updates only that key, keeps comments, 0600, atomic, optional backup), json/yaml by key path, systemd EnvironmentFile drop-in, GitHub Actions secret (gh, via stdin) or the clipboard (only after the person clicks, auto-cleared). First use of each target needs approval. dry_run tells which keys would be created/updated. Returns {written, target, keys:[{key, action}]}.

ParametersJSON Schema
NameRequiredDescriptionDefault
keysNosecret name → key in the target (default: the target key or the secret name)
nameNo
namesNo
targetYes
dry_runNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses that values are never exposed, that env-file edits are atomic, 0600, comment-preserving, and optionally backed up, that clipboard writes require a user click and auto-clear, and that targets are allowlisted with first-use approval. That is a rich, non-obvious safety and side-effect profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded paragraph: purpose, then the target catalogue, then per-target behaviors, then dry_run, then the return shape. Every clause carries information, though the heavy parenthetical density makes it slightly harder to scan than it could be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a nested union schema and no output schema, the description supplies the return shape ({written, target, keys:[{key, action}]}), the approval gate, and the dry_run contract, which is substantial. The remaining omission is the name/names selection parameters and any error/failure behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, so the description needs to compensate. It does explain the target kinds and dry_run semantics well beyond the schema's bare consts (e.g. 'json/yaml by key path', 'updates only that key'), but the top-level 'name' and 'names' parameters are never clarified in either place, leaving a real gap for a 5-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Writes stored values to an allowlisted target without exposing them,' then enumerates exactly which targets. This clearly separates it from read-side siblings like secret_list or secret_use, and the no-exposure constraint signals the security posture.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives actionable context: 'First use of each target needs approval' and 'dry_run tells which keys would be created/updated' tell the agent when to expect friction and when to preview. It does not, however, explicitly distinguish itself from secret_use or secret_request, so there is no named alternative or exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ssh_execRun a remote command with stored secretsA

Runs a shell command on an allowlisted SSH host (using the provisioned key). env values may contain ${secret:name}; they are delivered through stdin as exports, never argv. Needs approval per exact command; output redacted.

ParametersJSON Schema
NameRequiredDescriptionDefault
envNoremote env vars; values may contain ${secret:name}; delivered via stdin, not argv
hostYes
commandYes
timeout_msNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden well: it discloses allowlisting, provisioned-key auth, secret interpolation via stdin rather than argv, per-exact-command approval, and output redaction. It still omits timeout behavior, error handling, and local/remote destructive effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with the core action and followed by key security constraints. There is no wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, annotation-free tool, it covers the critical security and approval constraints an agent must know before calling it. Gaps remain around the optional timeout_ms parameter and the exact return/output shape beyond redaction.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%. The description repeats the env secret-interpolation detail already in the schema, adds a little host context via 'allowlisted', but leaves command and especially timeout_ms semantics unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: runs a shell command on an allowlisted SSH host using the provisioned key. This clearly distinguishes it from the secret_* and web_* siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives operational context such as the allowlisted host and per-command approval requirement, implying when it is usable. However, it does not explicitly compare it with alternatives or state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ssh_key_provisionCreate and install an SSH key (blind)A

Generates an ed25519 key locally (private key in the secret store + private ssh-agent, or a 0600 file), shows the host key fingerprint to the person for confirmation, optionally asks them for a one-time SSH password on the local page, installs the public key in authorized_keys and tests access. Returns only alias and fingerprints.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYeskey of ssh.hosts in config
aliasYes
storageNostore
passwordNoask the person for a one-time SSH password to install the key

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and does so well: it discloses local key generation, private-key storage locations (secret store + private agent, or a 0600 file), interactive steps (host-key fingerprint confirmation, optional one-time SSH password), the remote side effect (writing authorized_keys), and a post-install access test. It omits failure/reversibility behavior and required permissions, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action and ending with the return contract. The procedural clauses are dense but each conveys a distinct step or side effect, so there is little waste; it is packed rather than padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description compensates by stating it returns only alias and fingerprints. Given a mutating, interactive tool with no annotations, it covers generation, storage, prompts, installation and verification; only error handling and idempotency are left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%, so the description must compensate, and it partly does: 'secret store + private ssh-agent, or a 0600 file' explains the storage enum, and 'optionally asks them for a one-time SSH password' explains the password flag. The alias parameter remains undocumented in both schema and description, leaving one gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource (generates an ed25519 key, installs the public key in authorized_keys, tests access) and even states the scope of what it returns, so an agent knows exactly what the tool accomplishes. It does not, however, explicitly differentiate itself from sibling tools like ssh_exec or secret_write, which is what separates a 4 from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The narrated flow (generate key, confirm host fingerprint, install, test) strongly implies the scenario of provisioning SSH access to a host, but the description never states when to use this over alternatives such as ssh_exec or the secret_* tools, nor any when-not conditions. Usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

web_captureCapture a credential from a web panel (blind)A

Opens a browser window OWNED BY THIS SERVER (not yours) on an allowlisted site. The person logs in there (password/2FA never reach you). Declared steps (navigate/click/wait/wait_for_url/fill/press) run after approval (the person can edit them), then the extractor reads the value from the DOM straight into the store. You get only {stored:[name]} or {failed_step, error_code}; never page text, HTML or screenshots. Prefer this over any browser tool you control when a page shows a secret.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNo
nameYes
siteYes
stepsNo
extractYes
metadataNo
destinationNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and does so well: it discloses server-owned browser execution, allowlisted sites, human login and approval, step execution, editability, DOM extraction, and the narrow return values including failure shape. It also explicitly states that page text, HTML, and screenshots are never returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the security-critical ownership distinction and then proceeds through login, approval, step execution, extraction, and return values. Every sentence contributes relevant operational or safety context without filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex nested-parameter tool with no output schema and no annotations, the description supplies the essential operational model, safety boundaries, human-in-the-loop behavior, and exact success/failure response shapes. An agent can understand when to use it and what to expect from invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaningful semantics for the step types and extractor behavior, including that steps are declared and run after human approval. However, with seven parameters and low schema description coverage, it does not explain several top-level inputs such as site, url, destination, or metadata fields, so it only partially compensates for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation: opening a server-owned browser on an allowlisted site, having the person log in, running declared steps, and extracting the credential into the store. It clearly distinguishes the tool from browser tools the agent controls by emphasizing that the page is server-owned and the credential never reaches the agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit routing rule: prefer this over any browser tool you control when a page shows a secret. This names the alternative category and the condition that selects this tool, leaving little ambiguity for an agent choosing among tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

web_loginLog in to a site with stored credentials (blind)B

Fills a login form inside this server's own browser using ${secret:name} values (only on allowlisted origins) and saves the session encrypted with a TTL for later web_capture calls.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNo
siteYes
stepsYes
save_sessionNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does disclose meaningful behavior: execution happens in the server's own browser, secrets are referenced rather than passed, origins must be allowlisted, and the session is persisted encrypted with a TTL. However it says nothing about failure behavior, whether an existing session is overwritten, TTL specifics, or what is returned, which are important for a credential-handling tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the verb first and no filler. It is efficient, though the dense parenthetical packs constraints together, and the extreme brevity leaves gaps for a tool with a six-variant step DSL.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex browser-automation tool with no annotations, no output schema, and an undocumented step DSL, the description omits too much: return values, error/failure behavior, the site-vs-url relationship, save_session semantics, and TTL details. The security model is covered but operational completeness is not.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Top-level schema coverage is 0% and the description does not explain the distinction between 'site' and 'url', the structure/ordering semantics of the 'steps' array, or what save_session=false does. Its only parameter-adjacent content, the '${secret:name}' syntax, merely repeats the nested schema description for the fill value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Fills a login form inside this server's own browser') with the credential mechanism ('${secret:name} values'), and distinguishes itself from siblings by naming web_capture as the downstream consumer. The 'blind' nature (secrets never exposed to the agent) is conveyed. Slightly less than 5 because the site/url target and the step DSL that drives the login are not characterized.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for later web_capture calls' implies the paired workflow, but there is no explicit when-to-use/when-not guidance and no routing against alternatives like web_capture, blind_input, or ssh_exec. The allowlist constraint ('only on allowlisted origins') is a useful precondition, but the agent must infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 13 tool updatesv0.1.0
    • First observedblind_input
    • First observedblind_input_preview
    • First observedsecret_delete
    • First observedsecret_list
    • First observedsecret_request
    • First observedsecret_rotate
    • First observedsecret_use
    • First observedsecret_wait
    • First observedsecret_write
    • First observedssh_exec
    • First observedssh_key_provision
    • First observedweb_capture
    • First observedweb_login

TDQS

A3.7/5.0

Scored across 13 tools

Disambiguation4/5

Each tool has a genuinely distinct purpose grouped around secrets, blind input, SSH, and web capture. Minor potential confusion between secret_request and blind_input (both open an intake page) and between blind_input and blind_input_preview, but descriptions clearly differentiate (preview validates only, no values).

Naming Consistency4/5

Tools are consistently grouped by domain prefix (secret_*, ssh_*, web_*, blind_input_*) with predictable suffixes. Slight inconsistency in that some read as resource_verb (secret_list) while others are verb_noun (ssh_key_provision), but readability is high throughout.

Tool Count5/5

13 tools is a well-scoped count for a security-focused server covering multiple sub-domains (secrets lifecycle, SSH, web automation, blind input). Each tool earns its place with no obvious redundancy.

Completeness4/5

Covers a full secret lifecycle (request, list, rotate, delete, use, write) plus SSH key provisioning/exec and web login/capture, with preview and wait support. Reading secret values is deliberately omitted by design, so coverage is strong for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Zero-knowledge credential injection for AI agents. Your agent authenticates to websites and APIs without ever seeing a password, TOTP code, or API key.
    3 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to securely fill web forms with credentials from SecureVault, keeping raw secrets hidden from the agent.
    8 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables secure browser automation by letting agents fill Turnkey-stored secrets into web forms without the secret values ever appearing in the conversation, transcript, or model context.
    6 npm
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to securely control a user's existing Chrome profile locally, providing typed browser actions, form and editor support, WordPress workflows, terminal automation, and Figma inspection with policy-based authorization and redacted auditing.
    MIT