keywarden
keywarden
Tu agente de IA puede usar tus claves de API. Nunca puede leerlas.
keywarden es un almacén de credenciales local y cifrado que habla MCP. Claude Code, Claude Desktop, Cursor o cualquier cliente MCP se conecta a él y obtiene dos capacidades: hacer una llamada API autenticada y ejecutar un comando con credenciales en su entorno. Ninguna de las dos pone la credencial en sí en el contexto del modelo.
No existe una herramienta get_secret. Esa ausencia es todo el producto.
agent keywarden upstream
| | |
| "POST /v1/chat | |
| using openai/prod"| |
|-------------------->| |
| | check policy |
| | decrypt key |
| | attach Authorization |
| |------------------------->|
| |<-------------------------|
| response only | scrub any key from body |
|<--------------------| append to audit log |Por qué
Ahora mismo, la forma normal de permitir que un agente use tu clave de OpenAI es poner la clave en un archivo .env y
dejar que el agente la lea. En el momento en que lo hace, la clave está en la ventana de contexto de un modelo. Desde ahí
está en los registros de un proveedor, posiblemente en un conjunto de entrenamiento, posiblemente en un informe de fallo, y definitivamente en tu
propio historial de transcripciones que pegarás en un informe de error dentro de seis meses.
Rotar una clave es molesto. No saber si se ha filtrado es peor.
keywarden elimina el paso en el que el modelo ve la clave en absoluto.
Related MCP server: Echo Vault
Instalación
npm install -g keywardenNode 20.10 o más reciente. Dos dependencias de ejecución: el SDK de MCP y zod. Sin módulos nativos, sin compilador, sin demonio.
Inicio rápido
keywarden init --passphrase
keywarden add openai/prod --provider openai
keywarden mcp-configinit crea ~/.keywarden/ con un almacén cifrado y una política de denegación por defecto. add solicita
cada campo, para que nada termine en el historial de tu shell. mcp-config imprime el bloque para pegar en tu
cliente MCP.
Luego, en Claude Code:
Llama al endpoint de modelos de OpenAI con mi clave de producción y dime a cuáles tengo acceso.
El modelo llama a http_request con ref: "openai/prod". keywarden adjunta la clave, hace la llamada,
devuelve la respuesta. Pídele que imprima la clave y te dirá que no puede.
Las herramientas que obtiene un agente
Herramienta | Qué hace |
| Solo metadatos: refs, proveedores, nombres de campos, último uso. Nunca valores. |
| Una credencial más cómo puede usarse, qué hosts, qué variables de entorno. |
| Presets integrados y qué espera cada uno. |
| Llamada HTTPS autenticada. keywarden adjunta la credencial. |
| Lanza un proceso local con credenciales inyectadas como variables de entorno. |
| Entradas recientes del registro a prueba de manipulaciones. |
Establece KEYWARDEN_DISABLE_EXEC=1 para eliminar run por completo y exponer solo el proxy HTTP.
Tres superficies, un modelo de autorización
El mismo almacén, motor de políticas, concesiones y registro de auditoría son accesibles de tres maneras. Cuál uses no cambia nada sobre lo que está permitido.
superficie | para | cómo se identifica al llamante |
MCP (stdio) | Claude Code, Claude Desktop, Cursor | el cliente que lanzó el servidor |
CLI | tú, en una terminal | acceso al sistema de archivos del almacén |
HTTP (loopback) | cualquier lenguaje, CI, un script, una interfaz web | una clave de API de keywarden con alcance |
La superficie HTTP es lo que hace que keywarden sea utilizable desde código que no habla MCP, y es el primer lugar donde keywarden puede distinguir a un llamante de otro:
keywarden apikey create ci-runner --ref 'openai/**' --http --audit --ttl 30d
keywarden serve --port 8787curl -s http://127.0.0.1:8787/v1/proxy/openai%2Fprod \
-H "Authorization: Bearer kw_live_..." \
-H "content-type: application/json" \
-d '{"method":"POST","url":"/v1/chat/completions","body":{"model":"gpt-4o","messages":[]}}'El llamante tiene una clave de keywarden con alcance a openai/**, que lleva solo las capacidades que se le
otorgaron, expira en 30 días y es revocable con un comando. Nunca tiene la clave de OpenAI. Rutas:
/v1/secrets, /v1/secrets/:ref, /v1/proxy/:ref, /v1/run, /v1/audit, /v1/usage,
/v1/whoami, /healthz.
El servidor se vincula a 127.0.0.1 y rechaza una interfaz enrutable sin --allow-remote, porque
cualquiera que pueda alcanzar ese puerto obtiene un oráculo de autorización para cada credencial que cubre la clave.
Quién usó qué, y cuánto costó
Cada entrada en el registro de auditoría nombra a un actor, y el actor está dentro del hash, por lo que la atribución no puede reescribirse sin romper la cadena. Cada respuesta proxy se analiza para obtener los recuentos de tokens reportados por el proveedor.
keywarden usage --since 7dCREDENTIAL CALLS IN OUT TOTAL
openai/prod 142 418,220 96,410 514,630
anthropic/prod 38 92,004 31,887 123,891
ACTOR CALLS IN OUT TOTAL
http:ci-runner 118 356,900 74,220 431,120
mcp:mcp-client 62 153,324 54,077 207,401keywarden registra tokens, no dinero. Los precios cambian, difieren según el contrato, y una tarifa fija obsoleta
produce un número incorrecto con confianza en un informe financiero. Ten en cuenta que run no puede medirse: una vez que una
credencial está dentro de un subproceso, keywarden ve un código de salida, no un recuento de tokens.
Dos formas de usar una credencial
Proxy, para APIs HTTP. El agente describe una solicitud, keywarden adjunta la credencial y hace la llamada. Funciona para OpenAI, Anthropic, Stripe, GitHub, Slack, Cloudflare, Vercel, Supabase y cualquier API que se autentique con un encabezado o un parámetro de consulta.
// what the agent sends
{ "ref": "openai/prod", "method": "POST", "url": "/v1/chat/completions", "body": { "model": "gpt-4o", "messages": [] } }Inyección, para todo lo demás. AWS necesita firma de solicitudes SigV4, una URL de Postgres no es HTTP en absoluto,
y terraform apply quiere variables de entorno reales. keywarden lanza el proceso él mismo:
{ "command": "aws", "args": ["s3", "ls"], "inject": ["aws/prod"] }El proceso hijo obtiene AWS_ACCESS_KEY_ID y compañía. El modelo obtiene la salida estándar, con cualquier credencial
que aparezca enmascarada al salir.
Política
~/.keywarden/policy.json decide qué credencial puede usarse, con qué capacidad, contra qué.
Las reglas se evalúan de arriba a abajo, la primera coincidencia gana, y el valor por defecto es denegar.
{
"version": 1,
"default": "deny",
"redactResponses": true,
"rules": [
{
"ref": "openai/**",
"http": { "allow": true, "methods": ["POST"], "paths": ["/v1/**"] },
"exec": { "allow": false, "commands": [] },
"rateLimitPerMinute": 30
},
{
"ref": "aws/prod",
"http": { "allow": false },
"exec": { "allow": true, "commands": ["aws", "terraform"] },
"rateLimitPerMinute": 10,
"expiresAt": "2026-12-31T00:00:00.000Z"
}
]
}O desde la CLI:
keywarden policy allow "openai/**" --http --path "/v1/**" --method POST
keywarden policy allow aws/prod --exec aws --exec terraform --arg-deny "s3://*"
keywarden policy test aws/prod exec terraform* coincide dentro de un segmento de ruta, ** abarca segmentos. expiresAt hace que una regla sea temporal.
Nombrar un comando no es suficiente por sí solo. Permitir aws para aws s3 ls y el mismo binario
hace aws s3 cp a un bucket que pertenece a otra persona. Esa es la brecha a nivel de secuencia que la literatura
de amenazas de MCP sigue señalando: cada llamada individual está autorizada, y la combinación es la
exfiltración. Así que las reglas también restringen argumentos:
"exec": {
"allow": true,
"commands": ["aws"],
"argsDeny": ["s3://*", "--endpoint-url"], // any match refuses the call
"argsAllow": ["s3", "ls", "--region", "*"] // if set, every argument must match
}Concesiones: acceso temporal, con expiración y límite de uso
La política es configuración permanente. Es la forma incorrecta para "deja que el agente haga esta única cosa, ahora, durante quince minutos", que hoy significa ampliar una regla y olvidar estrecharla de nuevo.
Una concesión es una capacidad que lleva sus propias restricciones, tomada de la línea de trabajo de macaroon y biscuit, y emitida por ti en una terminal:
keywarden grant aws/prod --exec aws --ttl 15m --uses 5 --arg-deny "s3://*"
keywarden grant openai/prod --http --path "/v1/chat/**" --method POST --ttl 1h --uses 20
keywarden grant list
keywarden grant revoke <id>Las concesiones expiran solas, mueren cuando se agota su presupuesto de uso, y están protegidas con HMAC con una clave derivada
de tu almacén, por lo que un grants.json editado a mano se rechaza en lugar de honrarse. Un intento denegado
no consume un uso.
Establece "requireGrant": true en una regla de política y la configuración permanente se vuelve necesaria pero no
suficiente: no pasa nada hasta que emitas una concesión. Ese es el paso de aprobación con un humano en el circuito,
sin necesidad de un aviso interactivo dentro de un servidor stdio.
política | concesión | resultado |
permite, sin | — | permitir |
permite, | coincidencia activa | permitir |
permite, | ninguna | denegar |
deniega | coincidencia activa | permitir |
deniega | ninguna | denegar |
Integridad de configuración
Cifrar los secretos es la mitad del trabajo. policy.json decide si una credencial puede usarse y
providers.json decide a dónde se envía. Ambos son archivos planos. Alguien que no pueda descifrar un solo
byte aún puede agregar un proveedor cuyos hosts sean suyos y redirigir tu credencial hacia él.
Así que el almacén fija un hash de ambos archivos, y se niega a actuar sobre cualquiera de ellos hasta que hayas revisado el cambio:
keywarden trust show # what drifted
keywarden trust # review, then pin the current contentsEl archivo del almacén en sí está protegido con MAC en su totalidad, no solo por campo, porque cambiar
provider: "openai" a otra cosa nunca toca un texto cifrado y de otro modo se verificaría
limpiamente.
Lo que keywarden realmente hace cumplir
Sin herramienta de texto plano. La superficie MCP no tiene una ruta de código que devuelva un valor de credencial.
Lista de permitidos de salida. Una credencial solo puede enviarse a hosts que su proveedor declara, más los que agregues en la política. Una inyección de prompt que le diga al agente que haga POST de tu clave a
attacker.examplefalla en la verificación del host, antes de tocar la red.Solo HTTPS, sin seguir redirecciones. Un 302 a otro origen no reproducirá tu encabezado
Authorizationfuera del host.Protección SSRF. Loopback, rangos privados, CGNAT y link-local (que cubre el endpoint de metadatos de nube
169.254.169.254) están bloqueados, y la dirección se valida en la búsqueda DNS que el socket realmente usa, por lo que el rebinding de DNS no abre una ventana.Sin shell.
runpasa un array argv aspawnconshell: false. No hay análisis de metacaracteres en el que inyectar.Entorno hijo construido. El hijo obtiene una lista de permitidos de variables heredadas más las inyectadas. Tus otros secretos, y la propia frase de contraseña de keywarden, no se heredan.
Redacción de salida. Cada resultado de herramienta se escanea en busca de valores de credencial conocidos, sus formas base64 y codificadas en URL, y alrededor de una docena de formas de clave bien conocidas. Defensa en profundidad, no el control principal.
Auditoría a prueba de manipulaciones. Cada decisión, permitir o denegar, se agrega a un registro encadenado por hash.
keywarden audit verifyrecalcula la cadena e informa la primera entrada modificada o eliminada.Integridad de archivo completo. El almacén está protegido con MAC incluyendo sus metadatos, por lo que una credencial no puede redirigirse a otro proveedor sin detección.
policy.jsonyproviders.jsonestán fijados por hash al almacén y se rechazan cuando cambian fuera de banda.Endurecimiento del entorno. El servidor se niega a iniciar cuando
NODE_TLS_REJECT_UNAUTHORIZED=0,NODE_OPTIONSoSSLKEYLOGFILEestán establecidos, y advierte sobreNODE_EXTRA_CA_CERTSyHTTPS_PROXY. CVE-2026-21852 contra Claude Code fue una anulación de entorno que redirigió el tráfico saliente con el encabezadoAuthorizationadjunto; un proceso cuyo trabajo es adjuntar credenciales no debe iniciarse cuando la ruta de solicitud está bajo el control de otra persona.Restricciones de argumentos.
argsAllow/argsDenyestrechan qué invocaciones de un comando permitido están permitidas, no solo qué binario.Concesiones atenuadas. Capacidades con expiración, límite de uso y emitidas por el operador, resistentes a falsificación mediante un MAC derivado del almacén.
Enmarcado de datos no confiables. Los cuerpos de respuesta proxy se etiquetan como contenido no confiable de un host nombrado, por lo que una instrucción inyectada en una respuesta de API se presenta al modelo como datos.
Criptografía
Cifrado de sobre, todo desde node:crypto, sin bibliotecas criptográficas de terceros.
Una clave de datos aleatoria de 256 bits cifra cada campo con AES-256-GCM, con el ref de la credencial y el nombre del campo como datos autenticados adicionales, por lo que un texto cifrado no puede moverse entre entradas del almacén.
La clave de datos está envuelta por una clave derivada de tu frase de contraseña con scrypt a
N=2^17, r=8, aproximadamente 128 MiB y aproximadamente un segundo por intento. Eso es deliberado: el archivo del almacén es lo que un atacante se lleva, por lo que adivinar sin conexión tiene que ser costoso.Rotar tu frase de contraseña reenvuelve 32 bytes. No vuelve a cifrar cada secreto.
Modos de almacén
--passphrase es el fuerte. El servidor MCP necesita KEYWARDEN_PASSPHRASE en su entorno para
desbloquear sin un aviso.
--keyfile escribe una clave aleatoria en ~/.keywarden/masterkey para que nada tenga que solicitar. Es
conveniente, y significa que cualquiera que pueda leer tu directorio de inicio puede abrir el almacén. Sigue siendo mucho
mejor que archivos .env en texto plano dispersos por proyectos, porque la clave está en un solo lugar, su
uso está restringido por política, y cada uso se registra. Conoce qué intercambio hiciste. keywarden doctor te lo
recordará.
En Windows, los modos de archivo se establecen pero no se aplican de la manera en que POSIX aplica 0600. Consulta
THREAT_MODEL.md.
CLI
keywarden init --passphrase|--keyfile create the vault
keywarden doctor check the install, flag weak settings
keywarden trust [show] re-pin policy.json + providers.json after reviewing a change
keywarden grant <ref> ... issue a temporary, use-capped capability
keywarden grant list | revoke <id>
keywarden add <ref> --provider <id> store a credential (prompts for each field)
keywarden list metadata only
keywarden describe <ref> metadata plus how it can be used
keywarden reveal <ref> print plaintext, asks first, always audited
keywarden rm <ref> [--field f] delete
keywarden exec <ref[,ref]> -- <cmd> run a command with credentials injected
keywarden policy show|init|allow|deny|test
keywarden audit [tail|verify]
keywarden passphrase rotate
keywarden providers built-in presets
keywarden mcp-config print the MCP client config
keywarden doctor check the install, flag weak settingsProveedores personalizados
Cualquier cosa no integrada va en ~/.keywarden/providers.json. Consulta docs/PROVIDERS.md.
{
"acme": {
"label": "Acme Internal API",
"hosts": ["api.acme.internal", "*.acme.io"],
"baseUrl": "https://api.acme.io",
"fields": ["token", "tenant"],
"required": ["token"],
"auth": { "type": "header", "name": "X-Acme-Key", "template": "{{token}}" },
"env": { "ACME_TOKEN": "{{token}}", "ACME_TENANT": "{{tenant}}" }
}
}De lo que keywarden no te protege
Lee THREAT_MODEL.md antes de confiarle algo costoso. La versión corta:
Si el agente puede ejecutar comandos locales arbitrarios a través de alguna otra herramienta, puede leer tu archivo de bóveda y, en modo keyfile, tu clave maestra. keywarden protege el contexto del modelo, no tu disco.
runda la credencial a un proceso real. Si incluyes en la lista de permitidos un comando que pueda manipularse para exfiltrar su propio entorno, la credencial se escapa. Acota la lista de permitidos al máximo.El enmascarado es una red de seguridad con agujeros. Una credencial que una API devuelva recodificada en una forma que no reconozcamos no será detectada.
keywarden no impide que un agente haga algo costoso o destructivo con una credencial que tiene un permiso legítimo para usar. Para eso sirven el alcance de las políticas y los límites de frecuencia.
Desarrollo
npm install
npm run build
npm test # 89 unit tests + 46 end-to-end checks against the real CLI, MCP and HTTP serversLa suite e2e ejecuta los binarios reales en un KEYWARDEN_HOME desechable y comprueba, entre otras cosas,
que ninguna respuesta de herramienta contiene la credencial.
Lectura
THREAT_MODEL.md — qué está dentro del alcance y qué, honestamente, no lo está
docs/RESEARCH.md — la literatura de 2026 en la que se basa este diseño, qué se adoptó y qué se consideró y se descartó
docs/COMPETITORS.md — el panorama del sector, y en qué keywarden es realmente distinto y no solo se comercializa de otra manera
docs/TEAM.md — la arquitectura para varios desarrolladores: identidad, intercambio de claves sin un servidor legible, flujo de aprobación, contabilidad de costes y orden de compilación
docs/PROVIDERS.md — escribir un proveedor personalizado
Versión alojada
Se prevé una versión alojada para quienes quieren una bóveda de equipo, gestión mediante navegador y sincronización entre máquinas, con la misma garantía de cero exposición. Todo lo que hay en este repositorio sigue siendo MIT y se puede seguir usando de forma totalmente independiente. Ver docs/HOSTED.md.
Licencia
MIT
Available Tools
6 toolsaudit_tailA
Recent entries from keywarden's tamper-evident audit log: which credential was used, by which capability, against which host or command, and whether it was allowed or denied.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | Optional: only entries for this credential ref. | |
| limit | No | How many entries. Default 20, max 200. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It discloses that the tool returns recent entries, that the source log is tamper-evident, and what fields an entry contains. It does not explicitly discuss ordering, permissions, or read-only guarantees, but the audit-tail nature and field list make the behavior reasonably transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly written sentence that immediately states the resource and the most important properties of the returned entries. Every phrase earns its place and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple two-optional-parameter contract and a fully documented schema, the description covers everything needed for both selection and correct invocation. It explains what the tool does, what an entry includes, and the recent-history nature of the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters (ref and limit) are already fully described in the input schema, so the description adds no additional parameter meaning. The description reinforces the overall audit-log scope but does not go beyond what the schema already provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the exact resource: recent entries from the tamper-evident audit log, and enumerates the kinds of information the entries contain. It is easily distinguished from the sibling tools because it is about audit history, not secret lookup, provider listing, HTTP calls, or command execution.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is clearly implied: the agent should use this when it needs recent audit log entries about credential use, capability, target host/command, and allow/deny results. It does not explicitly name alternatives or define when-not-to-use conditions, but the context is not ambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_secretB
Metadata for one credential plus how it can be used: whether it can be proxied over HTTP, which hosts it may reach, and which environment variables it maps to when injected.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Credential ref, e.g. "openai/prod". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry some behavioral burden. It reveals what information the tool returns at a high level (proxying, hosts, env vars) but does not disclose things like whether it exposes secrets themselves, side effects, or auth requirements. It adds some value beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one clear sentence, front-loaded with the main intent and then enumerating the specific metadata categories. No waste, though it could be slightly more structured with a colon or list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one well-documented parameter and no output schema, the description covers the main purpose and key return aspects. However, it does not mention whether it returns the secret value itself, which could be relevant for an agent deciding between this and list_secrets. That gap leaves it merely adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers the ref parameter with 100% coverage including an example. The description does not add further meaning beyond referring to the credential, so it doesn't push above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: retrieving metadata for one credential and its usage characteristics. It specifies the resource (credential) and the relevant aspects (HTTP proxying, reachable hosts, environment variable mappings). It doesn't explicitly differentiate from sibling tools, but the focus is specific enough to avoid major confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage is for inspecting a credential's metadata and how it can be used. It doesn't explicitly state when to use this over alternatives like list_secrets, nor does it provide exclusions. Context is clear but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_requestA
Make an authenticated HTTPS request using a vaulted credential. keywarden attaches the credential itself; you never see it. The destination must be an allowed host for that credential. Redirects are not followed and non-HTTPS is refused.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Credential ref, e.g. "openai/prod". | |
| url | Yes | Absolute https URL, or a path resolved against the provider base URL (e.g. "/v1/models"). | |
| body | No | Request body. An object is JSON-encoded automatically; a string is sent verbatim. | |
| method | No | HTTP method. Defaults to GET. | |
| headers | No | Extra request headers. Auth headers are managed by keywarden and will be rejected here. | |
| timeout_ms | No | Per-request timeout. Default 60000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and excels: it discloses that the credential is attached by keywarden and invisible to the caller, that the host must be allow-listed, that redirects are not followed, and that non-HTTP requests are rejected. This exceeds the typical transparency and preempts common failure modes, giving the agent a realistic picture of runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four concise sentences front-load the core purpose and immediately follow with critical behavioral constraints. Every clause adds unique value—no redundant or fluff content—making it easy to parse and highly digestible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers authentication, host authorization, redirects, and HTTPS enforcement, which are the most critical behavioral aspects. However, since there is no output schema, the absence of any mention of response format or error handling is a minor gap—an agent might wonder what the tool returns. Still, for a generic HTTP client, the description is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all parameters with 100% coverage (ref, url, body, method, headers, timeout_ms). The description adds general behavioral context (auth, host restrictions) but does not elaborate on parameter-specific semantics beyond what the schema provides. This meets the baseline for full schema coverage without adding parametric nuance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool makes an authenticated HTTPS request using a vaulted credential. It differentiates itself from sibling tools (audit_tail, list_secrets, etc.) by focusing on outgoing requests, and the scope is crisply defined: a single request with auth handled internally. The verb 'Make' plus the resource 'authenticated HTTPS request' is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool, emphasizing the need for a vaulted credential and an allowed host, and explicitly notes restrictions (redirects not followed, non-HTTPS refused). It does not explicitly name alternatives or provide when-not-to-use guidance, but given the distinct sibling tools, the context is sufficient. A minor deduction for not explicitly contrasting with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_providersA
List known provider presets (openai, aws, stripe, ...) with their allowed hosts, expected field names, and env-var mappings. Useful before asking the user to add a new credential.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the burden. The verb 'list' strongly implies a read-only, side-effect-free operation, which is a core behavioral trait. However, it does not explicitly confirm a read-only nature, nor does it disclose any network calls, authentication dependencies, or failure modes, leaving some uncertainty.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that moves from the general operation to specific examples and output attributes. It is highly compact, with no redundant words. Every phrase adds value, and the essential 'List known provider presets' is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description takes responsibility for defining what is returned; it does so by naming permitted hosts, expected field names, and environment variable mappings. It also adds a practical use-case with clear context. It does not mention edge cases like empty providers or exact formatting, but these are not strongly demanded for such a simple read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero properties, so there are no parameters to describe. The description correctly focuses on the operation and its output without mentioning input requirements. According to the baseline rule for zero-parameter tools, a score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the verb ('List'), the resource ('provider presets'), and the output contents ('allowed hosts, expected field names, and env-var mappings'). It clearly distinguishes itself from sibling secret-related tools by focusing on the provider domain. There is no tautology; it goes beyond merely restating the tool name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear when-to-use signal: 'Useful before asking the user to add a new credential.' This grounds the tool as a prerequisite step in a credential-adding workflow. It does not explicitly name alternative tools or state when-not-to-use, but the given context is sufficient for most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_secretsA
List every credential in the vault as metadata only: ref, provider, description, which field names exist, when it was last used. Never returns credential values. Start here.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Optional: only secrets carrying this tag. | |
| provider | No | Optional: only secrets for this provider id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and meaningfully discloses that the tool only returns metadata and never credential values. It also surfaces the output fields and last-use flag, which is useful behavioral context. It does not mention edge behaviors such as pagination or permission failures, but those are minor for this tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences front-load the main action and output format, then add the critical safety note and a usage cue. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple optional-filter list tool with no output schema, the description sufficiently covers the return shape, the read-only metadata behavior, and the intended starting point. The schema covers the parameters, and no critical calling information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both optional filters already have clear descriptions in the schema (filter by tag, filter by provider). The description adds no additional meaning to the parameters, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Describes a specific verb ('List') and resource ('every credential in the vault'), and explains the metadata-only output fields (ref, provider, description, field names, last used). It distinguishes itself from sibling tools by explicitly disclaiming credential values, so an agent can tell it apart from describe_secret.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Start here' gives a clear entry-point cue for exploring the vault, and the metadata-only behavior makes it appropriate for discovery before retrieving a single secret. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
runA
Run a local command with one or more vaulted credentials injected as environment variables (e.g. aws, terraform, gh, psql, a build script). The command is executed directly with no shell, so pass arguments as an array. Output is scanned and any credential appearing in it is masked before you see it.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Working directory. Defaults to the server's cwd. | |
| env | No | Extra non-secret environment variables. | |
| args | No | Arguments as separate strings, e.g. ["s3", "ls"]. No shell parsing happens. | |
| stdin | No | Optional text written to the process stdin. | |
| inject | Yes | Credential refs to inject, e.g. ["aws/prod"]. | |
| command | Yes | Executable name or path, e.g. "aws". | |
| timeout_ms | No | Wall-clock limit. Default 60000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses the no-shell execution model, the need to pass arguments as an array, and the key credential-masking behavior. It does not mention exit-code or error-handling behavior, but the most important safety-relevant traits are surfaced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences deliver the core behavior, execution model, and output masking with no filler. The most important information is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema documents all seven parameters in detail, and the description covers the core execution semantics and output privacy behavior. It stops the short of explicitly describing the full output contract, such as stdout/stderr or exit-code handling, but for its complexity the definition is still reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the structured parameter descriptions already handle most meaning. The prose adds marginal clarification by tying 'inject' to environment variables and 'args' to the no-shell array convention, but it does not substantially go beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: run a local command with vaulted credentials injected as environment variables. It gives concrete examples (aws, terraform, gh, psql) and clearly positions itself as a local command runner, distinguishing it from the secret-management and HTTP sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: running local CLIs or scripts that need injected secrets. It does not explicitly state exclusions or compare against siblings, but the 'local command' framing and examples make the intended use obvious.
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.
6 tool updates
v0.3.0- First observed
audit_tail - First observed
describe_secret - First observed
http_request - First observed
list_providers - First observed
list_secrets - First observed
run
TDQS
Scored across 6 tools
Each tool targets a clearly distinct concern: auditing, listing all secrets, inspecting one secret, listing provider presets, making an HTTP request, and running a local command. Even http_request and run, which both consume credentials, are clearly separated by remote HTTP vs local execution.
list_secrets, list_providers, and describe_secret follow a readable verb_noun pattern, but audit_tail, http_request, and run break it: audit_tail is noun-first, http_request is a noun phrase, and run is a bare verb. The set is understandable but mixes conventions.
Six tools is a well-scoped size for a credential vault/usage server. Each tool covers a meaningful part of the workflow without redundancy or bloat.
The server covers the core credential-usage workflow well: list, describe, use over HTTP, use locally, and audit past use. Credential creation/update/delete is absent, but the descriptions suggest new credentials may be added by the user outside the tool set, so this is a minor workaround gap rather than a fatal one.
Maintenance
Related MCP Connectors
- FullmaktOAuthai.fullmakt
Credential broker for AI agents: scoped, revocable API access with policy enforcement and audit.
Give your AI hands. Identity, credential vault, and API gateway for autonomous agents.
Secrets for developers and agents—secure context and workflows without exposing secret values.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to securely access authenticated services (HTTP, SSH, SMTP) without exposing secrets, by acting as a server-side proxy that injects authentication.MIT
- FlicenseNot gradedqualityBmaintenanceEnables agents to securely use credentials for GitHub, Cloudflare, OpenAI, Stripe, and xAI without ever reading the secret values, including credential health, rotation, and audit features.-
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to call external endpoints under per-endpoint policy enforcement, with credentials and personal data kept inside a hardware enclave and every allowed or denied attempt recorded to an immutable audit ledger.2-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to invoke upstream APIs without ever holding reusable credentials, using short-lived scoped capabilities and server-side secret injection. Also provides execution controls and x402 facilitator routing for secure agent actions.-