Skip to main content
Glama

SecureInput — private API key input for AI coding agents

CI

Give an AI coding agent the access it needs without pasting your API key into chat. SecureInput is an open-source, local-first Model Context Protocol (MCP) server for API keys, passwords, and tokens. It collects input in an inline MCP App when the host supports it, or in a paired localhost browser otherwise. It can pass the value to a local command through stdin or environment variables, or write it to a .env file.

The default MCP response contains status and exit information, not the secret. The MCP bridge is designed for stdio clients such as Claude Code, Cursor, Codex, VS Code / GitHub Copilot, Windsurf, and Cline; inline display depends on the host's MCP Apps support. macOS and Linux require Node.js 22 or newer.

Install from source · Connect your agent · Security model · FAQ

agent: "I need a GitHub token to create the repo."
        │
        ▼
  request_secret (MCP)
        │
        ▼
  inline form in a compatible host, or paired localhost browser
        │
        ▼
  SecureInput daemon on 127.0.0.1
        ├── execute: gh auth login --with-token   (token through stdin)
        └── write_env: .env.local                 (plaintext file, mode 0600)
        │
        ▼
agent: { "ok": true, "status": "completed", "exitCode": 0 }

Why this exists

Coding agents constantly need credentials. The usual options are bad:

Approach

What goes wrong

Paste the key into chat

It enters the model context, transcript, logs, and possibly telemetry.

Agent prints a terminal command

You have to run it manually; the key can end up in shell history or ps.

Type it into a terminal prompt

Fine, but repetitive, easy to mistype, and impossible for remote or headless agents.

Commit a .env by hand

Easy to get wrong permissions, duplicate keys, or commit the file.

SecureInput provides a separate input path for the credential. By default it does not return the value in the MCP tool result. The inline host, commands you run, and applications with access to a written .env file remain part of the trust boundary. See Security model.

Related MCP server: vault-mcp

Features

  • MCP-native — one tool, request_secret, plus polling, cancellation, and status tools.

  • Local only — binds to 127.0.0.1; pairing token, signed session cookie, Origin and CSRF checks.

  • No secret in chat by default — the agent receives request status and exit details. stdout/stderr are withheld from MCP results.

  • Direct command execution — no shell, secrets supplied through stdin or environment variables, never command-line arguments.

  • Safe .env writes — atomic replace, 0600 permissions, comments and line endings preserved, .env and .env.* only.

  • Two input modes — the compact inline form submits on Enter; the paired browser offers request details and additional confirmations for risky actions.

  • One-time requests — pending requests expire, results are short-lived, and a submission can only be claimed once.

  • Defense in depth — RE2-safe validation patterns, value/output size caps, ANSI stripping, output redaction, audit metadata without values.

  • Small shadcn/ui frontend — the UI is intentionally boring: pairing, a request list, a form, and a result.

  • Opt-in return mode — for clients that truly need the value back; disabled by default and clearly marked dangerous.

Requirements

  • Node.js 22 or newer

  • macOS or Linux (Windows is supported in code but not yet covered by CI)

  • An MCP Apps-compatible host, or a browser on the same machine for fallback

Quick start from source

The npm package is not published. Install from this repository, or download the MCP bundle from GitHub Releases for an MCPB-compatible client. The bundle requires Node.js 22 or newer and is currently unsigned.

git clone https://github.com/r69shabh/secureinput.git
cd secureinput
npm ci
npm run build
npm link          # puts `secureinput` on your PATH

Add SecureInput to your MCP client. The first client connection starts the local daemon automatically. To start it yourself and pair the browser fallback:

secureinput serve

Inline requests do not open a browser. When a client needs the browser fallback, its pairing page opens automatically if browser opening is enabled. You can also open and pair it manually:

secureinput pair

You can also check that everything is healthy:

secureinput status
secureinput doctor

The daemon listens on http://127.0.0.1:4780. The config lives in ~/.secureinput/ with mode 0600.

