@apify/mcpc 0.2.4 → 0.3.0-beta.0
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/CHANGELOG.md +64 -1
- package/CONTRIBUTING.md +12 -0
- package/NOTICE +27 -0
- package/README.md +219 -226
- package/_config.yml +30 -0
- package/client-logo.svg +79 -0
- package/client-metadata.json +16 -0
- package/dist/bridge/index.js +51 -4
- package/dist/bridge/index.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +2 -0
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +32 -10
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/clean.d.ts.map +1 -1
- package/dist/cli/commands/clean.js +13 -2
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/grep.d.ts.map +1 -1
- package/dist/cli/commands/grep.js +39 -8
- package/dist/cli/commands/grep.js.map +1 -1
- package/dist/cli/commands/prompts.d.ts.map +1 -1
- package/dist/cli/commands/prompts.js +7 -26
- package/dist/cli/commands/prompts.js.map +1 -1
- package/dist/cli/commands/resources.d.ts.map +1 -1
- package/dist/cli/commands/resources.js +9 -3
- package/dist/cli/commands/resources.js.map +1 -1
- package/dist/cli/commands/sessions.d.ts +45 -2
- package/dist/cli/commands/sessions.d.ts.map +1 -1
- package/dist/cli/commands/sessions.js +493 -27
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/tasks.d.ts +1 -0
- package/dist/cli/commands/tasks.d.ts.map +1 -1
- package/dist/cli/commands/tasks.js +15 -1
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +6 -1
- package/dist/cli/commands/tools.d.ts.map +1 -1
- package/dist/cli/commands/tools.js +66 -14
- package/dist/cli/commands/tools.js.map +1 -1
- package/dist/cli/commands/x402.d.ts.map +1 -1
- package/dist/cli/commands/x402.js +7 -7
- package/dist/cli/commands/x402.js.map +1 -1
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +3 -6
- package/dist/cli/helpers.js.map +1 -1
- package/dist/cli/index.js +370 -131
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +18 -5
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +275 -89
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/parser.d.ts +4 -0
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +68 -24
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/shell.d.ts.map +1 -1
- package/dist/cli/shell.js +44 -21
- package/dist/cli/shell.js.map +1 -1
- package/dist/cli/tool-result.d.ts +1 -1
- package/dist/cli/tool-result.d.ts.map +1 -1
- package/dist/cli/tool-result.js +20 -15
- package/dist/cli/tool-result.js.map +1 -1
- package/dist/core/factory.d.ts +1 -0
- package/dist/core/factory.d.ts.map +1 -1
- package/dist/core/factory.js +3 -0
- package/dist/core/factory.js.map +1 -1
- package/dist/core/mcp-client.d.ts +1 -0
- package/dist/core/mcp-client.d.ts.map +1 -1
- package/dist/core/mcp-client.js +14 -0
- package/dist/core/mcp-client.js.map +1 -1
- package/dist/core/transports.d.ts +5 -1
- package/dist/core/transports.d.ts.map +1 -1
- package/dist/core/transports.js +26 -4
- package/dist/core/transports.js.map +1 -1
- package/dist/lib/auth/auth-page.d.ts +13 -0
- package/dist/lib/auth/auth-page.d.ts.map +1 -0
- package/dist/lib/auth/auth-page.js +129 -0
- package/dist/lib/auth/auth-page.js.map +1 -0
- package/dist/lib/auth/oauth-flow.d.ts +2 -1
- package/dist/lib/auth/oauth-flow.d.ts.map +1 -1
- package/dist/lib/auth/oauth-flow.js +65 -58
- package/dist/lib/auth/oauth-flow.js.map +1 -1
- package/dist/lib/auth/oauth-provider.d.ts +2 -0
- package/dist/lib/auth/oauth-provider.d.ts.map +1 -1
- package/dist/lib/auth/oauth-provider.js +6 -0
- package/dist/lib/auth/oauth-provider.js.map +1 -1
- package/dist/lib/auth/oauth-utils.d.ts +3 -0
- package/dist/lib/auth/oauth-utils.d.ts.map +1 -1
- package/dist/lib/auth/oauth-utils.js +32 -1
- package/dist/lib/auth/oauth-utils.js.map +1 -1
- package/dist/lib/auth/profiles.d.ts.map +1 -1
- package/dist/lib/auth/profiles.js +3 -3
- package/dist/lib/auth/profiles.js.map +1 -1
- package/dist/lib/bridge-manager.d.ts.map +1 -1
- package/dist/lib/bridge-manager.js +43 -28
- package/dist/lib/bridge-manager.js.map +1 -1
- package/dist/lib/cleanup.d.ts +5 -0
- package/dist/lib/cleanup.d.ts.map +1 -1
- package/dist/lib/cleanup.js +38 -1
- package/dist/lib/cleanup.js.map +1 -1
- package/dist/lib/config.d.ts +21 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +99 -5
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +4 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/session-client.d.ts +1 -0
- package/dist/lib/session-client.d.ts.map +1 -1
- package/dist/lib/session-client.js +7 -4
- package/dist/lib/session-client.js.map +1 -1
- package/dist/lib/sessions.d.ts.map +1 -1
- package/dist/lib/sessions.js +18 -9
- package/dist/lib/sessions.js.map +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +16 -2
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +112 -8
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/wallets.js +3 -3
- package/dist/lib/wallets.js.map +1 -1
- package/docs/TODOs.md +5 -0
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -1,30 +1,38 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mcpc — a universal MCP CLI client
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
that maps MCP operations to intuitive commands for interactive shell use, scripts, and AI coding agents.
|
|
3
|
+

