Skip to main content
Glama
vdoflip
by vdoflip

1pass-item-mcp

CI CodeQL License: MIT

A small, bounded MCP server that lets an AI agent (Claude Code, or any MCP client) use individual 1Password items, one approved command at a time, without ever seeing the secret.

  • Explicit allowlist. Only items listed in your config exist for the agent. Each item is pinned to the environment variable it goes into and the only commands that may receive it.

  • Approval on every use. The run tool is marked anthropic/requiresUserInteraction, so Claude Code asks you on every call, in every permission mode, with no "don't ask again". The 1Password app asks too, whenever its authorization has expired.

  • Never the value. The secret goes into the child process environment only. The agent gets exit code and output, with the secret (and common encodings of it) masked.

  • No shell, ever. Commands run as an argv list. Shells, interpreters, file readers, encoders and generic network tools can't be allowlisted.

Not affiliated with or endorsed by 1Password / AgileBits.

agent ──run_with_items(items=["github"], command=["gh","api","user"], reason="…")──►
          Claude Code: approve? (every call)
                          │ yes
        policy: item allowlisted? command allowed for it? args prefix? max_uses?
                binary unchanged since startup?
                          │ ok
        1Password: resolve op://Dev/GitHub PAT/token   (1Password app prompt if needed)
                          │
        exec gh api user  with GH_TOKEN=<secret>   (no shell, own process group, timeout)
                          │
◄── exit code + stdout/stderr, secret masked, size-capped ── audit log (no secrets)

Requirements

  • macOS or Linux, Python 3.10+ (uv recommended)

  • 1Password desktop app with Settings → Developer → Integrate with other apps enabled (for the default desktop backend). Alternatively a service account or the op CLI.

  • python3 on PATH for the Claude Code plugin's guard hook

Related MCP server: sandbox

Install

/plugin marketplace add vdoflip/1pass-item-mcp
/plugin install 1pass-item-mcp@1pass-item-mcp

The plugin starts the server with uvx (pinned to a release tag) and adds a guard hook (see Guard hook).

Any MCP client

uvx --from git+https://github.com/vdoflip/1pass-item-mcp@v0.1.0 1pass-item-mcp serve
# or, once published to PyPI:  uvx 1pass-item-mcp serve
{
  "mcpServers": {
    "1pass-item": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/vdoflip/1pass-item-mcp@v0.1.0", "1pass-item-mcp", "serve"]
    }
  }
}

Clients other than Claude Code may ignore requiresUserInteraction. Configure them to require approval for run_with_items.

Configure

1pass-item-mcp init       # writes ~/.config/1pass-item-mcp/config.toml (mode 600)
$EDITOR ~/.config/1pass-item-mcp/config.toml
1pass-item-mcp check      # validates config, resolves and pins commands
1pass-item-mcp check --resolve github   # test-fetch one item (value is not shown)
[onepassword]
backend = "desktop"            # desktop | service-account | cli
account = "my.1password.com"   # as shown in the 1Password app

[limits]
default_timeout_seconds = 60
max_timeout_seconds = 300
max_output_bytes = 65536
max_items_per_call = 5

[audit]
enabled = true                 # ~/.local/state/1pass-item-mcp/audit.jsonl

[items.github]
description = "GitHub token (read-only scopes) for the gh CLI"
ref = "op://Development/GitHub PAT/token"
env = "GH_TOKEN"
commands = ["gh"]
args_prefixes = [["api", "repos/"], ["pr", "view"], ["run", "list"]]
max_uses = 20

Key

Meaning

ref

op://vault/item[/section]/field (optionally ?attribute=otp)

env

Env var the secret is injected into. Loader, shell and OP_* variables are rejected

commands

Executable names (resolved on PATH at startup) or absolute paths. Must be non-empty

args_prefixes

Optional. Arguments must start with one of these sequences. Use it for multi-purpose CLIs

max_uses

Optional. Uses per server session