npm link is just for local use. npm install -g . or an absolute path to dist/cli/index.js works too.

Browser or inline input

When the local inline widget is rebuilt, a connected SecureInput server announces the updated resource automatically. Clients that honor MCP tool-list change notifications can use the new form for subsequent requests without reconnecting; already-open forms keep their original version. Some clients may need a reconnect if they do not refresh tool metadata. Installing this refresh capability itself requires restarting the existing MCP process once.

A GitHub push does not install updates on users' computers: update the local checkout and rebuild it first. The refresh mechanism updates the widget only; changes to the running server or daemon may still require a restart. SecureInput does not silently download or execute updates.

Inline input is the default on compatible MCP Apps clients. If the client cannot render it, SecureInput automatically opens paired localhost browser input. No browser is opened for supported inline requests, and Enter authorizes the requested delivery without an additional SecureInput confirmation dialog. The host may still apply its own MCP tool permissions.

Existing explicit browser-only preferences are preserved. To switch an existing installation to inline-first:

secureinput settings --input-mode inline
secureinput stop

Reconnect your MCP clients to apply a changed setting. Use secureinput settings --input-mode browser only if you want to force browser input.

Inline requires a host advertising the MCP Apps HTML capability. Text-only clients automatically use the browser. Both modes deliver to the same local execute or write_env implementation. The inline form shows only the field label and a rounded outline input with an inset submit arrow. In inline mode, Enter authorizes the requested delivery, including an overwrite explicitly requested by the agent; the browser flow keeps its separate review controls. The inline form encrypts values and a one-request capability with AES-256-GCM; a fresh RSA-OAEP-SHA-256 key pair wraps the encryption key. Only the daemon holds the private key. The capability and public key are supplied in widget-only tool-result metadata; the host must keep that metadata out of model context. Inline return-to-agent delivery is unsupported and uses the browser instead.

The inline widget needs no direct network access: it submits ciphertext through the host's MCP bridge. This does not protect against a malicious host that alters widget code or keys. The local browser retains a stronger boundary from the chat host. Neither mode sandboxes an approved command's filesystem or network access, and no “never trained” claim follows from merely using terminal commands.

For a synthetic local test of the actual widget and terminal-to-env flow:

npm run build
npm run demo:host

Open the printed loopback URL. Enter a fake key, review the command, and submit. The reference host renders the real MCP App inside a restricted iframe; the approved Node command writes .env.inline-demo with mode 0600 in an isolated temporary directory. This reference host is a test fixture, not proof that a particular chat product supports inline apps. Use real credentials only in a separately evaluated host.

Connect your coding agent

SecureInput runs as a stdio MCP bridge. The first client that needs it auto-starts the shared daemon; you only pair the browser once.

Claude Code

claude mcp add secureinput -- secureinput mcp

Cursor

Add to ~/.cursor/mcp.json (or the project .cursor/mcp.json):

{
  "mcpServers": {
    "secureinput": {
      "command": "secureinput",
      "args": ["mcp"]
    }
  }
}

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.secureinput]
command = "secureinput"
args = ["mcp"]

VS Code / GitHub Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "secureinput": {
      "type": "stdio",
      "command": "secureinput",
      "args": ["mcp"]
    }
  }
}

Any MCP client

Use a stdio server with command secureinput and argument mcp.

{
  "mcpServers": {
    "secureinput": {
      "command": "secureinput",
      "args": ["mcp"]
    }
  }
}

If the executable is not on PATH, use the absolute path to dist/cli/index.js:

{
  "mcpServers": {
    "secureinput": {
      "command": "node",
      "args": ["/absolute/path/to/secureinput/dist/cli/index.js", "mcp"]
    }
  }
}

Add an instruction like this to your agent rules so it reaches for the tool instead of asking for a pasted key:

When you need an API key, password, or token, call the SecureInput MCP tool
request_secret. Do not ask me to paste secrets into chat. Prefer delivery
mode "execute" with the secret in stdin/env, or "write_env" for .env files.

