@wyattjoh/op-remote
CLI and MCP server for remote 1Password secret access with Telegram-based
approval. Designed for AI agents (Claude Code, etc.) that need secrets at
runtime without exposing them in plaintext config files or conversation context.
How it works
- At startup, the MCP server (
op-remote serve --env-file=.env.tpl)
reads the project's .env.tpl and uses op run to resolve every op://
reference into its own process environment. This happens once, while the
user is present to authenticate with 1Password. No .env.tpl means no
secrets are loaded and the pipeline is inert, so each project that needs
remote secret access must provide one.
- The server exposes a
request_token MCP tool that returns a one-time token
and Unix socket path.
- The CLI (
op-remote run) is called by the agent with the token, the
same .env.tpl, and the command to run. It connects to the MCP server's
Unix socket to request the secrets named in the file.
- The MCP server sends a Telegram approval request with inline buttons
(Approve, Reject, Auto-Approve, Stop). The approver can also reply with a
reason when rejecting.
- On approval, secrets are injected into the subprocess environment. All
stdout/stderr output is masked to prevent secret leakage.
Install
Claude Code Plugin (Recommended)
Install via the plugin marketplace:
/plugin marketplace add wyattjoh/claude-code-marketplace
/plugin install op-remote@wyattjoh-marketplace
Then configure the Telegram credentials via the plugin's user config. The
plugin's MCP config is pre-wired with --env-file=.env.tpl, so each project
that uses op-remote only needs a .env.tpl at its root listing the project's
op:// secret references (see Project .env.tpl
below).
npm (global)
npm install -g @wyattjoh/op-remote
Or with Bun:
bun install -g @wyattjoh/op-remote
Configuration
Environment variables
| Variable | Required | Description |
|---|
REMOTE_OP_TELEGRAM_BOT_TOKEN | Yes | Telegram bot token for sending approval requests |
REMOTE_OP_TELEGRAM_CHAT_ID | Yes | Telegram chat ID to send approval messages to |
REMOTE_OP_TELEGRAM_APPROVER_IDS | No | Comma-separated Telegram user IDs allowed to approve/reject (all users if unset) |
REMOTE_OP_TIMEOUT | No | Approval timeout in seconds (default: 120) |
When installed as the Claude Code plugin, the Telegram variables above are
supplied via the plugin's user config and do not need to be set manually.
Project .env.tpl (required)
Every project that wants remote secret access must have a .env.tpl file at
its root. The plugin's MCP config passes --env-file=.env.tpl to
op-remote serve, so at server startup the file is read and all op://
references are resolved via op run into the server's process environment.
The resolved secrets are what later requests from op-remote run draw from.
# Plain values are passed through directly
DATABASE_HOST=localhost
DATABASE_PORT=5432
# op:// references are resolved once at server startup
DATABASE_PASSWORD=op://Development/my-app-db/password
API_KEY=op://Development/my-app-api/credential
The same file format is consumed in two places:
- MCP server startup reads it to resolve
op:// references up front
(requires an interactive op session, so this happens while the user is
present).
op-remote run reads it to know which variable names to request from
the server and which plain values to pass through directly.
Lines with op:// values become secret requests. All other key-value pairs
are injected as plain environment variables. Comments and blank lines are
ignored. If .env.tpl is missing, the server starts normally but has no
secrets to serve, so no op-remote run invocation will succeed.
MCP client configuration
If you are not using the Claude Code plugin, add the server to your
.mcp.json or ~/.claude/.mcp.json. Pass --env-file=.env.tpl so the server
loads the project's secrets at startup:
{
"mcpServers": {
"op-remote": {
"command": "op-remote",
"args": ["serve", "--env-file=.env.tpl"],
"env": {
"REMOTE_OP_TELEGRAM_BOT_TOKEN": "your-bot-token",
"REMOTE_OP_TELEGRAM_CHAT_ID": "your-chat-id"
}
}
}
}
The server will shell out to op run --env-file=.env.tpl internally to
resolve the project's op:// references, so op must be installed and
authenticated at server start.