allow_project_code

Required to allowlist tools that run agent-editable code (npm, make, git, docker, terraform, …)

The config file and its directory must be owned by you and not group/world-writable. The server reads them once at startup. Restart the MCP server after editing.

Backends

Backend

How it authenticates

Notes

desktop (default)

1Password SDK desktop-app integration (DesktopAuth)

The app shows a prompt naming this process. Authorization is per process and expires after 10 min idle or when 1Password locks. Your whole account is reachable by this process, so the allowlist is what bounds the agent

service-account

Token in $OP_SERVICE_ACCOUNT_TOKEN (configurable) at startup

Token is removed from the environment after reading. Scope the service account to a dedicated vault. No interactive 1Password prompt

cli

op read via the 1Password CLI

Uses the CLI's own desktop integration or service account

Tools

Tool

Approval

What it does

list_items

normal

Lists aliases, descriptions, refs, env var, allowed commands/args, remaining uses, warnings. Never contacts 1Password

run_with_items

every call

items (aliases), command (argv list), reason (shown to you), optional cwd and timeout_seconds. Returns exit_code, stdout, stderr, truncation flags, timed_out, redactions

Guard hook (Claude Code plugin)

The plugin adds a PreToolUse hook so the MCP server stays the only route to 1Password:

  • Bash commands using the op CLI (also via full paths, env, sh -c, Python subprocess, …), op:// references, 1Password SDKs or tokens are denied

  • running 1pass-item-mcp from the shell is denied (it can't be used to start a second server with a different config)

  • writes to the config file/directory or to the installed plugin are denied

Security model

Protects against: an agent (or a prompt injection) reading secrets into its context, widening its own access, using items for commands you didn't intend, or running a swapped-out binary. Each use is approved by a person, and every request is logged locally.

Does not protect against:

  • The allowlisted program itself. Whatever you allowlist receives the secret. If it can print its environment, read arbitrary files (/proc/self/environ), send data to arbitrary hosts, or run plugins/extensions/aliases, the agent could get the secret through it. Prefer narrow CLIs and use args_prefixes (e.g. gh without extension, alias, or api to arbitrary hosts).

  • Masking is best effort. Literal, base64 (any alignment), hex, URL, JSON-escaped and reversed forms are masked. Arbitrary transformations are not. The command allowlist is the real boundary.

  • Same-user processes. The agent runs as you. The guard hook matches command text and can be evaded by obfuscation; the 1Password app prompt and per-call approval remain.

  • Output you approve. Command output (minus the secret) goes to the model.

  • Python memory hygiene. Secrets are dropped after use but can't be zeroed in Python.

See SECURITY.md to report a vulnerability.

Development

uv sync                 # creates .venv with dev dependencies
uv run pytest           # tests use fake 1Password backends; no account needed
uv run ruff check . && uv run ruff format --check . && uv run mypy

Releases: bump the version in pyproject.toml, src/onepass_item_mcp/__init__.py, claude-plugin/.claude-plugin/plugin.json and the tag in claude-plugin/.mcp.json (a test checks they agree), update CHANGELOG.md, then push a vX.Y.Z tag. The release workflow builds, publishes to PyPI (trusted publishing, pypi environment) and creates a GitHub release.

License

MIT © vdoflip

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to securely use secrets by running commands with environment-injected credentials and sanitizing output to prevent leakage.
    1
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to safely execute privileged commands by routing them to a human approver, who runs them outside the agent's context and returns the output to the model.
    5
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to look up stored logins by URL, name, or alias and use them without seeing the secrets, injecting authentication into HTTP requests, running commands with credentials in the environment and scrubbed output, and fetching 2FA codes, subject to per-credential policies and user approval.
    23
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables running shell commands and persistent sessions with secrets stored in local secure storage injected into child processes at exec time based on rules. Guarantees secret plaintext never reaches the model context, returning only names, masks, and redacted output.
    16
    1
    MIT