MCP tools

request_secret

Creates a secure input request and optionally waits for the user.

{
  "title": "GitHub CLI login",
  "description": "Authenticate gh so I can create and push the repository.",
  "fields": [
    {
      "id": "token",
      "label": "GitHub token",
      "description": "A fine-grained token with repo access.",
      "type": "password",
      "minLength": 20
    }
  ],
  "delivery": {
    "mode": "execute",
    "command": "gh",
    "args": ["auth", "login", "--with-token"],
    "stdin": "{{token}}",
    "timeoutSeconds": 60
  },
  "waitSeconds": 30
}

Fields:

  • title — short request name, max 100 characters.

  • description — why the secret is needed, max 1000 characters.

  • cwd — optional working directory, resolved relative to the MCP client's working directory; must resolve inside an allowed root.

  • fields — 1–10 inputs. Each has id, label, optional description, type (password or text), placeholder, minLength, maxLength, pattern (RE2), required, sensitive, and autocomplete.

  • delivery — execute, write_env, or return (disabled by default).

  • timeoutSeconds — request lifetime, 30–900 seconds. Default 300.

  • waitSeconds — how long this tool call blocks, 0–240 seconds. Default 30.

If the user has not submitted within waitSeconds, the result is { "requestId": "req_…", "status": "pending", "inputMode": "inline" } (or "browser"). Call check_secret_request with the returned request ID.

check_secret_request

Long-polls an existing request. Waits up to 45 seconds.

{ "requestId": "req_…", "waitSeconds": 30 }

cancel_secret_request

Cancels a request that is still pending.

{ "requestId": "req_…" }

secureinput_status

Returns input mode, return-mode state, and pending request IDs/statuses. Full browser/API policy responses are unchanged.

Delivery modes

execute — run a command with the secret

{
  "mode": "execute",
  "command": "gh",
  "args": ["auth", "login", "--with-token"],
  "cwd": ".",
  "stdin": "{{token}}",
  "env": {},
  "timeoutSeconds": 120
}
  • The command is spawned directly with shell: false. There is no shell interpolation by SecureInput.

  • Secret fields can appear in stdin or env values as {{fieldId}}. They cannot appear in command or args. Environment variables can still be visible to other processes on some systems; prefer stdin when available.

  • Non-sensitive text fields may be used in args for things like usernames.

  • At least one secret reference must go through stdin or env.

  • stdout and stderr are withheld from the agent. The paired local browser can show size-capped, best-effort redacted output.

  • Child processes receive basic OS variables (such as PATH, HOME and temporary-directory settings), fixed terminal settings, and the explicit delivery env mapping. Other daemon environment variables are not inherited.

  • The process group is terminated on timeout.

  • Commands must be non-interactive. TTY-only login flows are not supported; use the tool's token/non-interactive mode instead.

write_env — write a .env file

{
  "mode": "write_env",
  "path": ".env.local",
  "mapping": {
    "secret": "STRIPE_SECRET_KEY"
  },
  "overwrite": false
}
  • Only .env and .env.* files are allowed, and names containing example, sample, template, dist, defaults, or schema are rejected. Script-like names such as .envrc are not accepted.

  • The parent directory must exist and resolve inside an allowed root.

  • Symlinks are rejected.

  • Existing keys require overwrite: true. The browser asks for overwrite confirmation; inline submission authorizes the requested overwrite without a separate confirmation.

  • Writes are atomic and the resulting file gets mode 0600. Existing comments, export prefixes, quoting style, and line endings are preserved.

  • Files larger than 1 MiB are refused.

return — hand the secret back to the agent (dangerous)

Disabled by default. Start the daemon with --allow-return to enable it:

secureinput serve --allow-return

The setting is persisted in the config file. Return mode puts the secret in the model context and transcript. Use it only when execute and write_env cannot solve the problem.

What the agent sees

MCP responses are compact, minified status objects. Full request details are sent only in widget-only _meta; they are not repeated in model-visible content. The inline widget does not poll while input is pending. After submission it long-polls an app-only status tool, keeping UI updates out of model context.

