@wyattjoh/op-remote 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @wyattjoh/op-remote
|
|
2
|
+
|
|
3
|
+
CLI and MCP server for remote 1Password secret access with Telegram-based
|
|
4
|
+
approval. Designed for AI agents (Claude Code, etc.) that need secrets at
|
|
5
|
+
runtime without exposing them in plaintext config files or conversation context.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
1. The **MCP server** (`op-remote serve`) runs as a stdio MCP server, loaded
|
|
10
|
+
with the real secrets via `op run`. It exposes a `request_token` tool that
|
|
11
|
+
returns a one-time token and Unix socket path.
|
|
12
|
+
2. The **CLI** (`op-remote run`) is called by the agent with the token, a
|
|
13
|
+
`.env.tpl` file containing `op://` references, and the command to run. It
|
|
14
|
+
connects to the MCP server's Unix socket to request the resolved secrets.
|
|
15
|
+
3. The MCP server sends a **Telegram approval request** with inline buttons
|
|
16
|
+
(Approve, Reject, Auto-Approve, Stop). The approver can also reply with a
|
|
17
|
+
reason when rejecting.
|
|
18
|
+
4. On approval, secrets are injected into the subprocess environment. All
|
|
19
|
+
stdout/stderr output is **masked** to prevent secret leakage.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g @wyattjoh/op-remote
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or with Bun:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun install -g @wyattjoh/op-remote
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
### Environment variables
|
|
36
|
+
|
|
37
|
+
| Variable | Required | Description |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `REMOTE_OP_TELEGRAM_BOT_TOKEN` | Yes | Telegram bot token for sending approval requests |
|
|
40
|
+
| `REMOTE_OP_TELEGRAM_CHAT_ID` | Yes | Telegram chat ID to send approval messages to |
|
|
41
|
+
| `REMOTE_OP_TELEGRAM_APPROVER_IDS` | No | Comma-separated Telegram user IDs allowed to approve/reject (all users if unset) |
|
|
42
|
+
| `REMOTE_OP_TIMEOUT` | No | Approval timeout in seconds (default: `120`) |
|
|
43
|
+
|
|
44
|
+
The MCP server also needs the actual secrets loaded into its environment (the
|
|
45
|
+
ones referenced by `op://` URIs in your `.env.tpl` files). Use `op run` to
|
|
46
|
+
inject them.
|
|
47
|
+
|
|
48
|
+
### Env file format (`.env.tpl`)
|
|
49
|
+
|
|
50
|
+
The CLI reads a `.env.tpl` file that distinguishes secrets from plain config:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
# Plain values are passed through directly
|
|
54
|
+
DATABASE_HOST=localhost
|
|
55
|
+
DATABASE_PORT=5432
|
|
56
|
+
|
|
57
|
+
# op:// references are resolved via the MCP server
|
|
58
|
+
DATABASE_PASSWORD=op://Development/my-app-db/password
|
|
59
|
+
API_KEY=op://Development/my-app-api/credential
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Lines with `op://` values become secret requests. All other key-value pairs are
|
|
63
|
+
injected as plain environment variables. Comments and blank lines are ignored.
|
|
64
|
+
|
|
65
|
+
## MCP client configuration
|
|
66
|
+
|
|
67
|
+
### Claude Code (`.mcp.json`)
|
|
68
|
+
|
|
69
|
+
Add to your project's `.mcp.json` or `~/.claude/.mcp.json`:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"op-remote": {
|
|
75
|
+
"command": "op-remote",
|
|
76
|
+
"args": ["serve"],
|
|
77
|
+
"env": {
|
|
78
|
+
"REMOTE_OP_TELEGRAM_BOT_TOKEN": "your-bot-token",
|
|
79
|
+
"REMOTE_OP_TELEGRAM_CHAT_ID": "your-chat-id",
|
|
80
|
+
"DATABASE_PASSWORD": "the-actual-secret-value"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Using 1Password CLI (recommended)
|
|
88
|
+
|
|
89
|
+
Use `op run` so secrets never touch config files:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"op-remote": {
|
|
95
|
+
"command": "op",
|
|
96
|
+
"args": ["run", "--env-file=.env.tpl", "--", "op-remote", "serve"],
|
|
97
|
+
"env": {
|
|
98
|
+
"REMOTE_OP_TELEGRAM_BOT_TOKEN": "op://Development/op-remote-telegram/bot-token",
|
|
99
|
+
"REMOTE_OP_TELEGRAM_CHAT_ID": "op://Development/op-remote-telegram/chat-id"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Claude Code Plugin
|
|
107
|
+
|
|
108
|
+
op-remote is also available as a Claude Code plugin:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"mcpServers": {
|
|
113
|
+
"op-remote": {
|
|
114
|
+
"command": "npx",
|
|
115
|
+
"args": ["@wyattjoh/op-remote", "serve"]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Usage
|
|
122
|
+
|
|
123
|
+
### Agent workflow
|
|
124
|
+
|
|
125
|
+
The agent calls the `request_token` MCP tool, then uses the returned token and
|
|
126
|
+
socket path to run commands with secrets:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
op-remote run \
|
|
130
|
+
--token=TOKEN \
|
|
131
|
+
--sock=SOCKET_PATH \
|
|
132
|
+
--env-file=.env.tpl \
|
|
133
|
+
--reason="Running database migration" \
|
|
134
|
+
-- npm run migrate
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### MCP tools
|
|
138
|
+
|
|
139
|
+
| Tool | Description |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| `request_token` | Returns a one-time token and Unix socket path for authenticating with the CLI |
|
|
142
|
+
| `resume` | Request to resume a stopped session (requires Telegram approval) |
|
|
143
|
+
| `disable_auto_approve` | Turn off auto-approval, requiring Telegram approval for future requests |
|
|
144
|
+
|
|
145
|
+
### Telegram approval buttons
|
|
146
|
+
|
|
147
|
+
When a secret access request is sent to Telegram, the approver sees:
|
|
148
|
+
|
|
149
|
+
- **Approve** - allow this single request
|
|
150
|
+
- **Reject** - deny the request (prompts for a reason via reply)
|
|
151
|
+
- **Auto-Approve** - approve this and all future requests in the session
|
|
152
|
+
- **Stop** - reject and halt the session entirely (the agent is instructed to stop)
|
|
153
|
+
|
|
154
|
+
## Security
|
|
155
|
+
|
|
156
|
+
- **One-time tokens** prevent replay attacks. Each token can only be used once.
|
|
157
|
+
- **Unix socket permissions** are set to `0600`, restricting access to the current user.
|
|
158
|
+
- **Output masking** replaces secret values in stdout/stderr with `<redacted>`.
|
|
159
|
+
- **Token reservation** prevents concurrent use of the same token.
|
|
160
|
+
- **Approver restrictions** optionally limit who can approve requests via Telegram user IDs.
|
|
161
|
+
- **Timeout** ensures abandoned requests don't hang indefinitely.
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
bun install
|
|
167
|
+
bun run build # transpile to dist/ (Node.js target)
|
|
168
|
+
bun run lint # oxlint
|
|
169
|
+
bun run fmt # oxfmt
|
|
170
|
+
bun run typecheck # tsc --noEmit
|
|
171
|
+
bun test # run tests
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT
|