|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@apify/mcpc)
|
|
6
|
+
[](https://www.npmjs.com/package/@apify/mcpc)
|
|
7
|
+
[](https://github.com/apify/mcpc/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/apify/mcpc/blob/main/LICENSE)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
`mcpc` is a command-line client for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
|
|
11
|
+
that maps MCP operations to intuitive commands for interactive shell use, scripting, and AI agents.
|
|
12
|
+
|
|
13
|
+
`mcpc` is your new Swiss Army knife for MCP. It's great for manual inspection and debugging of MCP servers,
|
|
14
|
+
as well as for agents to leverage all modern MCP capabilities through the most universal
|
|
15
|
+
coding interface: the UNIX shell.
|
|
11
16
|
|
|
12
17
|
**Key features:**
|
|
13
18
|
|
|
14
|
-
-
|
|
15
|
-
- 🔄 **Persistent sessions** - Keep multiple
|
|
16
|
-
-
|
|
17
|
-
- 🔌 **Code mode** - JSON output
|
|
18
|
-
-
|
|
19
|
-
-
|
|
19
|
+
- 🔧 **Full MCP support** - HTTP/stdio transports, instructions, tools, async tasks, resources, prompts, ...
|
|
20
|
+
- 🔄 **Persistent sessions** - Keep multiple stateful connections alive simultaneously.
|
|
21
|
+
- 🗺️ **Progressive tool discovery** - Find relevant MCP tools on the fly to save tokens and increase accuracy.
|
|
22
|
+
- 🔌 **Code mode** - JSON output composes with `jq`, `xargs`, and shell pipelines for MCP workflows as shell scripts.
|
|
23
|
+
- 🔒 **Secure** - Full OAuth 2.1 support with CMID and DCR, uses OS keychain for credentials storage.
|
|
24
|
+
- 🤖 **AI sandboxing** - Proxy MCP server connections to protect credentials from AI-generated code.
|
|
20
25
|
- 🪶 **Lightweight** - Minimal dependencies, works on Mac/Win/Linux, doesn't use LLMs on its own.
|
|
21
|
-
- 💸 **
|
|
26
|
+
- 💸 **Agentic payments** - Experimental support for the [x402](https://www.x402.org/) protocol on [Base](https://www.base.org/).
|
|
27
|
+
|
|
28
|
+

|
|
22
29
|
|
|
23
30
|
## Table of contents
|
|
24
31
|
|
|
25
32
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
26
33
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
27
34
|
|
|
35
|
+
- [Motivation](#motivation)
|
|
28
36
|
- [Install](#install)
|
|
29
37
|
- [Quickstart](#quickstart)
|
|
30
38
|
- [Usage](#usage)
|
|
@@ -43,6 +51,33 @@ After all, UNIX-compatible shell script is THE most universal coding language.
|
|
|
43
51
|
|
|
44
52
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
45
53
|
|
|
54
|
+
## Motivation
|
|
55
|
+
|
|
56
|
+
Many AI agents misuse MCP. They treat tools as prompt-time function calls, repeatedly injecting
|
|
57
|
+
tool definitions and results into the context. Tokens get wasted, context rots, the
|
|
58
|
+
agent gets slower and less reliable, and popular conclusion that: _"MCP sucks, CLIs are better"_.
|
|
59
|
+
|
|
60
|
+
`mcpc` challenges that narrative. It maps every MCP operation to an intuitive CLI command that
|
|
61
|
+
agents pick up from `--help` alone. Any agent with shell access gets full MCP support without
|
|
62
|
+
wiring up dozens of MCP functions. Just one `Bash()` tool, and `mcpc` handles the rest:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
┌──────────┐ Bash() ┌──────────┐ MCP ┌────────────┐
|
|
67
|
+
│ AI agent │ ────────────────────► │ mcpc │ ────────────────────► │ MCP server │
|
|
68
|
+
└──────────┘ └──────────┘ Sessions, OAuth, └────────────┘
|
|
69
|
+
Tools, Resources,
|
|
70
|
+
Prompts, Tasks,
|
|
71
|
+
x402, ...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
CLI is the perfect _local_ interface between agents and MCP, while MCP remains the
|
|
75
|
+
standard _remote_ interface for server discovery, authentication, payments, and access control.
|
|
76
|
+
The two aren't exclusive – they're complementary.
|
|
77
|
+
|
|
78
|
+
As a bonus, the same `mcpc` configuration, OAuth profiles, and live sessions can be shared across
|
|
79
|
+
many AI agents on the same machine. Authenticate once, reuse everywhere.
|
|
80
|
+
|
|
46
81
|
## Install
|
|
47
82
|
|
|
48
83
|
```bash
|
|
@@ -52,28 +87,14 @@ npm install -g @apify/mcpc
|
|
|
52
87
|
bun install -g @apify/mcpc
|
|
53
88
|
```
|
|
54
89
|
|
|
55
|
-
**Linux
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
without a keyring daemon, `mcpc` automatically falls back to a file-based credential store
|
|
59
|
-
(`~/.mcpc/credentials`, mode `0600`).
|
|
90
|
+
**Linux:** credentials use the OS keychain via the [Secret Service API](https://specifications.freedesktop.org/secret-service/).
|
|
91
|
+
GNOME/KDE desktops work out of the box. On headless/CI systems, `mcpc` falls back to a
|
|
92
|
+
file-based store (`~/.mcpc/credentials`, mode `0600`).
|
|
60
93
|
|
|
61
|
-
To
|
|
94
|
+
To force the keychain on headless systems, install `libsecret` + `gnome-keyring`
|
|
95
|
+
(via `apt-get`, `dnf`, or `pacman`) and run:
|
|
62
96
|
|
|
63
97
|
```bash
|
|
64
|
-
# Debian/Ubuntu
|
|
65
|
-
sudo apt-get install libsecret-1-0 gnome-keyring
|
|
66
|
-
|
|
67
|
-
# Fedora/RHEL/CentOS
|
|
68
|
-
sudo dnf install libsecret gnome-keyring
|
|
69
|
-
|
|
70
|
-
# Arch Linux
|
|
71
|
-
sudo pacman -S libsecret gnome-keyring
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
And then run `mcpc` as follows:
|
|
75
|
-
|
|
76
|
-
```
|
|
77
98
|
dbus-run-session -- bash -c "echo -n 'password' | gnome-keyring-daemon --unlock && mcpc ..."
|
|
78
99
|
```
|
|
79
100
|
|
|
@@ -106,6 +127,54 @@ mcpc @fs tools-list
|
|
|
106
127
|
<!-- AUTO-GENERATED: mcpc --help -->
|
|
107
128
|
|
|
108
129
|
```
|
|
130
|
+
Usage: mcpc [<@session>] [<command>] [options]
|
|
131
|
+
|
|
132
|
+
Universal command-line client for the Model Context Protocol (MCP).
|
|
133
|
+
|
|
134
|
+
Commands:
|
|
135
|
+
connect <server> [@session] Connect to an MCP server and start a new named @session
|
|
136
|
+
close <@session> Close a session
|
|
137
|
+
restart <@session> Restart a session (losing all state)
|
|
138
|
+
shell <@session> Open interactive shell for a session
|
|
139
|
+
login <server> Interactively login to a server using OAuth and save profile
|
|
140
|
+
logout <server> Delete an OAuth profile for a server
|
|
141
|
+
clean [resources...] Clean up mcpc data (sessions, profiles, logs, all)
|
|
142
|
+
grep <pattern> Search tools and instructions across all active sessions
|
|
143
|
+
x402 [subcommand] [args...] Configure an x402 payment wallet (EXPERIMENTAL)
|
|
144
|
+
help [command] [subcommand] Show help for a specific command
|
|
145
|
+
|
|
146
|
+
Options:
|
|
147
|
+
--json Output in JSON format for scripting
|
|
148
|
+
--verbose Enable debug logging
|
|
149
|
+
--profile <name> OAuth profile for the server ("default" if not provided)
|
|
150
|
+
--timeout <seconds> Request timeout in seconds (default: 300)
|
|
151
|
+
--max-chars <n> Truncate output to n characters (ignored in --json mode)
|
|
152
|
+
--insecure Skip TLS certificate verification (for self-signed certs)
|
|
153
|
+
-v, --version Output the version number
|
|
154
|
+
-h, --help Display help
|
|
155
|
+
|
|
156
|
+
MCP session commands (after connecting):
|
|
157
|
+
<@session> Show MCP server info, capabilities, and tools overview
|
|
158
|
+
<@session> grep <pattern> Search tools and instructions
|
|
159
|
+
<@session> tools-list List all server tools
|
|
160
|
+
<@session> tools-get <name> Get tool details and schema
|
|
161
|
+
<@session> tools-call <name> [arg:=val ... | <json> | <stdin]
|
|
162
|
+
<@session> prompts-list
|
|
163
|
+
<@session> prompts-get <name> [arg:=val ... | <json> | <stdin]
|
|
164
|
+
<@session> resources-list
|
|
165
|
+
<@session> resources-read <uri>
|
|
166
|
+
<@session> resources-subscribe <uri>
|
|
167
|
+
<@session> resources-unsubscribe <uri>
|
|
168
|
+
<@session> resources-templates-list
|
|
169
|
+
<@session> tasks-list
|
|
170
|
+
<@session> tasks-get <taskId>
|
|
171
|
+
<@session> tasks-result <taskId>
|
|
172
|
+
<@session> tasks-cancel <taskId>
|
|
173
|
+
<@session> logging-set-level <level>
|
|
174
|
+
<@session> ping
|
|
175
|
+
|
|
176
|
+
Run "mcpc" without arguments to show active sessions and OAuth profiles.
|
|
177
|
+
Run "mcpc --json" to get the same data as `{ sessions: [...], profiles: [...] }`.
|
|
109
178
|
```
|
|
110
179
|
|
|
111
180
|
### General actions
|
|
@@ -170,44 +239,15 @@ echo '{"greeting":"hello","count":10}' | mcpc @session tools-call <tool-name>
|
|
|
170
239
|
cat args.json | mcpc @session tools-call <tool-name>
|
|
171
240
|
```
|
|
172
241
|
|
|
173
|
-
**
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
- `enabled:=true` → boolean `true`
|
|
179
|
-
- `greeting:=hello` → string `"hello"` (not valid JSON, so string)
|
|
180
|
-
- `id:='"123"'` → string `"123"` (JSON string literal)
|
|
181
|
-
- Inline JSON: If first argument starts with `{` or `[`, it's parsed as a JSON object/array
|
|
182
|
-
- Stdin: When no positional args are provided and input is piped, reads JSON from stdin
|
|
183
|
-
|
|
184
|
-
**Using shell variables:**
|
|
185
|
-
|
|
186
|
-
When using shell variables that may contain spaces, use double quotes around the entire argument:
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
# Variable with spaces - use double quotes
|
|
190
|
-
QUERY="hello world"
|
|
191
|
-
mcpc @server tools-call search "query:=${QUERY}"
|
|
192
|
-
|
|
193
|
-
# Multiple variables
|
|
194
|
-
CITY="New York"
|
|
195
|
-
TYPE="restaurants"
|
|
196
|
-
mcpc @server tools-call search "query:=${CITY} ${TYPE}"
|
|
197
|
-
|
|
198
|
-
# For complex inputs, consider using JSON via stdin
|
|
199
|
-
echo "{\"query\": \"${QUERY}\", \"limit\": 10}" | mcpc @server tools-call search
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
**Common pitfall:** Don't put spaces around `:=` - it won't work:
|
|
242
|
+
**Auto-parsing rules** for `key:=value`: valid JSON keeps its type
|
|
243
|
+
(`count:=10` → number, `enabled:=true` → boolean, `cfg:='{"k":"v"}'` → object); anything
|
|
244
|
+
else is a string (`greeting:=hello` → `"hello"`). Force a string literal with JSON quotes:
|
|
245
|
+
`id:='"123"'`. Inline JSON is detected when the first arg starts with `{` or `[`. Stdin is
|
|
246
|
+
read when no positional args are given and input is piped.
|
|
203
247
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
# Correct - no spaces around :=
|
|
209
|
-
mcpc @server tools-call search "query:=hello world"
|
|
210
|
-
```
|
|
248
|
+
**Pitfalls:** no spaces around `:=` (use `query:=hello world`, not `query := ...`); quote
|
|
249
|
+
the whole argument when it contains shell expansions (`"query:=${VAR}"`). For complex
|
|
250
|
+
inputs, prefer piping JSON via stdin.
|
|
211
251
|
|
|
212
252
|
### Interactive shell
|
|
213
253
|
|
|
@@ -251,7 +291,7 @@ By default, `grep` searches only tools. Use `--resources` or `--prompts` to sear
|
|
|
251
291
|
(combine with `--tools` to include tools too). Sessions that are crashed or unavailable are shown
|
|
252
292
|
with their status rather than silently skipped.
|
|
253
293
|
|
|
254
|
-
The `grep` command is useful for **dynamic tool discovery**,
|
|
294
|
+
The `grep` command is useful for **dynamic tool discovery**,
|
|
255
295
|
also called [Tool search tool](https://www.anthropic.com/engineering/advanced-tool-use) by Anthropic
|
|
256
296
|
or [Dynamic context discovery](https://cursor.com/blog/dynamic-context-discovery) by Cursor.
|
|
257
297
|
Rather than loading all tools into AI agent's context, the agent can use `grep` to discover the right tool
|
|
@@ -303,59 +343,25 @@ mcpc @apify close # or: mcpc close @apify
|
|
|
303
343
|
|
|
304
344
|
### Session lifecycle
|
|
305
345
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
Still, sessions can fail due to network disconnects, bridge process crash, or server dropping it.
|
|
346
|
+
Session metadata is saved in `~/.mcpc/sessions.json`, [authentication tokens](#authentication)
|
|
347
|
+
in the OS keychain. The bridge process keeps the session alive with periodic [pings](#ping)
|
|
348
|
+
and auto-reconnects on network failures or its own crashes (10s cooldown on failed retries).
|
|
310
349
|
|
|
311
350
|
**Session states:**
|
|
312
351
|
|
|
313
|
-
| State
|
|
314
|
-
|
|
|
315
|
-
|
|
|
316
|
-
|
|
|
317
|
-
|
|
|
318
|
-
|
|
|
319
|
-
|
|
|
320
|
-
|
|
|
321
|
-
|
|
|
322
|
-
|
|
323
|
-
Here's how `mcpc` handles various bridge process and server connection states:
|
|
324
|
-
|
|
325
|
-
- While the **bridge process is running**:
|
|
326
|
-
- If **server positively responds** to pings, the session is marked 🟢 **`live`**, and everything is fine.
|
|
327
|
-
- If **server stops responding**, the session is marked 🟡 **`disconnected`**.
|
|
328
|
-
The bridge will keep trying to reconnect in the background and will return to 🟢 **`live`** once the server responds again.
|
|
329
|
-
- If **server rejects authentication** (HTTP 401 or 403) or token refresh fails,
|
|
330
|
-
the session is marked 🔴 **`unauthorized`**.
|
|
331
|
-
`mcpc` will auto-reconnect in the background if another session sharing the same OAuth profile has refreshed the tokens.
|
|
332
|
-
Otherwise, re-authenticate with `mcpc login <server>` and then `mcpc @my-session restart`.
|
|
333
|
-
- If **server rejects the session ID** (HTTP 404), indicating the MCP session is no longer valid,
|
|
334
|
-
the session is marked 🔴 **`expired`**.
|
|
335
|
-
You need to restart the session with `mcpc @my-session restart` to establish a new connection.
|
|
336
|
-
- If the **bridge process crashes**, `mcpc` will mark the session as 🟡 **`crashed`**
|
|
337
|
-
and auto-reconnect the bridge in the background. You can also trigger reconnection manually
|
|
338
|
-
by running any `mcpc @my-session ...` command.
|
|
339
|
-
- If reconnection **succeeds** and the server resumes the MCP session, the session returns to 🟢 **`live`**.
|
|
340
|
-
- If the server issues a **new session ID** instead of resuming, the session is marked 🔴 **`expired`**.
|
|
341
|
-
- If reconnection **fails**, the session remains 🟡 **`crashed`** and retries after a 10-second cooldown.
|
|
342
|
-
|
|
343
|
-
Note that `mcpc` never automatically removes sessions from the list.
|
|
344
|
-
Instead, it keeps them flagged as 🟡 **`crashed`**, 🔴 **`unauthorized`**, or 🔴 **`expired`**,
|
|
345
|
-
and any future attempts to use them will show the appropriate error with recovery instructions.
|
|
346
|
-
|
|
347
|
-
To **remove the session from the list**, you need to explicitly close it:
|
|
352
|
+
| State | Meaning |
|
|
353
|
+
| ----------------- | ----------------------------------------------------------------------------------------------- |
|
|
354
|
+
| 🟢 `live` | Bridge process running and server responding |
|
|
355
|
+
| 🟡 `connecting` | Initial bridge startup in progress (`mcpc connect`) |
|
|
356
|
+
| 🟡 `reconnecting` | Bridge crashed or lost auth; auto-reconnecting in the background |
|
|
357
|
+
| 🟡 `disconnected` | Bridge process running but server unreachable; auto-recovers when server responds |
|
|
358
|
+
| 🟡 `crashed` | Bridge process crashed or was killed; auto-reconnects in the background |
|
|
359
|
+
| 🔴 `unauthorized` | Server rejected authentication (401/403) or token refresh failed; re-run `login` then `restart` |
|
|
360
|
+
| 🔴 `expired` | Server rejected session ID (404); requires `restart` |
|
|
348
361
|
|
|
349
|
-
|
|
350
|
-
mcpc @apify
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
You can restart a session anytime, which kills the bridge process
|
|
354
|
-
and opens new connection with new `MCP-Session-Id`, by running:
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
mcpc @apify restart # or: mcpc restart @apify
|
|
358
|
-
```
|
|
362
|
+
`mcpc` never removes sessions automatically — failed ones stay flagged with a recovery hint
|
|
363
|
+
in the error message. Use `mcpc @apify restart` to kill the bridge and open a fresh
|
|
364
|
+
`MCP-Session-Id`, or `mcpc @apify close` to remove the session entirely.
|
|
359
365
|
|
|
360
366
|
## Authentication
|
|
361
367
|
|
|
@@ -388,9 +394,12 @@ mcpc @apify tools-list
|
|
|
388
394
|
|
|
389
395
|
### OAuth profiles
|
|
390
396
|
|
|
391
|
-
For OAuth-enabled remote MCP servers, `mcpc` implements the full OAuth 2.1 flow with PKCE
|
|
392
|
-
|
|
393
|
-
|
|
397
|
+
For OAuth-enabled remote MCP servers, `mcpc` implements the full OAuth 2.1 flow with PKCE as
|
|
398
|
+
mandated by the [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization):
|
|
399
|
+
`WWW-Authenticate` 401 challenges, Protected Resource Metadata and authorization server metadata
|
|
400
|
+
discovery, all three [client registration approaches](#client-registration-approaches),
|
|
401
|
+
[resource indicators (RFC 8707)](https://www.rfc-editor.org/rfc/rfc8707), and automatic
|
|
402
|
+
refresh-token rotation.
|
|
394
403
|
|
|
395
404
|
The OAuth authentication **always** needs to be initiated by the user calling the `login` command,
|
|
396
405
|
which opens a web browser with login screen. `mcpc` never opens the web browser on its own.
|
|
@@ -433,83 +442,72 @@ mcpc logout mcp.apify.com
|
|
|
433
442
|
mcpc logout mcp.apify.com --profile work
|
|
434
443
|
```
|
|
435
444
|
|
|
436
|
-
###
|
|
437
|
-
|
|
438
|
-
When multiple authentication methods are available, `mcpc` uses this precedence order:
|
|
439
|
-
|
|
440
|
-
1. **Command-line `--header` flag** (highest priority) - Always used if provided
|
|
441
|
-
2. **Saved authentication profiles** - OAuth tokens from saved profile
|
|
442
|
-
3. **Config file headers** - Headers from `--config` file for the server
|
|
443
|
-
4. **No authentication** - Attempts unauthenticated connection
|
|
444
|
-
|
|
445
|
-
**Note:** `--profile` and `--header "Authorization: ..."` cannot be combined — they are mutually
|
|
446
|
-
exclusive. Providing both will result in a clear error. Use one or the other.
|
|
445
|
+
### Client registration approaches
|
|
447
446
|
|
|
448
|
-
`mcpc`
|
|
447
|
+
When logging in, `mcpc` supports all three OAuth client registration approaches defined in the
|
|
448
|
+
[MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-registration-approaches),
|
|
449
|
+
picking the one the authorization server advertises in its OAuth metadata:
|
|
449
450
|
|
|
450
|
-
**
|
|
451
|
+
| **Approach** | **`mcpc login` flags** |
|
|
452
|
+
| :-------------------------------------- | :-------------------------------------------------- |
|
|
453
|
+
| **Pre-registration** | `--client-id` (and optional `--client-secret`) |
|
|
454
|
+
| **Client ID Metadata Documents (CIMD)** | default (or `--client-metadata-url <url>`) |
|
|
455
|
+
| **Dynamic Client Registration (DCR)** | fallback (or force with `--no-client-metadata-url`) |
|
|
451
456
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
457
|
+
`mcpc` ships with a hosted [Client ID Metadata Document](https://apify.github.io/mcpc/client-metadata.json)
|
|
458
|
+
so every installation presents the same client identity to CIMD-capable authorization servers.
|
|
459
|
+
When the authorization server advertises `client_id_metadata_document_supported: true`, the CIMD
|
|
460
|
+
URL is used as the `client_id`; otherwise mcpc falls back to Dynamic Client Registration.
|
|
455
461
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
- If authentication succeeds → Continue with command/session
|
|
460
|
-
- If authentication fails (expired/invalid) → Fail with an error
|
|
461
|
-
2. **Profile doesn't exist**: Fail with an error
|
|
462
|
-
|
|
463
|
-
**When `--x402` is specified (without `--profile`):**
|
|
464
|
-
|
|
465
|
-
- OAuth profile auto-detection is skipped, since x402 serves as the payment/auth mechanism
|
|
466
|
-
- If you also pass `--profile`, the specified profile is still used alongside x402
|
|
462
|
+
```bash
|
|
463
|
+
# Default: mcpc's hosted CIMD is used automatically (no flags needed).
|
|
464
|
+
mcpc login mcp.apify.com
|
|
467
465
|
|
|
468
|
-
|
|
466
|
+
# Pre-registered OAuth client (public or confidential) — skips CIMD.
|
|
467
|
+
mcpc login mcp.example.com --client-id <id> [--client-secret <secret>]
|
|
469
468
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
- Can be combined with `--header "Authorization: ..."` for explicit bearer token without profile
|
|
469
|
+
# Custom CIMD: override the default with your own hosted document.
|
|
470
|
+
mcpc login mcp.example.com --client-metadata-url https://example.com/my-client.json
|
|
473
471
|
|
|
474
|
-
|
|
472
|
+
# Disable CIMD: force Dynamic Client Registration even if the server supports CIMD.
|
|
473
|
+
mcpc login mcp.example.com --no-client-metadata-url
|
|
474
|
+
```
|
|
475
475
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
- If authentication fails (expired/invalid) → Fail with an error
|
|
479
|
-
2. **`default` profile doesn't exist**: Attempt unauthenticated connection
|
|
480
|
-
- If server accepts (no auth required) → Continue without creating profile
|
|
481
|
-
- If server rejects with 401 + `WWW-Authenticate` → Fail with an error
|
|
476
|
+
See the [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-registration-approaches)
|
|
477
|
+
for details on each approach and the format of Client ID Metadata Documents.
|
|
482
478
|
|
|
483
|
-
|
|
479
|
+
### Authentication precedence
|
|
484
480
|
|
|
485
|
-
|
|
481
|
+
When connecting, `mcpc` picks one auth source based on the flags you pass — explicit flags
|
|
482
|
+
always win over stored profiles, and credentials are never silently downgraded. If a profile
|
|
483
|
+
is missing, expired, or invalid, `mcpc` fails with an error that includes the right
|
|
484
|
+
`mcpc login` command to recover.
|
|
486
485
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
486
|
+
| Flag | Behavior |
|
|
487
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
488
|
+
| `--header "Authorization: ..."` | Use explicit header; skip OAuth auto-detection. Cannot combine with `--profile`. |
|
|
489
|
+
| `--profile <name>` | Require the named profile to exist. |
|
|
490
|
+
| `--no-profile` | Connect anonymously even if a `default` profile exists. |
|
|
491
|
+
| `--x402` | Skip OAuth auto-detection; use x402 payments instead. Combine with `--profile` to use both. |
|
|
492
|
+
| _(none)_ | Use `default` profile if it exists; otherwise connect anonymously. |
|
|
490
493
|
|
|
491
|
-
|
|
494
|
+
Config file headers (from `--config`) apply to servers loaded from that file.
|
|
492
495
|
|
|
493
496
|
```bash
|
|
494
|
-
#
|
|
495
|
-
# - Uses 'work' if it exists
|
|
496
|
-
# - Fails if it doesn't exist
|
|
497
|
-
mcpc connect mcp.apify.com @apify-work --profile work
|
|
498
|
-
|
|
499
|
-
# Without profile - opportunistic authentication:
|
|
500
|
-
# - Uses 'default' if it exists
|
|
501
|
-
# - Tries unauthenticated if 'default' doesn't exist
|
|
502
|
-
# - Fails if the server requires authentication
|
|
497
|
+
# Default: 'default' profile if it exists, else anonymous
|
|
503
498
|
mcpc connect mcp.apify.com @apify-personal
|
|
504
499
|
|
|
505
|
-
#
|
|
506
|
-
mcpc connect mcp.apify.com @apify --
|
|
500
|
+
# Specific profile (fails if missing)
|
|
501
|
+
mcpc connect mcp.apify.com @apify-work --profile work
|
|
507
502
|
|
|
508
|
-
#
|
|
509
|
-
mcpc connect mcp.apify.com @apify --
|
|
503
|
+
# Explicit bearer token (no profile)
|
|
504
|
+
mcpc connect mcp.apify.com @apify --header "Authorization: Bearer ${APIFY_TOKEN}"
|
|
510
505
|
|
|
511
|
-
#
|
|
506
|
+
# Skip default profile, connect anonymously
|
|
512
507
|
mcpc connect mcp.apify.com @apify-anon --no-profile
|
|
508
|
+
|
|
509
|
+
# x402 micropayments instead of OAuth
|
|
510
|
+
mcpc connect mcp.apify.com @apify --x402
|
|
513
511
|
```
|
|
514
512
|
|
|
515
513
|
## MCP proxy
|
|
@@ -592,22 +590,12 @@ mcpc @server tools-get search
|
|
|
592
590
|
mcpc @server tools-call search query:="hello world"
|
|
593
591
|
```
|
|
594
592
|
|
|
595
|
-
**Code mode** - Once agents understand the server's capabilities, they can write shell
|
|
596
|
-
that compose multiple `mcpc` commands with `--json` output
|
|
597
|
-
[
|
|
598
|
-
and use
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
# AI-generated script using --json for structured data
|
|
602
|
-
mcpc --json @apify tools-call search-actors keywords:="scraper" \
|
|
603
|
-
| jq '.content[0].text | fromjson | .items[0].id' \
|
|
604
|
-
| xargs -I {} mcpc @apify tools-call get-actor actorId:="{}"
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
With [schema validation](#schema-validation), agents can ensure stability of integrations and faster failure recovery.
|
|
608
|
-
Agents, make no harm!
|
|
609
|
-
|
|
610
|
-
See an [example](./docs/examples/company-lookup.sh) of an AI-generated shell script.
|
|
593
|
+
**Code mode** - Once agents understand the server's capabilities, they can write shell
|
|
594
|
+
scripts that compose multiple `mcpc` commands with `--json` output — see
|
|
595
|
+
[Scripting](#scripting) below. This can be
|
|
596
|
+
[more accurate](https://www.anthropic.com/engineering/code-execution-with-mcp) and use
|
|
597
|
+
fewer tokens than tool calling for complex workflows. Pair with
|
|
598
|
+
[schema validation](#schema-validation) to catch breaking changes early.
|
|
611
599
|
|
|
612
600
|
### Scripting
|
|
613
601
|
|
|
@@ -630,12 +618,15 @@ For a complete example script, see [`docs/examples/company-lookup.sh`](./docs/ex
|
|
|
630
618
|
|
|
631
619
|
### Schema validation
|
|
632
620
|
|
|
633
|
-
|
|
621
|
+
The `tools-get` and `tools-call` commands support `--schema` to validate a tool's schema against an expected snapshot. This helps detect breaking changes early in scripts and CI:
|
|
634
622
|
|
|
635
623
|
```bash
|
|
636
624
|
# Save expected schema
|
|
637
625
|
mcpc --json @apify tools-get search-actors > expected.json
|
|
638
626
|
|
|
627
|
+
# Validate without calling (read-only check)
|
|
628
|
+
mcpc @apify tools-get search-actors --schema expected.json
|
|
629
|
+
|
|
639
630
|
# Validate before calling (fails if schema changed incompatibly)
|
|
640
631
|
mcpc @apify tools-call search-actors --schema expected.json keywords:="test"
|
|
641
632
|
```
|
|
@@ -738,10 +729,10 @@ mcpc x402 sign <base64-payment-required> --amount 1.00 --expiry 3600 --json
|
|
|
738
729
|
|
|
739
730
|
**Options:**
|
|
740
731
|
|
|
741
|
-
| Option
|
|
742
|
-
|
|
|
743
|
-
| `--amount <usd>`
|
|
744
|
-
| `--expiry <seconds
|
|
732
|
+
| Option | Description |
|
|
733
|
+
| -------------------- | ------------------------------------------------------------- |
|
|
734
|
+
| `--amount <usd>` | Override the payment amount in USD (e.g. `0.50` for $0.50) |
|
|
735
|
+
| `--expiry <seconds>` | Override the payment expiry in seconds from now (e.g. `3600`) |
|
|
745
736
|
|
|
746
737
|
The command outputs the signed `PAYMENT-SIGNATURE` header value and an MCP config snippet
|
|
747
738
|
that can be used directly with other MCP clients.
|
|
@@ -812,7 +803,7 @@ The bridge process manages the full MCP session lifecycle:
|
|
|
812
803
|
| 🔔 [**Notifications**](#list-change-notifications) | ✅ Supported |
|
|
813
804
|
| 📄 [**Pagination**](#pagination) | ✅ Supported |
|
|
814
805
|
| 🏓 [**Ping**](#ping) | ✅ Supported |
|
|
815
|
-
| ⏳ [**Async tasks**](#async-tasks)
|
|
806
|
+
| ⏳ [**Async tasks**](#async-tasks) | ✅ Supported |
|
|
816
807
|
| 📁 **Roots** | 🚧 Planned |
|
|
817
808
|
| ❓ **Elicitation** | 🚧 Planned |
|
|
818
809
|
| 🔤 **Completion** | 🚧 Planned |
|
|
@@ -982,6 +973,9 @@ mcpc @apify tasks-list
|
|
|
982
973
|
# Check task status
|
|
983
974
|
mcpc @apify tasks-get <taskId>
|
|
984
975
|
|
|
976
|
+
# Get the task result (blocks until the task reaches a terminal state)
|
|
977
|
+
mcpc @apify tasks-result <taskId>
|
|
978
|
+
|
|
985
979
|
# Cancel a running task
|
|
986
980
|
mcpc @apify tasks-cancel <taskId>
|
|
987
981
|
```
|
|
@@ -989,6 +983,8 @@ mcpc @apify tasks-cancel <taskId>
|
|
|
989
983
|
With `--task`, the CLI shows a progress spinner with elapsed time, server status messages,
|
|
990
984
|
and progress notifications. Press **ESC** during execution to detach and get the task ID
|
|
991
985
|
for later retrieval. With `--detach`, the task starts and returns the task ID immediately.
|
|
986
|
+
Use `tasks-result <taskId>` to fetch the final `CallToolResult` payload once the task
|
|
987
|
+
completes.
|
|
992
988
|
|
|
993
989
|
`tools-list` and `tools-get` show task support annotations per tool:
|
|
994
990
|
`[task:optional]`, `[task:required]`, or `[task:forbidden]`.
|
|
@@ -1055,16 +1051,13 @@ For **stdio servers:**
|
|
|
1055
1051
|
- `args` (optional) - Array of command arguments
|
|
1056
1052
|
- `env` (optional) - Environment variables for the process
|
|
1057
1053
|
|
|
1058
|
-
**
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
mcpc @fs tools-list
|
|
1066
|
-
mcpc @fs tools-call search
|
|
1067
|
-
```
|
|
1054
|
+
> **Note:** Stdio servers inherit only a minimal env whitelist from the shell
|
|
1055
|
+
> (`PATH`, `HOME`, `SHELL`, …). Other vars — `NODE_EXTRA_CA_CERTS`, `HTTPS_PROXY`,
|
|
1056
|
+
> `SSL_CERT_FILE`, etc. — must be forwarded explicitly via the `env` block using
|
|
1057
|
+
> `${VAR_NAME}`. Anything the server writes to stderr is captured to
|
|
1058
|
+
> `~/.mcpc/logs/bridge-<session>.log` with a `[server stderr]` prefix, and the
|
|
1059
|
+
> tail is appended to the error message if `mcpc connect` fails, so you can see
|
|
1060
|
+
> why a stdio server failed to start.
|
|
1068
1061
|
|
|
1069
1062
|
**Environment variable substitution:**
|
|
1070
1063
|
|
|
@@ -1218,19 +1211,19 @@ See [CONTRIBUTING](./CONTRIBUTING.md) for development setup, architecture overvi
|
|
|
1218
1211
|
<!-- Stars, contributors, commits, and activity as of March 2026. -->
|
|
1219
1212
|
|
|
1220
1213
|
| Tool | Lang | Stars | Contrib / Commits | Active | Tools | Resources | Prompts | Tasks | Code mode | Sessions | OAuth | Stdio | HTTP | Tool search | x402 | LLM |
|
|
1221
|
-
| ----------------------------------------------------------------------- | ------ | ----: |
|
|
1222
|
-
| **[apify/mcpc](https://github.com/apify/mcpc)** | TS | ~420 |
|
|
1223
|
-
| [steipete/mcporter](https://github.com/steipete/mcporter) | TS | ~3.5k |
|
|
1224
|
-
| [IBM/mcp-cli](https://github.com/IBM/mcp-cli) | Python | ~1.9k |
|
|
1225
|
-
| [knowsuchagency/mcp2cli](https://github.com/knowsuchagency/mcp2cli) | Python | ~1.8k | 5 / ~76
|
|
1226
|
-
| [f/mcptools](https://github.com/f/mcptools) | Go | ~1.5k |
|
|
1227
|
-
| [philschmid/mcp-cli](https://github.com/philschmid/mcp-cli) | TS | ~1.1k | 2 / ~30
|
|
1228
|
-
| [adhikasp/mcp-client-cli](https://github.com/adhikasp/mcp-client-cli) | Python | ~670 | 6 / ~110
|
|
1229
|
-
| [thellimist/clihub](https://github.com/thellimist/clihub) | Go | ~640 | 1 / ~60
|
|
1230
|
-
| [wong2/mcp-cli](https://github.com/wong2/mcp-cli) | JS | ~430 | 4 / ~63
|
|
1231
|
-
| [mcpshim/mcpshim](https://github.com/mcpshim/mcpshim) | Go | ~54 | 1 / ~13
|
|
1232
|
-
| [evantahler/mcpx](https://github.com/evantahler/mcpx) | TS | ~28 | 1 / ~64
|
|
1233
|
-
| [EstebanForge/mcp-cli-ent](https://github.com/EstebanForge/mcp-cli-ent) | Go | ~15 | ~2 / ~46
|
|
1214
|
+
| ----------------------------------------------------------------------- | ------ | ----: | ----------------: | ------ | ----- | --------- | ------- | ----- | --------- | -------- | ----- | ----- | ---- | ----------- | ---- | --- |
|
|
1215
|
+
| **[apify/mcpc](https://github.com/apify/mcpc)** | TS | ~420 | 7 / ~510 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — |
|
|
1216
|
+
| [steipete/mcporter](https://github.com/steipete/mcporter) | TS | ~3.5k | 24 / ~570 | ✅ | ✅ | — | — | — | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | — |
|
|
1217
|
+
| [IBM/mcp-cli](https://github.com/IBM/mcp-cli) | Python | ~1.9k | 22 / ~790 | ✅ | ✅ | ✅ | ✅ | — | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | ✅ |
|
|
1218
|
+
| [knowsuchagency/mcp2cli](https://github.com/knowsuchagency/mcp2cli) | Python | ~1.8k | 5 / ~76 | ✅ | ✅ | ✅ | ✅ | — | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
1219
|
+
| [f/mcptools](https://github.com/f/mcptools) | Go | ~1.5k | 15 / ~170 | ⚠️ | ✅ | ✅ | ✅ | — | ✅ | — | — | ✅ | ✅ | — | — | — |
|
|
1220
|
+
| [philschmid/mcp-cli](https://github.com/philschmid/mcp-cli) | TS | ~1.1k | 2 / ~30 | ✅ | ✅ | — | — | — | ✅ | ✅ | — | ✅ | ✅ | ✅ | — | — |
|
|
1221
|
+
| [adhikasp/mcp-client-cli](https://github.com/adhikasp/mcp-client-cli) | Python | ~670 | 6 / ~110 | ⚠️ | ✅ | ✅ | ✅ | — | — | — | — | ✅ | — | — | — | ✅ |
|
|
1222
|
+
| [thellimist/clihub](https://github.com/thellimist/clihub) | Go | ~640 | 1 / ~60 | ✅ | ✅ | — | — | — | — | — | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
1223
|
+
| [wong2/mcp-cli](https://github.com/wong2/mcp-cli) | JS | ~430 | 4 / ~63 | ⚠️ | ✅ | ✅ | ✅ | — | — | — | ✅ | — | ✅ | — | — | — |
|
|
1224
|
+
| [mcpshim/mcpshim](https://github.com/mcpshim/mcpshim) | Go | ~54 | 1 / ~13 | ✅ | ✅ | — | — | — | ✅ | ✅ | ✅ | — | ✅ | ✅ | — | — |
|
|
1225
|
+
| [evantahler/mcpx](https://github.com/evantahler/mcpx) | TS | ~28 | 1 / ~64 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
1226
|
+
| [EstebanForge/mcp-cli-ent](https://github.com/EstebanForge/mcp-cli-ent) | Go | ~15 | ~2 / ~46 | ✅ | ✅ | — | — | — | ✅ | ✅ | — | ✅ | ✅ | ✅ | — | — |
|
|
1234
1227
|
|
|
1235
1228
|
**Legend:** ✅ = supported, ⚠️ = stale (no commits in 3+ months), **Contrib / Commits** = contributors / total commits, **Tasks** = [async tasks](https://modelcontextprotocol.io/specification/latest/server/utilities/tasks), **x402** = [x402 payment protocol](https://www.x402.org/) support, **LLM** = requires/uses an LLM.
|
|
1236
1229
|
|