A completed execute request looks like this:

{"requestId":"req_…","status":"completed","exitCode":0}

The secret does not appear in the tool result, the request object, the SSE stream, the audit log, or the server log.

Security model

SecureInput is built for the local-desktop threat model, not for hostile multi-user hosts.

Protected by design

  • Loopback-only server, with a Host-header check that rejects DNS-rebinding attempts.

  • 256-bit random MCP and pairing tokens stored in a 0600 config file.

  • Pairing token exchanged for a signed, HttpOnly, SameSite=Strict session cookie.

  • Same-origin checks and a custom CSRF header on state-changing browser requests.

  • Strict CSP, frame-ancestors 'none', no CORS, no-store on API and HTML entry points.

  • One-time request claim, per-request TTL, pending caps, and rate limits.

  • Constant-time token comparison and pairing rate limiting.

  • RE2 validation patterns, which avoid regex denial-of-service.

  • Submitted field values are not deliberately put in URLs, argv, logs, audit records, or error messages. The initial pairing URL contains a separate pairing token; keep it private.

  • Output redaction covers raw, JSON-escaped, URL-encoded, and base64 forms of each secret, plus common token formats.

  • Command execution with shell: false; timeout kills the process group.

  • Env writes are atomic, 0600, symlink-safe, and confined to allowed roots.

  • Risk assessment marks shell/network/absolute-path commands, env overwrites, and return mode. The browser flow adds review checkboxes; the inline flow does not show those checkboxes and submission authorizes delivery.

  • Audit log records metadata and outcomes only: request ID, client, delivery destination, field names, exit code, duration.

Outside the boundary

  • A command you approve can exfiltrate the secret. Reviewing the exact command and destination is the final control.

  • An agent with filesystem or terminal access may be able to read a .env file after it is written, or run commands that read it. Use execute with stdin when you do not want a persistent file.

  • Same-user malware, root, a compromised browser, a malicious extension, or a keylogger can read anything you type. SecureInput does not claim to stop them.

  • Environment variables can be visible to other processes running as the same user on some systems. Prefer stdin when the command supports it.

  • Redaction is best-effort for transformed secrets (hashed, split, encrypted, or re-encoded output).

  • Pending requests and secret values live only in memory. Restarting the daemon discards them.

  • .env files are plaintext. SecureInput sets safe permissions but does not encrypt anything.

Configuration

Default config directory: ~/.secureinput/

File

Purpose

config.json

Port, tokens, allowed roots, return/audit/browser settings. Mode 0600.

runtime.json

Running daemon PID and port.

audit.jsonl

Metadata-only audit trail. No secret values.

server.log

Daemon log. No secret values.

Environment variables:

Variable

Meaning

SECUREINPUT_HOME

Override the config directory.

SECUREINPUT_NO_OPEN

Set to 1 to prevent automatic browser opening.

SECUREINPUT_WEB_DIR

Override the built web UI directory.

Allowed roots default to your home directory. Tighten this when starting the daemon:

secureinput serve --root ~/projects

Repeat --root for multiple directories. Values are resolved and persisted on first run. Restart the daemon after changing them.

CLI reference

secureinput serve [--port 4780] [--root <path>]... [--allow-return]
                  [--no-open] [--no-audit] [--home <path>] [--web-dir <path>]
secureinput mcp   [--home <path>] [--port <port>]
                  [--client-name <name>] [--client-version <version>]
secureinput pair  [--home <path>] [--port <port>] [--no-open]
secureinput status
secureinput stop
secureinput doctor
  • serve runs the daemon and opens the pairing page.

  • mcp runs the stdio bridge and auto-starts the daemon if needed.

  • pair starts the daemon if needed and prints a pairing URL.

  • status shows daemon health, policy, and pending requests.

  • stop stops the daemon.

  • doctor checks Node version, daemon reachability, and runtime PID.

