@mcpbridgeapp/cli 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +345 -2
- package/dist/agents/broken.d.ts +24 -0
- package/dist/agents/broken.js +31 -0
- package/dist/agents/broken.js.map +1 -0
- package/dist/agents/cli.d.ts +47 -0
- package/dist/agents/cli.js +270 -0
- package/dist/agents/cli.js.map +1 -0
- package/dist/agents/health.d.ts +38 -0
- package/dist/agents/health.js +53 -0
- package/dist/agents/health.js.map +1 -0
- package/dist/agents/ollama.d.ts +27 -0
- package/dist/agents/ollama.js +118 -0
- package/dist/agents/ollama.js.map +1 -0
- package/dist/agents/openai.d.ts +35 -0
- package/dist/agents/openai.js +168 -0
- package/dist/agents/openai.js.map +1 -0
- package/dist/agents/outcome.d.ts +34 -0
- package/dist/agents/outcome.js +96 -0
- package/dist/agents/outcome.js.map +1 -0
- package/dist/agents/permissions.d.ts +44 -0
- package/dist/agents/permissions.js +68 -0
- package/dist/agents/permissions.js.map +1 -0
- package/dist/agents/registry.d.ts +56 -0
- package/dist/agents/registry.js +167 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/shim.d.ts +35 -0
- package/dist/agents/shim.js +53 -0
- package/dist/agents/shim.js.map +1 -0
- package/dist/agents/types.d.ts +69 -0
- package/dist/agents/types.js +28 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/config.d.ts +99 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/connect.d.ts +35 -0
- package/dist/connect.js +124 -0
- package/dist/connect.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +269 -0
- package/dist/index.js.map +1 -0
- package/dist/limit.d.ts +14 -0
- package/dist/limit.js +33 -0
- package/dist/limit.js.map +1 -0
- package/dist/protocol.d.ts +175 -0
- package/dist/protocol.js +86 -0
- package/dist/protocol.js.map +1 -0
- package/dist/secrets.d.ts +27 -0
- package/dist/secrets.js +53 -0
- package/dist/secrets.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +97 -0
- package/dist/server.js.map +1 -0
- package/dist/tasks.d.ts +48 -0
- package/dist/tasks.js +103 -0
- package/dist/tasks.js.map +1 -0
- package/dist/tools.d.ts +25 -0
- package/dist/tools.js +71 -0
- package/dist/tools.js.map +1 -0
- package/dist/ui/page.d.ts +7 -0
- package/dist/ui/page.js +428 -0
- package/dist/ui/page.js.map +1 -0
- package/dist/ui/presets.d.ts +22 -0
- package/dist/ui/presets.js +57 -0
- package/dist/ui/presets.js.map +1 -0
- package/dist/ui/server.d.ts +38 -0
- package/dist/ui/server.js +567 -0
- package/dist/ui/server.js.map +1 -0
- package/package.json +93 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Syed Zeeshan Ali
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,346 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# mcpbridgeapp
|
|
4
|
+
|
|
5
|
+
**Let any AI app hand work to the AI tools on your own computer.**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@mcpbridgeapp/cli)
|
|
8
|
+
[](https://github.com/szeeshan896/mcpbridgeapp/actions/workflows/ci.yml)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
[Quick start](#quick-start) · [How it works](#how-it-works) · [Control panel](#the-control-panel) · [Agents](#agents-you-can-use) · [Safety](#safety) · [Reference](#reference)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/how-it-works.png" alt="AI apps such as claude.ai, ChatGPT and Claude Code send a task to the mcpbridge.app relay, which forwards it to your computer, where mcpbridgeapp runs Claude Code, Codex, Grok, Antigravity, DeepSeek, NVIDIA or Ollama and sends the answer back" width="100%">
|
|
16
|
+
|
|
17
|
+
You are chatting with Claude on your phone. Your laptop at home has Codex, Claude Code and
|
|
18
|
+
Grok signed in, each on a plan you already pay for. With mcpbridgeapp you can say:
|
|
19
|
+
|
|
20
|
+
> Ask codex through mcpbridgeapp to review `payment.ts` in my shop project.
|
|
21
|
+
|
|
22
|
+
Claude passes the task to your laptop. Codex runs there, reads the real files, and its
|
|
23
|
+
review comes back into the same chat. **One message, work done.**
|
|
24
|
+
|
|
25
|
+
- **Use the plans you already pay for.** mcpbridgeapp runs the AI command-line tools that are
|
|
26
|
+
signed in on your computer. No new subscription and no API key needed for them.
|
|
27
|
+
- **No keys on any server.** Logins and API keys stay on your computer. The relay only
|
|
28
|
+
passes messages along, so a breach there leaks no AI credentials.
|
|
29
|
+
- **Works from anywhere.** claude.ai on the web, the desktop app and your phone, ChatGPT,
|
|
30
|
+
Claude Code, Cursor, or any app that speaks [MCP](https://modelcontextprotocol.io).
|
|
31
|
+
- **A second opinion on tap.** Have one AI check another's work, or pick the model best at
|
|
32
|
+
the task: a free NVIDIA coding model, DeepSeek, a local Ollama model that never touches
|
|
33
|
+
the internet.
|
|
34
|
+
- **No terminal needed.** A control panel in your browser adds agents, keys and the
|
|
35
|
+
connection, and tests each agent with one click.
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
You need **[Node.js 22 or newer](https://nodejs.org)** on the computer where your AI
|
|
40
|
+
tools are installed. Check with `node --version`.
|
|
41
|
+
|
|
42
|
+
### A. From claude.ai, your phone, ChatGPT and other apps
|
|
43
|
+
|
|
44
|
+
1. **Create an account** at **[mcpbridge.app](https://mcpbridge.app)**. On the dashboard,
|
|
45
|
+
generate an **agent token**.
|
|
46
|
+
2. **Start the control panel** on your computer:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx -y @mcpbridgeapp/cli ui
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
It opens in your browser. Paste the agent token under **Relay connection**, then press
|
|
53
|
+
**Save & connect**. The panel turns **Online**. Keep that window open (you can minimise
|
|
54
|
+
it); while it runs, your agents are reachable.
|
|
55
|
+
3. **Add the connector in claude.ai.** Open **Customize → Connectors → Add custom
|
|
56
|
+
connector**, name it `mcpbridgeapp`, and use `https://mcpbridge.app/mcp` as the URL. Press
|
|
57
|
+
**Connect**, sign in, and press **Allow**. Nothing to paste. The same connector then
|
|
58
|
+
works in the Claude desktop app and on your phone.
|
|
59
|
+
4. **Ask.** In any chat, switch the mcpbridgeapp connector on (**+ → Connectors**) and say
|
|
60
|
+
*"list my mcpbridgeapp agents"*, then *"ask codex to …"*.
|
|
61
|
+
|
|
62
|
+
The dashboard shows the exact setup lines for Claude Code, Claude Desktop and Cursor, with
|
|
63
|
+
your own address filled in.
|
|
64
|
+
|
|
65
|
+
### B. Only Claude Code, on the same computer
|
|
66
|
+
|
|
67
|
+
You don't need an account or the relay. Claude Code starts mcpbridgeapp itself:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# macOS / Linux
|
|
71
|
+
claude mcp add -s user mcpbridgeapp -- npx -y @mcpbridgeapp/cli
|
|
72
|
+
|
|
73
|
+
# Windows (PowerShell or cmd)
|
|
74
|
+
claude mcp add -s user mcpbridgeapp -- cmd /c npx -y @mcpbridgeapp/cli
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Then, in Claude Code: *"ask gemini through mcpbridgeapp to review the caching layer in this
|
|
78
|
+
module"*. `-s user` makes it available in every folder, not just the current one.
|
|
79
|
+
|
|
80
|
+
### Install it for good (optional)
|
|
81
|
+
|
|
82
|
+
`npx` fetches the latest version each time. To install once instead:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install -g @mcpbridgeapp/cli
|
|
86
|
+
mcpbridgeapp ui # the control panel
|
|
87
|
+
mcpbridgeapp --agents # which agents are ready on this computer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## How it works
|
|
91
|
+
|
|
92
|
+
<img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/flow.png" alt="Sequence: claude.ai calls ask_agent on the relay; the relay forwards it to mcpbridgeapp on your computer; mcpbridgeapp runs codex in your folder; the answer is checked and returned the same way" width="100%">
|
|
93
|
+
|
|
94
|
+
1. Your AI app calls mcpbridgeapp's `ask_agent` tool. It names an agent (say `codex`), writes a
|
|
95
|
+
self-contained task, and can pass a folder on your computer.
|
|
96
|
+
2. The relay at mcpbridge.app forwards the call over a WebSocket that **your computer**
|
|
97
|
+
opened. Nothing on your computer listens for connections, so no ports to open and no
|
|
98
|
+
firewall rules.
|
|
99
|
+
3. mcpbridgeapp looks the agent up in **your** configuration and runs it, e.g.
|
|
100
|
+
`codex exec "<task>"` in that folder. The task is passed as a single argument with no
|
|
101
|
+
shell involved, so text in a prompt can never become a command.
|
|
102
|
+
4. The agent works the way it always does, signed in as you.
|
|
103
|
+
5. mcpbridgeapp **checks the answer** before calling it a success. An agent that exits normally
|
|
104
|
+
but only says *"I couldn't read the files"*, or stops after *"I'll start by reading
|
|
105
|
+
payment.ts"*, comes back as a failure that says why. A usage limit or an expired
|
|
106
|
+
sign-in is remembered, so the next call is told straight away instead of waiting.
|
|
107
|
+
6. The answer travels back the same way into your chat.
|
|
108
|
+
|
|
109
|
+
Close the laptop and the dashboard shows **offline**. That is the point, not a
|
|
110
|
+
limitation: the work happens where your logins are, which is why the server needs none.
|
|
111
|
+
|
|
112
|
+
## The control panel
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx -y @mcpbridgeapp/cli ui # or: mcpbridgeapp ui
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
<img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/control-panel.png" alt="The mcpbridgeapp control panel: relay connection Online as my-laptop, and a list of agents (antigravity, claude, codex, deepseek, gemini, grok, an NVIDIA model, ollama), each ready, with Test, Edit and Customise buttons" width="100%">
|
|
119
|
+
|
|
120
|
+
A page on your own computer (`http://127.0.0.1:8809`) that does everything this README does
|
|
121
|
+
with commands:
|
|
122
|
+
|
|
123
|
+
- **Connect to the relay.** Paste the agent token once. The page keeps the computer online
|
|
124
|
+
while it is open, reconnects by itself the next time you open it, and sends a newly added
|
|
125
|
+
agent to the relay straight away.
|
|
126
|
+
- **Add an agent from a preset.** NVIDIA (free tier), DeepSeek, Grok, OpenRouter, Groq,
|
|
127
|
+
Mistral, Ollama, or any OpenAI-compatible service or command-line tool. Paste the key,
|
|
128
|
+
press **List models**, pick one and save. To keep several models from one provider, tick
|
|
129
|
+
them under **Add several models at once**. Each becomes its own agent, named after its
|
|
130
|
+
model (`nvidia-qwen3-coder-480b`).
|
|
131
|
+
- **Test** any agent with a one-word prompt and see the answer or the exact error.
|
|
132
|
+
- **Allow edits or commands** per agent (see [Safety](#safety)).
|
|
133
|
+
|
|
134
|
+
**On Windows**, if you cloned the repository, double-click `start-ui.cmd`. Put a shortcut to
|
|
135
|
+
it on your desktop to start mcpbridgeapp with one click.
|
|
136
|
+
|
|
137
|
+
Keys and the agent token are saved in `~/.config/mcpbridge/secrets.json` on your computer.
|
|
138
|
+
They are never written to `config.json` and never sent to the relay. The page answers only on
|
|
139
|
+
127.0.0.1, and only to the browser that opened the link it printed.
|
|
140
|
+
|
|
141
|
+
## The dashboard
|
|
142
|
+
|
|
143
|
+
<img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/dashboard.png" alt="The mcpbridge.app dashboard: your machine is Online as my-laptop, with each agent listed as available and what it may do" width="100%">
|
|
144
|
+
|
|
145
|
+
[mcpbridge.app](https://mcpbridge.app) shows whether your computer is online and which agents
|
|
146
|
+
it offers. It is also where you manage tokens, turn on 2-step verification, and see and
|
|
147
|
+
disconnect the apps you have allowed.
|
|
148
|
+
|
|
149
|
+
## Agents you can use
|
|
150
|
+
|
|
151
|
+
| Agent | What it is | Needs |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| `claude` | Claude Code | `claude` installed and signed in |
|
|
154
|
+
| `codex` | OpenAI Codex CLI | `codex` installed and signed in |
|
|
155
|
+
| `grok` | Grok Build CLI | `grok` installed and signed in |
|
|
156
|
+
| `antigravity` | Google's Antigravity CLI (`agy`), Gemini models | `agy` installed and signed in |
|
|
157
|
+
| `gemini` | Gemini CLI | `gemini` installed and signed in |
|
|
158
|
+
| `ollama` | a model running locally in [Ollama](https://ollama.com) | Ollama and one pulled model. No account, works offline |
|
|
159
|
+
| anything else | DeepSeek, NVIDIA, xAI API, OpenRouter, Groq, Mistral, LM Studio, … | an API key, added in the control panel |
|
|
160
|
+
|
|
161
|
+
The first six are built in: install the tool, sign in once in a terminal, and it shows up.
|
|
162
|
+
Anything not installed is listed as unavailable, never silently broken. Check from a
|
|
163
|
+
terminal:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npx -y @mcpbridgeapp/cli --agents
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
✓ claude claude found on PATH
|
|
171
|
+
✓ codex codex found on PATH
|
|
172
|
+
✗ gemini gemini is not on PATH — install it or fix the command
|
|
173
|
+
✓ ollama Ollama at http://127.0.0.1:11434, using qwen3:latest
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Using these tools removes the key, not the quota: each one still spends its own plan's
|
|
177
|
+
limits.
|
|
178
|
+
|
|
179
|
+
## Tools your AI app gets
|
|
180
|
+
|
|
181
|
+
| Tool | What it does |
|
|
182
|
+
|---|---|
|
|
183
|
+
| `list_agents` | which agents exist, whether each is ready, what each may do, and whether your computer is online |
|
|
184
|
+
| `ask_agent` | give one agent a task, wait, get the answer |
|
|
185
|
+
| `start_task` | the same, but returns an id at once, for work longer than the app will wait |
|
|
186
|
+
| `get_task` | check on a started task: queued, running (with the output so far), or finished |
|
|
187
|
+
|
|
188
|
+
The agent you delegate to starts fresh. It cannot see your chat, so the calling AI writes a
|
|
189
|
+
complete task and passes `workingDirectory` when it is about code.
|
|
190
|
+
|
|
191
|
+
Every answer says honestly how it went:
|
|
192
|
+
|
|
193
|
+
- **`succeeded`** is true only if the agent actually did the work, not just because its
|
|
194
|
+
program exited normally.
|
|
195
|
+
- **`status`** in `list_agents` is `ready`, `unavailable`, `quota-exhausted`,
|
|
196
|
+
`sign-in-failed` or `directory-not-trusted`, with the last error and, when the agent
|
|
197
|
+
named one, when to retry. A limit is remembered for an hour, a failed sign-in for six,
|
|
198
|
+
and any success clears it.
|
|
199
|
+
- **`writesFiles`** and **`runsCommands`** say what the agent is allowed to do, so the
|
|
200
|
+
calling AI hands file-changing work only to an agent that can do it.
|
|
201
|
+
- **`diagnostics`** is short and to the point. `notes` carries what you should know about a
|
|
202
|
+
success, such as tokens spent or an answer cut short.
|
|
203
|
+
- On a **timeout**, whatever the agent had written so far comes back, marked incomplete.
|
|
204
|
+
- **Tasks queue.** Two delegations run at once by default. The rest wait their turn, and
|
|
205
|
+
`get_task` says where they are in the queue.
|
|
206
|
+
|
|
207
|
+
## Safety
|
|
208
|
+
|
|
209
|
+
mcpbridgeapp runs programs on your computer for apps on the internet, so it is careful by
|
|
210
|
+
default.
|
|
211
|
+
|
|
212
|
+
**Agents are read-only until you allow more.** Every agent starts unable to change files
|
|
213
|
+
or run commands. In the control panel, press **Edit** (or **Customise** for a built-in)
|
|
214
|
+
and tick what it may do. mcpbridgeapp turns that into the tool's own flags:
|
|
215
|
+
|
|
216
|
+
| CLI | Change files | Run commands |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| claude | `--permission-mode acceptEdits` | `--allowedTools Bash` |
|
|
219
|
+
| codex | `--sandbox workspace-write` (one switch for both; still no network) | same |
|
|
220
|
+
| grok | `--always-approve` (all or nothing) | same |
|
|
221
|
+
| gemini | `--approval-mode auto_edit` | `--approval-mode yolo` |
|
|
222
|
+
| agy (Antigravity) | `--mode accept-edits` | `--dangerously-skip-permissions` (allows edits too) |
|
|
223
|
+
|
|
224
|
+
Allow only what you are happy for every app connected to your account to do on your
|
|
225
|
+
computer. Some tools can't even read files without approval when no one is there to give
|
|
226
|
+
it: Grok Build, for one, reads with shell commands. Such an agent needs **Change files**
|
|
227
|
+
ticked before it can review code.
|
|
228
|
+
|
|
229
|
+
**Commands come only from your configuration.** A tool call can name an agent, never a
|
|
230
|
+
command. The prompt reaches the program as one argument with no shell, so `;`, `&&` and
|
|
231
|
+
backticks in a prompt arrive as plain text. A test checks exactly that.
|
|
232
|
+
|
|
233
|
+
**The relay holds no AI credentials.** It stores accounts, password hashes and token
|
|
234
|
+
hashes, never an API key or a CLI login. Tokens are shown once. claude.ai and Claude Code
|
|
235
|
+
sign in through OAuth with PKCE, and every app you allow is listed on the dashboard, where
|
|
236
|
+
you can disconnect it. 2-step verification with an authenticator app is available.
|
|
237
|
+
|
|
238
|
+
**Local servers stay local.** The control panel and the optional HTTP mode listen on
|
|
239
|
+
127.0.0.1 only, and refuse requests from other websites.
|
|
240
|
+
|
|
241
|
+
## Reference
|
|
242
|
+
|
|
243
|
+
### Commands
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
mcpbridgeapp MCP server over stdio (what Claude Code starts)
|
|
247
|
+
mcpbridgeapp ui [--port N] the control panel in your browser
|
|
248
|
+
mcpbridgeapp connect stay connected to the relay (uses the saved token,
|
|
249
|
+
[--relay URL --token T] or pass them here)
|
|
250
|
+
mcpbridgeapp --agents which agents are ready here
|
|
251
|
+
mcpbridgeapp --ask <agent> "…" delegate once from the terminal, to test an agent
|
|
252
|
+
mcpbridgeapp --http [port] one shared HTTP server on 127.0.0.1 (default 8808)
|
|
253
|
+
mcpbridgeapp --example-config print a starter config
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Configuration
|
|
257
|
+
|
|
258
|
+
Everything the control panel does is saved in `~/.config/mcpbridge/config.json` (set
|
|
259
|
+
`MCPBRIDGE_CONFIG` to use another file). You can also write it by hand. An entry replaces the
|
|
260
|
+
built-in agent of the same name.
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"maxConcurrent": 2,
|
|
265
|
+
"agents": {
|
|
266
|
+
"codex": {
|
|
267
|
+
"command": ["codex", "exec", "--skip-git-repo-check", "{prompt}"],
|
|
268
|
+
"allow": { "edits": true, "commands": true },
|
|
269
|
+
"timeoutMs": 600000
|
|
270
|
+
},
|
|
271
|
+
"deepseek": {
|
|
272
|
+
"type": "openai",
|
|
273
|
+
"baseUrl": "https://api.deepseek.com/v1",
|
|
274
|
+
"model": "<a model id: List models in the control panel shows them>",
|
|
275
|
+
"apiKeyEnv": "DEEPSEEK_API_KEY"
|
|
276
|
+
},
|
|
277
|
+
"local": { "type": "ollama", "model": "qwen3:latest" }
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
| Field | Meaning |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `command` | the program and its arguments. `{prompt}` is replaced by the task, as one argument |
|
|
285
|
+
| `promptVia` | `"argv"` (default) or `"stdin"`. Use stdin for long prompts: Windows limits an argument to about 32 KB |
|
|
286
|
+
| `allow` | `{ "edits": true, "commands": true, "trustDirectory": true }`, the same switches as the control panel |
|
|
287
|
+
| `capabilities` | for a CLI mcpbridgeapp doesn't know: declare `{ "writesFiles": true, "runsCommands": true }` yourself |
|
|
288
|
+
| `env` | extra environment variables for that agent |
|
|
289
|
+
| `timeoutMs` | how long one call may run (default 5 minutes) |
|
|
290
|
+
| `type: "openai"` | any service with `POST /v1/chat/completions`: `baseUrl`, `model`, `apiKeyEnv` |
|
|
291
|
+
| `type: "ollama"` | a local Ollama model: `model`, optional `baseUrl` |
|
|
292
|
+
| `maxConcurrent` | how many delegations run at once (default 2) |
|
|
293
|
+
|
|
294
|
+
`apiKeyEnv` is the **name** of an environment variable, not the key, so a config file can be
|
|
295
|
+
shared without leaking anything. Keys saved in the control panel go to `secrets.json` and are
|
|
296
|
+
loaded into that variable. A variable you export yourself still wins.
|
|
297
|
+
|
|
298
|
+
### Troubleshooting
|
|
299
|
+
|
|
300
|
+
| You see | What to do |
|
|
301
|
+
|---|---|
|
|
302
|
+
| Panel or dashboard says **offline** | Start `mcpbridgeapp ui` (or `mcpbridgeapp connect`) and keep its window open |
|
|
303
|
+
| `sign-in-failed`, *"session expired"* | Run that tool once in a terminal and sign in again |
|
|
304
|
+
| `quota-exhausted` | The tool's plan hit its limit. Wait for `retryAt`, or use another agent |
|
|
305
|
+
| Agent times out, or says it *needs permission* | It stopped at an approval prompt. Allow edits or commands for it, or ask only for a reading |
|
|
306
|
+
| Gemini CLI: `IneligibleTierError` | Google withdrew Gemini CLI for personal accounts. Use the built-in `antigravity` agent, same models, same login |
|
|
307
|
+
| `directory-not-trusted` | Tick *Trust the working directory* for that agent, if you trust the folders your apps send it |
|
|
308
|
+
| Codex: *not a git repository* | Point it at a git repository, or add `--skip-git-repo-check` to its command |
|
|
309
|
+
| Claude Code doesn't see the tools | Add it with `-s user`, then restart Claude Code. Check with `claude mcp list` |
|
|
310
|
+
|
|
311
|
+
**Windows:** npm-installed CLIs are `.cmd` files, which Node can't run without a shell, and a
|
|
312
|
+
prompt must never go through a shell. mcpbridgeapp reads the `.cmd` file and runs the real
|
|
313
|
+
program it points to, so `claude`, `codex` and the rest work as they are.
|
|
314
|
+
|
|
315
|
+
### Run your own relay
|
|
316
|
+
|
|
317
|
+
mcpbridge.app is one instance of the relay in [`relay/`](relay/README.md). You can host your
|
|
318
|
+
own: it is one Docker image with a SQLite database, and deploys to Railway, Fly.io or any
|
|
319
|
+
VPS. Accounts use email or phone, a password or Google, with optional 2-step verification.
|
|
320
|
+
|
|
321
|
+
## Development
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
git clone https://github.com/szeeshan896/mcpbridgeapp.git
|
|
325
|
+
cd mcpbridgeapp
|
|
326
|
+
npm install # also builds dist/
|
|
327
|
+
npm test # typecheck and tests
|
|
328
|
+
npm start # the stdio server, from source
|
|
329
|
+
cd relay && npm install && npm test
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
src/agents/ running each kind of agent: cli.ts, openai.ts, ollama.ts; judging an
|
|
334
|
+
answer (outcome.ts); remembered failures (health.ts); permission flags
|
|
335
|
+
(permissions.ts); Windows .cmd shims (shim.ts)
|
|
336
|
+
src/ui/ the control panel
|
|
337
|
+
src/connect.ts the outbound connection to a relay; src/protocol.ts its messages
|
|
338
|
+
src/tools.ts the four tools, shared by the local server and the relay path
|
|
339
|
+
src/tasks.ts background tasks and their queue
|
|
340
|
+
relay/ the hosted relay: accounts, OAuth, tokens, 2FA, dashboard, forwarding
|
|
341
|
+
test/fixtures/ a stand-in agent CLI, so the suite runs on Windows, macOS and Linux
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
[MIT](LICENSE) © Syed Zeeshan Ali
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Agent, type AgentResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stands in for an agent whose configuration could not be used.
|
|
4
|
+
*
|
|
5
|
+
* <p>Without this, one bad entry in the config file threw during startup and took the
|
|
6
|
+
* whole bridge with it — every other agent included — and over stdio the client saw only
|
|
7
|
+
* a process that died, with the reason going nowhere a person would look.
|
|
8
|
+
*/
|
|
9
|
+
export declare class BrokenAgent implements Agent {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
readonly readsFiles = false;
|
|
13
|
+
readonly writesFiles = false;
|
|
14
|
+
readonly runsCommands = false;
|
|
15
|
+
readonly timeoutMs = 0;
|
|
16
|
+
readonly requires = "a valid configuration";
|
|
17
|
+
constructor(name: string, reason: string);
|
|
18
|
+
get description(): string;
|
|
19
|
+
probe(): Promise<{
|
|
20
|
+
available: boolean;
|
|
21
|
+
detail: string;
|
|
22
|
+
}>;
|
|
23
|
+
run(): Promise<AgentResult>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { failed } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stands in for an agent whose configuration could not be used.
|
|
4
|
+
*
|
|
5
|
+
* <p>Without this, one bad entry in the config file threw during startup and took the
|
|
6
|
+
* whole bridge with it — every other agent included — and over stdio the client saw only
|
|
7
|
+
* a process that died, with the reason going nowhere a person would look.
|
|
8
|
+
*/
|
|
9
|
+
export class BrokenAgent {
|
|
10
|
+
name;
|
|
11
|
+
reason;
|
|
12
|
+
readsFiles = false;
|
|
13
|
+
writesFiles = false;
|
|
14
|
+
runsCommands = false;
|
|
15
|
+
timeoutMs = 0;
|
|
16
|
+
requires = 'a valid configuration';
|
|
17
|
+
constructor(name, reason) {
|
|
18
|
+
this.name = name;
|
|
19
|
+
this.reason = reason;
|
|
20
|
+
}
|
|
21
|
+
get description() {
|
|
22
|
+
return `misconfigured: ${this.reason}`;
|
|
23
|
+
}
|
|
24
|
+
async probe() {
|
|
25
|
+
return { available: false, detail: `misconfigured: ${this.reason}` };
|
|
26
|
+
}
|
|
27
|
+
async run() {
|
|
28
|
+
return failed(this.name, `agent "${this.name}" is misconfigured: ${this.reason}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=broken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broken.js","sourceRoot":"","sources":["../../src/agents/broken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IAQX;IACA;IARF,UAAU,GAAG,KAAK,CAAC;IACnB,WAAW,GAAG,KAAK,CAAC;IACpB,YAAY,GAAG,KAAK,CAAC;IACrB,SAAS,GAAG,CAAC,CAAC;IACd,QAAQ,GAAG,uBAAuB,CAAC;IAE5C,YACW,IAAY,EACZ,MAAc;QADd,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;IACtB,CAAC;IAEJ,IAAI,WAAW;QACb,OAAO,kBAAkB,IAAI,CAAC,MAAM,EAAE,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,GAAG;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,CAAC,IAAI,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;CACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { CliAgentConfig } from '../config.js';
|
|
2
|
+
import { type Permissions } from './permissions.js';
|
|
3
|
+
import { type Agent, type AgentResult, type RunOptions } from './types.js';
|
|
4
|
+
export declare const PROMPT_PLACEHOLDER = "{prompt}";
|
|
5
|
+
/**
|
|
6
|
+
* An agent that is a command-line tool. The command comes from configuration and the
|
|
7
|
+
* prompt only ever fills {prompt} or goes down stdin — never through a shell, so nothing
|
|
8
|
+
* in a prompt can be read as a shell metacharacter.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CliAgent implements Agent {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
private readonly config;
|
|
13
|
+
private readonly maxOutputChars;
|
|
14
|
+
readonly requires: string;
|
|
15
|
+
readonly readsFiles = true;
|
|
16
|
+
readonly permissions: Permissions;
|
|
17
|
+
constructor(name: string, config: CliAgentConfig, maxOutputChars: number);
|
|
18
|
+
get writesFiles(): boolean;
|
|
19
|
+
get runsCommands(): boolean;
|
|
20
|
+
get timeoutMs(): number;
|
|
21
|
+
private get promptVia();
|
|
22
|
+
get description(): string;
|
|
23
|
+
probe(): Promise<{
|
|
24
|
+
available: boolean;
|
|
25
|
+
detail: string;
|
|
26
|
+
}>;
|
|
27
|
+
run(prompt: string, options: RunOptions): Promise<AgentResult>;
|
|
28
|
+
private spawnAgent;
|
|
29
|
+
private startupAdvice;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Turns a spawn failure into something the caller can act on. The size limit varies by
|
|
33
|
+
* platform — roughly 128KB per argument on Linux, about 1MB on macOS, and as little as
|
|
34
|
+
* 32KB on Windows — so the advice names the setting that removes it rather than a number.
|
|
35
|
+
*/
|
|
36
|
+
export declare function startupAdvice(agent: string, command: string, error: Error & {
|
|
37
|
+
code?: string;
|
|
38
|
+
}, prompt: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* A .cmd or .bat can only be run through a shell, and running the prompt through a shell
|
|
41
|
+
* is exactly what this program must never do: quoting rules for batch files are their own
|
|
42
|
+
* minefield (see CVE-2024-27980). So such an agent is refused with the fix, rather than
|
|
43
|
+
* made to work unsafely or left to fail as a bare ENOENT.
|
|
44
|
+
*/
|
|
45
|
+
export declare function needsAShell(resolvedPath: string): boolean;
|
|
46
|
+
export declare function resolveOnPath(executable: string): Promise<string | null>;
|
|
47
|
+
export declare function onPath(executable: string): Promise<boolean>;
|