The MCP bridge inherits your current working directory and reports it to the daemon. That directory must be inside an allowed root; otherwise the request is rejected instead of silently falling back.

HTTP API and HTTP MCP

The daemon also exposes a stateless Streamable HTTP MCP endpoint:

POST http://127.0.0.1:4780/mcp
Authorization: Bearer <mcpToken from ~/.secureinput/config.json>
Content-Type: application/json

This is useful for clients or test harnesses that prefer HTTP over stdio. The endpoint uses JSON responses rather than long-lived SSE sessions. It is still loopback-only and requires the MCP token.

The browser UI uses authenticated REST and SSE endpoints under /api. Those are implementation details and may change; the MCP tools are the stable interface.

Choose a delivery method

Method

Useful for

What persists

execute with stdin

A non-interactive CLI login or command that accepts a token on stdin

The command may store credentials itself

execute with environment variables

A command that requires an environment variable

The command may store credentials; other same-user processes may see its environment

write_env

A local application that reads a .env file

A plaintext file with owner-only permissions

Use the browser input mode when you need to review the destination and risk confirmations in SecureInput itself. The compact inline form shows the input label and submits immediately; it does not show the browser's review screen. A person must be available to enter the value in either mode.

FAQ

Does the coding agent see my API key? The MCP result does not intentionally return it by default. The agent sees the request ID, status and exit code; stdout/stderr stay local. An approved command can still write or transmit values, and an agent with terminal or filesystem access may be able to read a written .env file. return mode explicitly gives the value to the agent and is disabled unless you start the daemon with --allow-return.

Can I enter a secret inside the agent chat? Yes, by default with a compatible MCP Apps host. The widget encrypts its submission before passing it through the host to the local daemon. It uses the same local command/env-file delivery implementation; Enter authorizes inline delivery, while the browser retains its review controls. The host still controls rendering and widget metadata, so use inline input only in a host you trust. See the input-mode settings below. This is not a claim of compatibility with every chat client.

Where are secrets stored? SecureInput keeps pending requests and submitted values in process memory and drops references after delivery; JavaScript memory is not guaranteed to be zeroized. write_env intentionally writes plaintext to the .env file you approve. Commands may also persist credentials themselves. Completed request metadata is kept in memory for 10 minutes, and only metadata is written to the audit log.

Does it work with Claude Code? Yes. Run claude mcp add secureinput -- secureinput mcp. The same stdio bridge works with Cursor, Codex CLI, VS Code Copilot, Cline, Windsurf, and other MCP clients.

Does it work with Cursor? Yes. Add the mcpServers entry shown above to Cursor's MCP config.

Why not just use a password manager? A password manager is great for humans, but it is not an MCP delivery path. SecureInput focuses on getting a secret into a specific command or env file with an auditable destination, without an agent API key.

Can the agent read my whole environment? A command receives a small set of OS environment variables plus the values explicitly supplied in the delivery mapping. It still runs with your OS user's permissions and may read files or credential stores. The browser mode shows the command and adds confirmations for high-risk requests; the compact inline mode does not show those details. Use the smallest credential and the narrowest scope you can.

What happens if the daemon restarts? Pending requests and completed results are lost. The agent will receive a "request not found" error and can create a new request. This is deliberate: no secret vault, no stale credentials.

Can I use it over SSH or in a dev container? The daemon only listens on loopback. If your browser and agent run on the same machine, it works. For remote containers, forward the port over SSH and pair from that machine's browser session; do not expose port 4780 publicly. Remote/multi-user hosting is out of scope.

What about Windows? The code handles Windows process termination and paths, but CI currently tests macOS/Linux. Treat Windows as best-effort for now.

Is the browser UI built with shadcn/ui only? The UI uses shadcn/ui components, Radix primitives, Tailwind, and lucide icons. There are no third-party UI kits or external assets.

Development

npm ci
npm run typecheck
npm test
npm run build
  • npm run dev builds the web UI and starts the daemon without opening a browser.

  • npm run dev:web runs Vite on port 5173 and proxies /api to the daemon.

  • npm test runs node:test unit and integration tests, including auth, CSRF, Origin/Host rejection, SSE, MCP over HTTP, one-time submit, expiry, redaction, env writes, and stdio bridge behavior.

Project layout:

src/shared/   schemas, validation, redaction, env parser
src/server/   daemon, auth, policy, request service, delivery, audit
src/mcp/      stdio bridge
src/cli/      command-line entry point
src/web/      React + Vite + Tailwind + shadcn/ui
test/         node:test unit and integration tests

See PLAN.md for the detailed design and threat model, SECURITY.md for vulnerability reporting, and CONTRIBUTING.md for contribution guidelines.

License

MIT. See LICENSE.

Available Tools

6 tools
cancel_secret_requestCancel a pending secure input requestC
Destructive

Cancel pending input.

NameRequiredDescriptionDefault
requestIdYes

TDQS

C2.3/5.0
Behavior2/5

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

Annotations already declare destructiveHint=true and openWorldHint=false, so the safety profile is partially covered, but the description adds nothing about what cancellation actually does to an outstanding request, whether a canceled request can later be submitted, or whether the call is idempotent or errors on an already-completed request. With a destructive mutation and zero disclosure of its effect, this leaves a real gap.

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

Conciseness2/5

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

Two words is brief but not concise in the useful sense: nothing is front-loaded because nothing is explained. The size reflects under-specification rather than economy.

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 destructive mutation with no output schema, 0% parameter documentation, and five closely related siblings, the description does not give an agent enough to call it correctly or predict the result. It should at minimum identify the request identifier's source and the effect of cancellation.

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?

There is exactly one parameter (requestId) and schema description coverage is 0%, so the schema supplies only type and length constraints. The description never mentions requestId, how to obtain it, or which sibling returns it, leaving the parameter's semantics entirely undocumented.

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

Purpose3/5

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

The description pairs a verb (cancel) with a vague object ("pending input"), so the resource is only identifiable by leaning on the title, which says "secure input request." It is enough to know this cancels something pending, but it does not state the scope or distinguish it from siblings like check_secret_request or secureinput_status.

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 statement of when to use this versus the other five siblings (submit_inline_secret, check_secret_request, request_secret, secureinput_status, inline_request_status). The agent must infer that this is the teardown counterpart to request_secret on its own.

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

check_secret_requestCheck a pending secure input requestC
Read-only

Wait for request status. Use waitSeconds=45 to avoid repeated polling.

NameRequiredDescriptionDefault
requestIdYes
waitSecondsNo

TDQS

C2.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds one genuinely useful behavioral fact: the call can block up to the wait limit, which discourages polling loops. It does not describe what statuses come back or what happens at timeout, so the addition is modest.

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 short sentences with no padding, and the actionable invocation tip comes early. It is efficient, though the terseness contributes to the missing purpose and parameter context.

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 no annotations about returns, the description should say what a check yields (pending vs fulfilled, or how the secret is delivered) and what timeout means. None of that is present, so an agent cannot plan around the result.

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 both parameters. It only advises a waitSeconds value; the required requestId is never explained (e.g., that it comes from request_secret), and the 0-45 range and default of 30 are left to the schema alone.

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

Purpose2/5

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

"Wait for request status" gestures at a verb and resource but is close to restating the title, and it never says the subject is a pending secure input request or how it differs from siblings like inline_request_status and secureinput_status. An agent cannot tell from the description which of the several status tools to pick.

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?

The only guidance is "Use waitSeconds=45 to avoid repeated polling," which is an invocation tip rather than a when-to-use rule. There is no statement of when this tool is appropriate versus request_secret, submit_inline_secret, or the other status tools, and no prerequisites.

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

inline_request_statusC
Read-only

Wait for inline delivery status.

NameRequiredDescriptionDefault
requestIdYes
waitSecondsNo

TDQS

C2.6/5.0
Behavior3/5

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

Annotations already state readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the key trait that this call blocks/waits, but omits what happens on timeout, whether a timeout is an error or a status result, and polling behavior — meaningful gaps for a wait-style tool.

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

Conciseness3/5

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

One short sentence with zero filler, but it is under-specified rather than concise: the whole budget is spent on a vague noun phrase with no front-loaded detail about blocking or return shape.

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?

No output schema exists, so the description must carry the return-value burden, and it does not — an agent cannot tell whether this returns a status object, blocks until completion, or errors on timeout. With two parameters at 0% coverage and ambiguous sibling overlap, the definition is too thin.

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% and the description says nothing about requestId or waitSeconds — not even that waitSeconds is the max blocking duration with a default of 30 and a ceiling of 45, which is the single most important parameter semantic here. The description does not compensate for the coverage gap.

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

Purpose3/5

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

"Wait for inline delivery status" gives a verb (wait) and a resource (inline delivery status), so the gist is retrievable, but "inline delivery status" is opaque and it does not distinguish itself from siblings like check_secret_request or secureinput_status, which plausibly do similar status lookups.

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?

The word "Wait" weakly implies this is the blocking/polling variant versus a non-blocking check, but no when-to-use, when-not-to-use, or sibling alternative is named despite five closely related sibling tools being present.

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

request_secretRequest a secret from the userB

Collect secret input. Use {{fieldId}} in execute stdin/env, or map fields to write_env keys. Never put secrets in args. Returns requestId and status.

NameRequiredDescriptionDefault
cwdNo
titleYes
fieldsYes
deliveryYes
descriptionYes
waitSecondsNo
timeoutSecondsNo

TDQS

B3.1/5.0
Behavior3/5

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

Annotations already establish that this is a non-read-only, non-destructive, closed-world operation, and the description adds the important security constraint that secrets must never go in args. "Returns requestId and status" hints at an asynchronous flow, but waitSeconds, timeoutSeconds, and the return mode are never explained, so the agent cannot tell whether the call blocks or must be polled with check_secret_request.

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?

Three short sentences, front-loaded with the core action and followed by the two most important usage rules — no wasted words. The terseness is arguably over-compressed given the schema complexity, but the structure itself is clean.

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?

The tool has a complex nested delivery oneOf with three modes, 7 parameters at 0% schema description coverage, and no output schema. The description covers only two of the three delivery modes (return is missing) and omits the async/timeout semantics, so an agent must reverse-engineer the schema to call it correctly.

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 full burden, yet it only alludes to the fields' id values and write_env mapping keys. It says nothing about title, description, cwd, fields (up to 10, with type/label/required/pattern/autocomplete sub-properties), waitSeconds, or timeoutSeconds, leaving most of the 7 parameters undocumented anywhere.

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?

"Collect secret input" states a specific verb and resource, and the delivery-mode hints ({{fieldId}} in execute stdin/env, write_env keys) make clear this is a request-and-deliver flow rather than an inline submission. It does not name any sibling, so the distinction from submit_inline_secret or check_secret_request is left implicit.

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 description does give actionable usage for the delivery modes and the "never put secrets in args" rule, which shapes how the agent should call it. But there is no guidance on when to use this tool versus submit_inline_secret, check_secret_request, or cancel_secret_request, and no statement of prerequisites or when a request must be polled.

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

secureinput_statusSecureInput statusB
Read-only

Get input mode and pending request IDs.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds that the call returns input mode plus pending request IDs, but never explains what "input mode" values mean or how pending IDs relate to the other request tools.

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 filler. It is efficient, though it borders on under-specification given the unexplained domain term.

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 must carry the return contract, and it only sketches it: "input mode" and "pending request IDs" are named but not characterized. For a zero-param read tool that is acceptable but leaves real ambiguity about what an agent receives and how to use it.

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?

The tool takes zero parameters, so the schema leaves nothing to document; baseline is 4. The description correctly implies a no-argument, poll-style call.

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?

A specific verb ("Get") paired with two concrete outputs (input mode, pending request IDs) tells an agent what it retrieves. However, it does nothing to distinguish this from overlapping siblings like inline_request_status or check_secret_request, and "input mode" is left undefined.

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 when-to-use guidance, no exclusions, and no mention of the closely related sibling tools for checking secret/request status. The agent is left to infer that this is a general state poll rather than a per-request check.

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

submit_inline_secretSubmit encrypted secure inputC
Destructive

Submit an encrypted input envelope.

NameRequiredDescriptionDefault
ivYes
keyYes
versionYes
requestIdYes
ciphertextYes

TDQS

C2.2/5.0
Behavior2/5

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

Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is partly covered, but the description adds nothing: it does not say what gets consumed or destroyed (presumably the pending secret request), whether the operation is one-shot, or what happens on success or failure. No contradiction with annotations, but zero added value.

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

Conciseness3/5

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

A single short sentence with no filler and the action front-loaded, so there is no waste. However, for a five-parameter cryptographic submission tool this is under-specification rather than genuine conciseness.

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?

Given a destructive, open-world write with five strictly-patterned required parameters and no output schema, the description should explain the request lifecycle and payload construction. One sentence leaves the agent unable to build a valid call or understand the consequences.

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

Parameters1/5

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

Schema description coverage is 0% for five required parameters, and the description compensates with nothing. It never explains that key/iv are base64-encoded cryptographic material, that ciphertext carries the actual secret, or that requestId must reference an existing request — all of which are essential for correct invocation.

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

Purpose3/5

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

"Submit an encrypted input envelope" gives a verb and a resource, but it is essentially a paraphrase of the title ("Submit encrypted secure input") and leaves "envelope" undefined. It gives no hint of how this differs from siblings like request_secret or secureinput_status, so an agent cannot route on this alone.

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 when-to-use guidance, no prerequisites (e.g. a requestId must first come from request_secret), and no mention of alternatives such as inline_request_status for checking progress. The agent must infer the entire workflow from the sibling names.

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. 6 tool updates
    • First observedcancel_secret_request
    • First observedcheck_secret_request
    • First observedinline_request_status
    • First observedrequest_secret
    • First observedsecureinput_status
    • First observedsubmit_inline_secret

TDQS

C2.8/5.0

Scored across 6 tools

Disambiguation3/5

The set has overlapping status tools: inline_request_status, check_secret_request, and secureinput_status all report/wait on status, and submit_inline_secret vs request_secret could be confused as initiation paths. Descriptions help somewhat, but the inline-versus-secret request boundaries are not fully clear.

Naming Consistency3/5

Mostly snake_case, but the set mixes verb-first names (submit_inline_secret, check_secret_request, cancel_secret_request) with noun-status names (inline_request_status, secureinput_status). The 'secureinput' token also breaks the underscore pattern.

Tool Count4/5

Six tools are reasonable for a focused secure-input workflow. The only concern is that three status-related tools feel somewhat redundant, making it slightly over-scoped but still well within range.

Completeness4/5

The surface covers the core lifecycle: request creation, inline submission, status checks, and cancellation. Minor gaps exist around historical/listing or cleanup operations, but no obvious blocking dead end for the stated secure-input purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    C
    maintenance
    Enables AI agents to securely store and manage encrypted secrets locally while using them indirectly through environment-variable injection or file writes, so plaintext values never enter the agent's context.
    8
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI coding agents to securely inject API keys and secrets into environment files, configs, or commands without the agent ever seeing the secret values.
    1 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Secrets manager for AI coding agents. The model only sees secret names; values are injected into the child process at exec time, every command needs your approval in a native dialog, and output is redacted before it returns to the model.
    2
    70 PyPI
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets AI coding agents read project documentation and secret metadata, then use credentials by injecting them into child processes while redacting the values from all output. Agents can deploy, migrate databases, or SSH using real secrets without the values ever entering their context, transcripts, or logs.
    MIT