@apify/mcpc 0.1.4 → 0.1.5
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/.claude/settings.local.json +24 -1
- package/.idea/codeStyles/Project.xml +4 -1
- package/.idea/workspace.xml +305 -275
- package/README.md +654 -516
- package/dist/bridge/index.js +53 -1
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/proxy-server.d.ts +21 -0
- package/dist/bridge/proxy-server.d.ts.map +1 -0
- package/dist/bridge/proxy-server.js +160 -0
- package/dist/bridge/proxy-server.js.map +1 -0
- package/dist/cli/commands/clean.js +8 -8
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/logging.js +1 -1
- package/dist/cli/commands/logging.js.map +1 -1
- package/dist/cli/commands/prompts.d.ts.map +1 -1
- package/dist/cli/commands/prompts.js +13 -4
- package/dist/cli/commands/prompts.js.map +1 -1
- package/dist/cli/commands/resources.js +5 -5
- package/dist/cli/commands/resources.js.map +1 -1
- package/dist/cli/commands/sessions.d.ts +2 -0
- package/dist/cli/commands/sessions.d.ts.map +1 -1
- package/dist/cli/commands/sessions.js +43 -57
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +0 -1
- package/dist/cli/commands/tools.d.ts.map +1 -1
- package/dist/cli/commands/tools.js +9 -9
- package/dist/cli/commands/tools.js.map +1 -1
- package/dist/cli/commands/utilities.js +1 -1
- package/dist/cli/commands/utilities.js.map +1 -1
- package/dist/cli/helpers.d.ts +7 -2
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +31 -14
- package/dist/cli/helpers.js.map +1 -1
- package/dist/cli/index.js +70 -46
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +7 -3
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/parser.d.ts +6 -1
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +78 -53
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/shell.d.ts.map +1 -1
- package/dist/cli/shell.js +27 -13
- package/dist/cli/shell.js.map +1 -1
- package/dist/core/factory.d.ts.map +1 -1
- package/dist/core/factory.js +1 -0
- package/dist/core/factory.js.map +1 -1
- package/dist/core/mcp-client.d.ts +5 -0
- package/dist/core/mcp-client.d.ts.map +1 -1
- package/dist/core/mcp-client.js +76 -26
- package/dist/core/mcp-client.js.map +1 -1
- package/dist/lib/auth/keychain.d.ts +3 -0
- package/dist/lib/auth/keychain.d.ts.map +1 -1
- package/dist/lib/auth/keychain.js +18 -0
- package/dist/lib/auth/keychain.js.map +1 -1
- package/dist/lib/auth/oauth-flow.d.ts.map +1 -1
- package/dist/lib/auth/oauth-flow.js +52 -12
- package/dist/lib/auth/oauth-flow.js.map +1 -1
- package/dist/lib/bridge-manager.d.ts +2 -1
- package/dist/lib/bridge-manager.d.ts.map +1 -1
- package/dist/lib/bridge-manager.js +25 -6
- package/dist/lib/bridge-manager.js.map +1 -1
- package/dist/lib/errors.d.ts +6 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +13 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/logger.d.ts +2 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +10 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/schema-validator.d.ts.map +1 -1
- package/dist/lib/schema-validator.js +45 -0
- package/dist/lib/schema-validator.js.map +1 -1
- package/dist/lib/sessions.d.ts +1 -1
- package/dist/lib/sessions.d.ts.map +1 -1
- package/dist/lib/sessions.js +21 -9
- package/dist/lib/sessions.js.map +1 -1
- package/dist/lib/types.d.ts +6 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +5 -1
- package/dist/lib/utils.js.map +1 -1
- package/docs/README.md +19 -0
- package/docs/TODOs.md +43 -0
- package/docs/claude-skill/SKILL.md +48 -28
- package/docs/images/mcpc-screenshot.png +0 -0
- package/package.json +4 -3
- package/PUBLISHING.md +0 -111
- package/TODOs.md +0 -46
package/README.md
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
# `mcpc`: Universal MCP command-line client
|
|
2
2
|
|
|
3
|
-
`mcpc` is a CLI for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
|
|
4
|
-
|
|
3
|
+
`mcpc` is a CLI for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
|
|
4
|
+
that maps MCP operations to intuitive commands for interactive shell use, scripts, and AI coding agents.
|
|
5
5
|
|
|
6
6
|
`mcpc` can connect to any MCP server over Streamable HTTP or stdio transports,
|
|
7
|
-
securely
|
|
8
|
-
and
|
|
7
|
+
securely authenticate via OAuth and store credentials,
|
|
8
|
+
and maintain persistent sessions to multiple servers.
|
|
9
9
|
It supports all major MCP features, including tools, resources, prompts, asynchronous tasks, and notifications.
|
|
10
10
|
|
|
11
|
-
`mcpc` is
|
|
12
|
-
and AI coding agents to use MCP in ["code mode"](https://www.anthropic.com/engineering/code-execution-with-mcp)
|
|
13
|
-
for better accuracy and lower token compared to traditional tool function calling.
|
|
11
|
+
`mcpc` is useful for manual testing of MCP servers, scripting,
|
|
12
|
+
and enabling AI coding agents to use MCP in ["code mode"](https://www.anthropic.com/engineering/code-execution-with-mcp)
|
|
13
|
+
for better accuracy and lower token usage compared to traditional tool function calling.
|
|
14
14
|
After all, UNIX-compatible shell script is THE most universal coding language, for people and LLMs alike.
|
|
15
15
|
|
|
16
|
-
Note that `mcpc` does not
|
|
16
|
+
Note that `mcpc` does not invoke LLMs itself; that's the job of the higher layer.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+

|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**Key features:**
|
|
21
|
+
- 🌎 **Highly compatible** - Works with any MCP server over Streamable HTTP or stdio.
|
|
21
22
|
- 🔄 **Persistent sessions** - Keep multiple server connections alive simultaneously.
|
|
22
23
|
- 🚀 **Zero setup** - Connect to remote servers instantly with just a URL.
|
|
23
|
-
- 🔧 **
|
|
24
|
-
-
|
|
25
|
-
- 🤖 **AI-friendly** - Designed for
|
|
26
|
-
- 🔒 **Secure** - OS keychain
|
|
24
|
+
- 🔧 **Strong MCP support** - Instructions, tools, resources, prompts, dynamic discovery.
|
|
25
|
+
- 🔌 **JSON output** - Easy integration with `jq`, scripts, and other CLI tools.
|
|
26
|
+
- 🤖 **AI-friendly** - Designed for both function calling and code mode with sandboxing.
|
|
27
|
+
- 🔒 **Secure** - Full OAuth 2.1 support, OS keychain for credentials storage.
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
## Table of contents
|
|
@@ -34,48 +35,15 @@ Note that `mcpc` does not use LLMs on its own; that's a job for the higher layer
|
|
|
34
35
|
- [Install](#install)
|
|
35
36
|
- [Quickstart](#quickstart)
|
|
36
37
|
- [Usage](#usage)
|
|
37
|
-
- [MCP command arguments](#mcp-command-arguments)
|
|
38
|
-
- [Global flags](#global-flags)
|
|
39
|
-
- [Authentication](#authentication)
|
|
40
|
-
- [No authentication](#no-authentication)
|
|
41
|
-
- [Bearer token authentication](#bearer-token-authentication)
|
|
42
|
-
- [OAuth authentication](#oauth-authentication)
|
|
43
|
-
- [Authentication profiles](#authentication-profiles)
|
|
44
|
-
- [Authentication behavior](#authentication-behavior)
|
|
45
|
-
- [Multiple accounts for the same server](#multiple-accounts-for-the-same-server)
|
|
46
|
-
- [Authentication precedence](#authentication-precedence)
|
|
47
|
-
- [Authentication profiles storage format](#authentication-profiles-storage-format)
|
|
48
38
|
- [Sessions](#sessions)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- [JSON mode](#json-mode)
|
|
54
|
-
- [Scripting](#scripting)
|
|
55
|
-
- [MCP server schema changes](#mcp-server-schema-changes)
|
|
56
|
-
- [Session failover](#session-failover)
|
|
57
|
-
- [Logging](#logging)
|
|
58
|
-
- [Cleanup](#cleanup)
|
|
39
|
+
- [Authentication](#authentication)
|
|
40
|
+
- [MCP proxy](#mcp-proxy)
|
|
41
|
+
- [Automation](#automation)
|
|
42
|
+
- [MCP support](#mcp-support)
|
|
59
43
|
- [Configuration](#configuration)
|
|
60
|
-
- [MCP config JSON file](#mcp-config-json-file)
|
|
61
|
-
- [Environment variables](#environment-variables)
|
|
62
|
-
- [MCP protocol notes](#mcp-protocol-notes)
|
|
63
44
|
- [Security](#security)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- [Bridge process authentication](#bridge-process-authentication)
|
|
67
|
-
- [File permissions](#file-permissions)
|
|
68
|
-
- [Network security](#network-security)
|
|
69
|
-
- [Error handling](#error-handling)
|
|
70
|
-
- [Exit codes](#exit-codes)
|
|
71
|
-
- [Retry strategy](#retry-strategy)
|
|
72
|
-
- [Interactive shell](#interactive-shell)
|
|
73
|
-
- [Claude Code skill](#claude-code-skill)
|
|
74
|
-
- [Troubleshooting](#troubleshooting)
|
|
75
|
-
- [Logs](#logs)
|
|
76
|
-
- [Common issues](#common-issues)
|
|
77
|
-
- [Contributing](#contributing)
|
|
78
|
-
- [Authors](#authors)
|
|
45
|
+
- [Errors](#errors)
|
|
46
|
+
- [Development](#development)
|
|
79
47
|
- [License](#license)
|
|
80
48
|
|
|
81
49
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
@@ -87,6 +55,21 @@ Note that `mcpc` does not use LLMs on its own; that's a job for the higher layer
|
|
|
87
55
|
npm install -g @apify/mcpc
|
|
88
56
|
```
|
|
89
57
|
|
|
58
|
+
**Linux users:** `mcpc` uses the OS keychain for secure credential storage, which requires the [Libsecret](https://wiki.gnome.org/Projects/Libsecret)
|
|
59
|
+
library. Install it with:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Debian/Ubuntu
|
|
63
|
+
sudo apt-get update
|
|
64
|
+
sudo apt-get install libsecret-1-0
|
|
65
|
+
|
|
66
|
+
# Fedora/RHEL/CentOS
|
|
67
|
+
sudo dnf install libsecret
|
|
68
|
+
|
|
69
|
+
# Arch Linux
|
|
70
|
+
sudo pacman -S libsecret
|
|
71
|
+
```
|
|
72
|
+
|
|
90
73
|
## Quickstart
|
|
91
74
|
|
|
92
75
|
```bash
|
|
@@ -103,8 +86,8 @@ mcpc mcp.apify.com
|
|
|
103
86
|
mcpc mcp.apify.com tools-list --json
|
|
104
87
|
|
|
105
88
|
# Create and use persistent MCP session
|
|
106
|
-
mcpc mcp.apify.com
|
|
107
|
-
mcpc @test tools-call search-actors
|
|
89
|
+
mcpc mcp.apify.com connect @test
|
|
90
|
+
mcpc @test tools-call search-actors keywords:="website crawler"
|
|
108
91
|
mcpc @test shell
|
|
109
92
|
|
|
110
93
|
# Interact with a local MCP server package (stdio) referenced from config file
|
|
@@ -113,135 +96,328 @@ mcpc --config ~/.vscode/mcp.json filesystem tools-list
|
|
|
113
96
|
|
|
114
97
|
## Usage
|
|
115
98
|
|
|
116
|
-
|
|
117
|
-
|
|
99
|
+
<!-- AUTO-GENERATED: mcpc --help -->
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
Usage: mcpc [options] <target> [command]
|
|
103
|
+
|
|
104
|
+
Universal command-line client for the Model Context Protocol (MCP).
|
|
118
105
|
|
|
119
106
|
Options:
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
--
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
--
|
|
126
|
-
|
|
127
|
-
--schema <file>
|
|
128
|
-
--schema-mode <mode>
|
|
129
|
-
|
|
130
|
-
|
|
107
|
+
-j, --json Output in JSON format for scripting
|
|
108
|
+
-c, --config <file> Path to MCP config JSON file (e.g. ".vscode/mcp.json")
|
|
109
|
+
-H, --header <header> HTTP header for remote MCP server (can be repeated)
|
|
110
|
+
-v, --version Output the version number
|
|
111
|
+
--verbose Enable debug logging
|
|
112
|
+
--profile <name> OAuth authentication profile to use (default:
|
|
113
|
+
"default")
|
|
114
|
+
--schema <file> Validate tool/prompt schema against expected schema
|
|
115
|
+
--schema-mode <mode> Schema validation mode: strict, compatible (default),
|
|
116
|
+
ignore
|
|
117
|
+
--timeout <seconds> Request timeout in seconds (default: 300)
|
|
118
|
+
--clean[=types] Clean up mcpc data (types: sessions, logs, profiles,
|
|
119
|
+
all)
|
|
120
|
+
-h, --help Display general help
|
|
131
121
|
|
|
132
122
|
Targets:
|
|
133
|
-
|
|
134
|
-
<config-entry>
|
|
135
|
-
|
|
123
|
+
@<session> Named persistent session (e.g. "@apify")
|
|
124
|
+
<config-entry> Entry in MCP config file specified by --config (e.g. "fs")
|
|
125
|
+
<server-url> Remote MCP server URL (e.g. "mcp.apify.com")
|
|
126
|
+
|
|
127
|
+
Management commands (<target> missing):
|
|
128
|
+
login Create OAuth profile with credentials to access remote server
|
|
129
|
+
logout Remove OAuth profile for remote server
|
|
130
|
+
connect @<session> Connect to server and create named persistent session
|
|
131
|
+
restart @<session> Kill and restart a session
|
|
132
|
+
close @<session> Close a session
|
|
133
|
+
|
|
134
|
+
MCP commands (<target> provided):
|
|
135
|
+
help Show server info ("help" can be omitted)
|
|
136
|
+
shell Open interactive shell
|
|
137
|
+
tools-list Send "tools/list" MCP request...
|
|
138
|
+
tools-get <tool-name>
|
|
139
|
+
tools-call <tool-name> [<args-json> | arg1:=val1 arg2:=val2 ...]
|
|
140
|
+
prompts-list
|
|
141
|
+
prompts-get <prompt-name> [<args-json> | arg1:=val1 arg2:=val2 ...]
|
|
142
|
+
resources
|
|
143
|
+
resources-list
|
|
144
|
+
resources-read <uri>
|
|
145
|
+
resources-subscribe <uri>
|
|
146
|
+
resources-unsubscribe <uri>
|
|
147
|
+
resources-templates-list
|
|
148
|
+
logging-set-level <level>
|
|
149
|
+
ping
|
|
136
150
|
|
|
137
|
-
Commands:
|
|
138
|
-
help Show server info, instructions, and capabilities
|
|
139
|
-
shell Open interactive shell to run MCP commands)
|
|
140
|
-
login Create OAuth profile with credentials to access remote server
|
|
141
|
-
logout Remove OAuth profile
|
|
142
|
-
session @<session> Create a named persistent session
|
|
143
|
-
restart @<session> Kill and restart a session
|
|
144
|
-
close @<session> Close a session
|
|
145
151
|
```
|
|
146
152
|
|
|
147
|
-
|
|
153
|
+
### Management commands
|
|
148
154
|
|
|
149
|
-
|
|
150
|
-
- **Named entry** in a config file, when used with `--config` (e.g. `filesystem`) - local or remote server
|
|
151
|
-
- **Remote MCP endpoint** URL (e.g. `mcp.apify.com` or `https://mcp.apify.com`) - direct HTTP connection
|
|
155
|
+
When `<target>` is missing, `mcpc` provides general management commands.
|
|
152
156
|
|
|
153
|
-
|
|
157
|
+
```bash
|
|
158
|
+
# List all sessions and OAuth profiles (also in JSON mode)
|
|
159
|
+
mcpc
|
|
160
|
+
mcpc --json
|
|
154
161
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
# Show command help or version
|
|
163
|
+
mcpc --help
|
|
164
|
+
mcpc --version
|
|
158
165
|
|
|
159
|
-
|
|
166
|
+
# Clean expired sessions and old log files
|
|
167
|
+
mcpc --clean
|
|
168
|
+
```
|
|
160
169
|
|
|
161
|
-
|
|
170
|
+
For additional management commands, see [OAuth profiles](#oauth-profiles) and [Cleanup](#cleanup).
|
|
171
|
+
|
|
172
|
+
### Targets
|
|
173
|
+
|
|
174
|
+
To connect to an MCP server, you need to specify a `<target>`, which can be one of (in order of precedence):
|
|
175
|
+
|
|
176
|
+
- **Entry in a config file** (e.g. `--config .vscode/mcp.json filesystem`) - see [Config file](#mcp-server-config-file)
|
|
177
|
+
- **Remote MCP server URL** (e.g. `https://mcp.apify.com`)
|
|
178
|
+
- **Named session** (e.g. `@apify`) - see [Sessions](#sessions)
|
|
179
|
+
|
|
180
|
+
`mcpc` automatically selects the transport protocol based on the server (stdio or Streamable HTTP),
|
|
181
|
+
connects, and enables you to interact with it.
|
|
182
|
+
|
|
183
|
+
**URL handling:**
|
|
184
|
+
- URLs without a scheme (e.g. `mcp.apify.com`) default to `https://`
|
|
185
|
+
- `localhost` and `127.0.0.1` addresses without a scheme default to `http://` (for local dev/proxy servers)
|
|
186
|
+
- To override the default, specify the scheme explicitly (e.g. `http://example.com`)
|
|
187
|
+
|
|
188
|
+
### MCP commands
|
|
189
|
+
|
|
190
|
+
Examples of sending MCP commands to various targets:
|
|
162
191
|
|
|
163
192
|
```bash
|
|
164
|
-
#
|
|
165
|
-
|
|
193
|
+
# Server from config file (stdio)
|
|
194
|
+
mcpc --config .vscode/mcp.json fileSystem
|
|
195
|
+
mcpc --config .vscode/mcp.json fileSystem tools-list
|
|
196
|
+
mcpc --config .vscode/mcp.json fileSystem tools-call list_directory path:=/
|
|
197
|
+
|
|
198
|
+
# Remote server (Streamable HTTP)
|
|
199
|
+
mcpc mcp.apify.com\?tools=docs
|
|
200
|
+
mcpc mcp.apify.com\?tools=docs tools-list
|
|
201
|
+
mcpc mcp.apify.com\?tools=docs tools-call search-apify-docs query:="What are Actors?"
|
|
202
|
+
|
|
203
|
+
# Session
|
|
204
|
+
mcpc mcp.apify.com\?tools=docs connect @apify
|
|
205
|
+
mcpc @apify tools-list
|
|
206
|
+
mcpc @apify tools-call search-apify-docs query:="What are Actors?"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
See [MCP feature support](#mcp-feature-support) for details about all supported MCP features and commands.
|
|
166
210
|
|
|
167
|
-
|
|
168
|
-
... --args name=value query="hello world"
|
|
211
|
+
#### Command arguments
|
|
169
212
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
213
|
+
The `tools-call` and `prompts-get` commands accept arguments as positional parameters after the tool/prompt name:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Key:=value pairs (auto-parsed: tries JSON, falls back to string)
|
|
217
|
+
mcpc <target> tools-call <tool-name> greeting:="hello world" count:=10 enabled:=true
|
|
218
|
+
mcpc <target> tools-call <tool-name> config:='{"key":"value"}' items:='[1,2,3]'
|
|
173
219
|
|
|
174
|
-
#
|
|
175
|
-
|
|
220
|
+
# Force string type with JSON quotes
|
|
221
|
+
mcpc <target> tools-call <tool-name> id:='"123"' flag:='"true"'
|
|
176
222
|
|
|
177
|
-
#
|
|
178
|
-
|
|
223
|
+
# Inline JSON object (if first arg starts with { or [)
|
|
224
|
+
mcpc <target> tools-call <tool-name> '{"greeting":"hello world","count":10}'
|
|
179
225
|
|
|
180
|
-
# Read from stdin (automatic when
|
|
181
|
-
echo '{"
|
|
226
|
+
# Read from stdin (automatic when no positional args and input is piped)
|
|
227
|
+
echo '{"greeting":"hello","count":10}' | mcpc <target> tools-call <tool-name>
|
|
228
|
+
cat args.json | mcpc <target> tools-call <tool-name>
|
|
182
229
|
```
|
|
183
230
|
|
|
184
231
|
**Rules:**
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
232
|
+
- All arguments use `:=` syntax: `key:=value`
|
|
233
|
+
- Values are auto-parsed: valid JSON becomes that type, otherwise treated as string
|
|
234
|
+
- `count:=10` → number `10`
|
|
235
|
+
- `enabled:=true` → boolean `true`
|
|
236
|
+
- `greeting:=hello` → string `"hello"` (not valid JSON, so string)
|
|
237
|
+
- `id:='"123"'` → string `"123"` (JSON string literal)
|
|
238
|
+
- Inline JSON: If first argument starts with `{` or `[`, it's parsed as a JSON object/array
|
|
239
|
+
- Stdin: When no positional args are provided and input is piped, reads JSON from stdin
|
|
240
|
+
|
|
241
|
+
**Using shell variables:**
|
|
242
|
+
|
|
243
|
+
When using shell variables that may contain spaces, use double quotes around the entire argument:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Variable with spaces - use double quotes
|
|
247
|
+
QUERY="hello world"
|
|
248
|
+
mcpc @server tools-call search "query:=${QUERY}"
|
|
249
|
+
|
|
250
|
+
# Multiple variables
|
|
251
|
+
CITY="New York"
|
|
252
|
+
TYPE="restaurants"
|
|
253
|
+
mcpc @server tools-call search "query:=${CITY} ${TYPE}"
|
|
254
|
+
|
|
255
|
+
# For complex inputs, consider using JSON via stdin
|
|
256
|
+
echo "{\"query\": \"${QUERY}\", \"limit\": 10}" | mcpc @server tools-call search
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Common pitfall:** Don't put spaces around `:=` - it won't work:
|
|
260
|
+
```bash
|
|
261
|
+
# Wrong - spaces around :=
|
|
262
|
+
mcpc @server tools-call search query := "hello world"
|
|
263
|
+
|
|
264
|
+
# Correct - no spaces around :=
|
|
265
|
+
mcpc @server tools-call search "query:=hello world"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Interactive shell
|
|
269
|
+
|
|
270
|
+
`mcpc` provides an interactive shell for discovery and testing of MCP servers.
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
mcpc mcp.apify.com shell # Direct connection
|
|
274
|
+
mcpc @apify shell # Use existing session
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Shell commands: `help`, `exit`/`quit`/Ctrl+D, Ctrl+C to cancel.
|
|
278
|
+
Arrow keys navigate history (saved to `~/.mcpc/history`).
|
|
279
|
+
|
|
280
|
+
### JSON mode
|
|
281
|
+
|
|
282
|
+
By default, `mcpc` prints output in Markdown-ish text format with colors, making it easy to read by both humans and AIs.
|
|
283
|
+
|
|
284
|
+
With `--json` option, `mcpc` always emits only a single JSON object (or array), to enable [scripting](#scripting).
|
|
285
|
+
**For all MCP commands, the returned objects are always consistent with the
|
|
286
|
+
[MCP specification](https://modelcontextprotocol.io/specification/latest).**
|
|
287
|
+
On success, the JSON object is printed to stdout, on error to stderr.
|
|
288
|
+
|
|
289
|
+
Note that `--json` is not available for `shell`, `login`, and `mcpc --help` commands.
|
|
290
|
+
|
|
291
|
+
## Sessions
|
|
292
|
+
|
|
293
|
+
MCP is a [stateful protocol](https://modelcontextprotocol.io/specification/latest/basic/lifecycle):
|
|
294
|
+
clients and servers negotiate protocol version and capabilities, and then communicate within a persistent session.
|
|
295
|
+
To support these sessions, `mcpc` can start a lightweight **bridge process** that maintains the connection and state.
|
|
296
|
+
This is more efficient than forcing every MCP command to reconnect and reinitialize,
|
|
297
|
+
and enables long-term stateful sessions.
|
|
298
|
+
|
|
299
|
+
The sessions are given names prefixed with `@` (e.g. `@apify`),
|
|
300
|
+
which then serve as unique reference in commands.
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# Create a persistent session
|
|
304
|
+
mcpc mcp.apify.com\?tools=docs connect @apify
|
|
305
|
+
|
|
306
|
+
# List all sessions and OAuth profiles
|
|
307
|
+
mcpc
|
|
308
|
+
|
|
309
|
+
# Run MCP commands in the session
|
|
310
|
+
mcpc @apify tools-list
|
|
311
|
+
mcpc @apify shell
|
|
312
|
+
|
|
313
|
+
# Restart the session (kills and restarts the bridge process)
|
|
314
|
+
mcpc @apify restart
|
|
315
|
+
|
|
316
|
+
# Close the session, terminates bridge process
|
|
317
|
+
mcpc @apify close
|
|
318
|
+
|
|
319
|
+
# ...now session name "@apify" is forgotten and available for future use
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Session lifecycle
|
|
323
|
+
|
|
324
|
+
The sessions are persistent: metadata is saved in `~/.mcpc/sessions.json` file,
|
|
325
|
+
[authentication tokens](#authentication) in OS keychain.
|
|
326
|
+
The `mcpc` bridge process keeps the session alive by sending periodic [ping messages](#ping) to the MCP server.
|
|
327
|
+
Still, sessions can fail due to network disconnects, bridge process crash, or server dropping it.
|
|
328
|
+
|
|
329
|
+
**Session states:**
|
|
330
|
+
|
|
331
|
+
| State | Meaning |
|
|
332
|
+
|------------------|-----------------------------------------------------------------------------------------------|
|
|
333
|
+
| 🟢 **`live`** | Bridge process is running; server might or might not be operational |
|
|
334
|
+
| 🟡 **`crashed`** | Bridge process crashed or was killed; will auto-restart on next use |
|
|
335
|
+
| 🔴 **`expired`** | Server rejected the session (auth failed, session ID invalid); requires `close` and reconnect |
|
|
336
|
+
|
|
337
|
+
Here's how `mcpc` handles various bridge process and server connection states:
|
|
338
|
+
|
|
339
|
+
- While the **bridge process is running**:
|
|
340
|
+
- If **server positively responds** to pings, the session is marked 🟢 **`live`**, and everything is fine.
|
|
341
|
+
- If **server stops responding**, the bridge will keep trying to reconnect in the background.
|
|
342
|
+
- If **server negatively responds** to indicate `MCP-Session-Id` is no longer valid
|
|
343
|
+
or authentication permanently failed (HTTP 401 or 403),
|
|
344
|
+
the bridge process will flag the session as 🔴 **`expired`** and **terminate** to avoid wasting resources.
|
|
345
|
+
Any future attempt to use the session (`mcpc @my-session ...`) will fail.
|
|
346
|
+
- If the **bridge process crashes**, `mcpc` will mark the session as 🟡 **`crashed`** on first use.
|
|
347
|
+
Next time you run `mcpc @my-session ...`, it will attempt to restart the bridge process.
|
|
348
|
+
- If bridge **restart succeeds**, everything starts again (see above).
|
|
349
|
+
- If bridge **restart fails**, `mcpc @my-session ...` returns error, and session remains marked 🟡 **`crashed`**.
|
|
350
|
+
|
|
351
|
+
Note that `mcpc` never automatically removes sessions from the list.
|
|
352
|
+
Instead, it keeps them flagged as 🟡 **`crashed`** or 🔴 **`expired`**,
|
|
353
|
+
and any future attempts to use them will fail.
|
|
354
|
+
|
|
355
|
+
To **remove the session from the list**, you need to explicitly close it:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
mcpc @apify close
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
You can restart a session anytime, which kills the bridge process
|
|
362
|
+
and opens new connection with new `MCP-Session-Id`, by running:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
mcpc @apify restart
|
|
366
|
+
```
|
|
367
|
+
|
|
190
368
|
|
|
191
369
|
## Authentication
|
|
192
370
|
|
|
193
|
-
`mcpc` supports all standard [
|
|
194
|
-
including the `WWW-Authenticate` discovery mechanism and OAuth 2.1 with PKCE.
|
|
371
|
+
`mcpc` supports all standard [MCP authorization methods](https://modelcontextprotocol.io/specification/latest/basic/authorization).
|
|
195
372
|
|
|
196
|
-
###
|
|
373
|
+
### Anonymous access
|
|
197
374
|
|
|
198
375
|
For local servers (stdio) or remote servers (Streamable HTTP) which do not require credentials,
|
|
199
376
|
`mcpc` can be used without authentication:
|
|
200
377
|
|
|
201
378
|
```bash
|
|
202
|
-
#
|
|
203
|
-
mcpc
|
|
379
|
+
# One-shot command
|
|
380
|
+
mcpc mcp.apify.com\?tools=docs tools-list
|
|
381
|
+
|
|
382
|
+
# Session command
|
|
383
|
+
mcpc mcp.apify.com\?tools=docs connect @test
|
|
384
|
+
mcpc @test tools-list
|
|
204
385
|
```
|
|
205
386
|
|
|
206
387
|
### Bearer token authentication
|
|
207
388
|
|
|
208
|
-
For remote servers that require a
|
|
209
|
-
All headers are stored securely in the OS keychain for the session, but **not** saved as
|
|
389
|
+
For remote servers that require a Bearer token (but not OAuth), use the `--header` flag to pass the token.
|
|
390
|
+
All headers are stored securely in the OS keychain for the session, but they are **not** saved as reusable
|
|
391
|
+
[OAuth profiles](#oauth-profiles). This means `--header` needs to be provided whenever
|
|
392
|
+
running a one-shot command or connecting new session.
|
|
210
393
|
|
|
211
394
|
```bash
|
|
212
|
-
# One-time command with
|
|
395
|
+
# One-time command with Bearer token
|
|
213
396
|
mcpc --header "Authorization: Bearer ${APIFY_TOKEN}" https://mcp.apify.com tools-list
|
|
214
397
|
|
|
215
|
-
# Create session with
|
|
216
|
-
mcpc --header "Authorization: Bearer ${APIFY_TOKEN}" https://mcp.apify.com
|
|
398
|
+
# Create session with Bearer token (saved to keychain for this session only)
|
|
399
|
+
mcpc --header "Authorization: Bearer ${APIFY_TOKEN}" https://mcp.apify.com connect @apify
|
|
217
400
|
|
|
218
|
-
# Use the session (token loaded from keychain automatically)
|
|
401
|
+
# Use the session (Bearer token is loaded from keychain automatically)
|
|
219
402
|
mcpc @apify tools-list
|
|
220
403
|
```
|
|
221
404
|
|
|
222
|
-
### OAuth
|
|
223
|
-
|
|
224
|
-
For OAuth-enabled remote MCP servers, `mcpc` implements the full OAuth 2.1 flow with PKCE, including:
|
|
225
|
-
- `WWW-Authenticate` header discovery
|
|
226
|
-
- Authorization server metadata discovery (RFC 8414)
|
|
227
|
-
- Client ID metadata documents (SEP-991)
|
|
228
|
-
- Dynamic client registration (RFC 7591)
|
|
229
|
-
- Automatic token refresh
|
|
405
|
+
### OAuth profiles
|
|
230
406
|
|
|
231
|
-
|
|
232
|
-
|
|
407
|
+
For OAuth-enabled remote MCP servers, `mcpc` implements the full OAuth 2.1 flow with PKCE,
|
|
408
|
+
including `WWW-Authenticate` header discovery, server metadata discovery, client ID metadata documents,
|
|
409
|
+
dynamic client registration, and automatic token refresh.
|
|
233
410
|
|
|
234
|
-
|
|
411
|
+
The OAuth authentication **always** needs to be initiated by the user calling the `login` command,
|
|
412
|
+
which opens a web browser with login screen. `mcpc` never opens the web browser on its own.
|
|
235
413
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
This allows you to:
|
|
240
|
-
- Authenticate once, create multiple sessions
|
|
414
|
+
The OAuth credentials to specific servers are securely stored as **authentication profiles** - reusable
|
|
415
|
+
credentials that allow you to:
|
|
416
|
+
- Authenticate once, use credentials across multiple commands or sessions
|
|
241
417
|
- Use different accounts (profiles) with the same server
|
|
242
418
|
- Manage credentials independently from sessions
|
|
243
419
|
|
|
244
|
-
|
|
420
|
+
Key concepts:
|
|
245
421
|
- **Authentication profile**: Named set of OAuth credentials for a specific server (stored in `~/.mcpc/profiles.json` + OS keychain)
|
|
246
422
|
- **Session**: Active connection to a server that may reference an authentication profile (stored in `~/.mcpc/sessions.json`)
|
|
247
423
|
- **Default profile**: When `--profile` is not specified, `mcpc` uses the authentication profile named `default`
|
|
@@ -250,20 +426,36 @@ This allows you to:
|
|
|
250
426
|
|
|
251
427
|
```bash
|
|
252
428
|
# Login to server and save 'default' authentication profile for future use
|
|
253
|
-
mcpc
|
|
429
|
+
mcpc mcp.apify.com login
|
|
254
430
|
|
|
255
431
|
# Use named authentication profile instead of 'default'
|
|
256
|
-
mcpc
|
|
432
|
+
mcpc mcp.apify.com login --profile work
|
|
257
433
|
|
|
258
|
-
#
|
|
259
|
-
mcpc https://mcp.apify.com
|
|
434
|
+
# Create two sessions using the two different credentials
|
|
435
|
+
mcpc https://mcp.apify.com connect @apify-personal
|
|
436
|
+
mcpc https://mcp.apify.com connect @apify-work --profile work
|
|
260
437
|
|
|
261
|
-
#
|
|
262
|
-
mcpc
|
|
438
|
+
# Both sessions now work independently
|
|
439
|
+
mcpc @apify-personal tools-list # Uses personal account
|
|
440
|
+
mcpc @apify-work tools-list # Uses work account
|
|
263
441
|
|
|
442
|
+
# Re-authenticate existing profile (e.g., to refresh or change scopes)
|
|
443
|
+
mcpc mcp.apify.com login --profile work
|
|
444
|
+
|
|
445
|
+
# Delete "default" and "work" authentication profiles
|
|
446
|
+
mcpc mcp.apify.com logout
|
|
447
|
+
mcpc mcp.apify.com logout --profile work
|
|
264
448
|
```
|
|
265
449
|
|
|
266
|
-
|
|
450
|
+
### Authentication precedence
|
|
451
|
+
|
|
452
|
+
When multiple authentication methods are available, `mcpc` uses this precedence order:
|
|
453
|
+
|
|
454
|
+
1. **Command-line `--header` flag** (highest priority) - Always used if provided
|
|
455
|
+
2. **Saved authentication profiles** - OAuth tokens from saved profile
|
|
456
|
+
3. **Config file headers** - Headers from `--config` file for the server
|
|
457
|
+
4. **No authentication** - Attempts unauthenticated connection
|
|
458
|
+
|
|
267
459
|
|
|
268
460
|
`mcpc` automatically handles authentication based on whether you specify a profile:
|
|
269
461
|
|
|
@@ -283,9 +475,9 @@ mcpc https://mcp.apify.com logout --profile personal
|
|
|
283
475
|
- If server accepts (no auth required) → Continue without creating profile
|
|
284
476
|
- If server rejects with 401 + `WWW-Authenticate` → Fail with an error
|
|
285
477
|
|
|
286
|
-
On failure, the error message includes instructions on how to login and save the profile, so
|
|
478
|
+
On failure, the error message includes instructions on how to login and save the profile, so you know what to do.
|
|
287
479
|
|
|
288
|
-
|
|
480
|
+
This flow ensures:
|
|
289
481
|
- You only authenticate when necessary
|
|
290
482
|
- Credentials are never silently mixed up (personal → work) or downgraded (authenticated → unauthenticated)
|
|
291
483
|
- You can mix authenticated sessions (with named profiles) and public access on the same server
|
|
@@ -294,258 +486,331 @@ On failure, the error message includes instructions on how to login and save the
|
|
|
294
486
|
|
|
295
487
|
```bash
|
|
296
488
|
# With specific profile - always authenticated:
|
|
297
|
-
# - Uses '
|
|
489
|
+
# - Uses 'work' if it exists
|
|
298
490
|
# - Fails if it doesn't exist
|
|
299
|
-
mcpc
|
|
491
|
+
mcpc mcp.apify.com connect @apify-work --profile work
|
|
300
492
|
|
|
301
493
|
# Without profile - opportunistic authentication:
|
|
302
494
|
# - Uses 'default' if it exists
|
|
303
495
|
# - Tries unauthenticated if 'default' doesn't exist
|
|
304
496
|
# - Fails if the server requires authentication
|
|
305
|
-
mcpc
|
|
497
|
+
mcpc mcp.apify.com connect @apify-personal
|
|
306
498
|
|
|
307
499
|
# Public server - no authentication needed:
|
|
308
|
-
mcpc
|
|
500
|
+
mcpc mcp.apify.com\?tools=docs tools-list
|
|
309
501
|
```
|
|
310
502
|
|
|
311
|
-
#### Multiple accounts for the same server
|
|
312
503
|
|
|
313
|
-
|
|
504
|
+
## MCP proxy
|
|
505
|
+
|
|
506
|
+
For stronger isolation, `mcpc` can expose an MCP session under new local proxy MCP server using the `--proxy` option.
|
|
507
|
+
The proxy forwards all MCP requests to the upstream server but **never exposes the original authentication tokens** to the client.
|
|
508
|
+
This is useful when you want to give someone or something MCP access without revealing your credentials.
|
|
509
|
+
See also [AI sandbox access](#ai-sandbox-access).
|
|
314
510
|
|
|
315
511
|
```bash
|
|
316
|
-
#
|
|
317
|
-
mcpc
|
|
512
|
+
# Human authenticates to a remote server
|
|
513
|
+
mcpc mcp.apify.com login
|
|
318
514
|
|
|
319
|
-
#
|
|
320
|
-
mcpc
|
|
515
|
+
# Create authenticated session with proxy server on localhost:8080
|
|
516
|
+
mcpc mcp.apify.com connect @open-relay --proxy 8080
|
|
321
517
|
|
|
322
|
-
#
|
|
323
|
-
|
|
324
|
-
|
|
518
|
+
# Now any MCP client can connect to proxy like to a regular MCP server
|
|
519
|
+
# The client has NO access to the original OAuth tokens or HTTP headers
|
|
520
|
+
# Note: localhost/127.0.0.1 URLs default to http:// (no scheme needed)
|
|
521
|
+
mcpc localhost:8080 tools-list
|
|
522
|
+
mcpc 127.0.0.1:8080 tools-call search-actors keywords:="web scraper"
|
|
325
523
|
|
|
326
|
-
#
|
|
327
|
-
mcpc
|
|
328
|
-
mcpc @
|
|
524
|
+
# Or create a new session from the proxy for convenience
|
|
525
|
+
mcpc localhost:8080 connect @sandboxed
|
|
526
|
+
mcpc @sandboxed tools-call search-actors keywords:="web scraper"
|
|
527
|
+
|
|
528
|
+
# Optionally protect proxy with bearer token for better security (stored in OS keychain)
|
|
529
|
+
mcpc mcp.apify.com connect @secure-relay --proxy 8081 --proxy-bearer-token secret123
|
|
530
|
+
# To use the proxy, caller needs to pass the bearer token in HTTP header
|
|
531
|
+
mcpc localhost:8081 connect @sandboxed2 --header "Authorization: Bearer secret123"
|
|
329
532
|
```
|
|
330
533
|
|
|
331
|
-
|
|
534
|
+
**Proxy options for `connect` command:**
|
|
332
535
|
|
|
333
|
-
|
|
536
|
+
| Option | Description |
|
|
537
|
+
|--------------------------------|--------------------------------------------------------------------------------|
|
|
538
|
+
| `--proxy [host:]port` | Start proxy MCP server. Default host: `127.0.0.1` (localhost only) |
|
|
539
|
+
| `--proxy-bearer-token <token>` | Requires `Authorization: Bearer <token>` header to access the proxy MCP server |
|
|
334
540
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
541
|
+
**Security model:**
|
|
542
|
+
|
|
543
|
+
- **Localhost by default**: `--proxy 8080` binds to `127.0.0.1` only, preventing network access
|
|
544
|
+
- **Tokens hidden**: Original OAuth tokens and/or HTTP headers are never exposed to proxy clients
|
|
545
|
+
- **Optional auth**: Use `--proxy-bearer-token` to add another layer of security
|
|
546
|
+
- **Explicit opt-in**: Proxy only starts when `--proxy` flag is provided
|
|
547
|
+
|
|
548
|
+
**Binding to network interfaces:**
|
|
339
549
|
|
|
340
|
-
**Example:**
|
|
341
550
|
```bash
|
|
342
|
-
#
|
|
343
|
-
|
|
344
|
-
# Command provides: --header "Authorization: Bearer ${TOKEN2}"
|
|
345
|
-
# Result: Uses TOKEN2 (command-line flag wins)
|
|
346
|
-
```
|
|
551
|
+
# Localhost only (default, most secure)
|
|
552
|
+
mcpc mcp.apify.com connect @relay --proxy 8080
|
|
347
553
|
|
|
348
|
-
|
|
554
|
+
# Bind to all interfaces (allows network access - use with caution!)
|
|
555
|
+
mcpc mcp.apify.com connect @relay --proxy 0.0.0.0:8080
|
|
349
556
|
|
|
350
|
-
|
|
557
|
+
# Bind to specific interface
|
|
558
|
+
mcpc mcp.apify.com connect @relay --proxy 192.168.1.100:8080
|
|
559
|
+
```
|
|
351
560
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
"name": "personal",
|
|
358
|
-
"serverUrl": "https://mcp.apify.com",
|
|
359
|
-
"authType": "oauth",
|
|
360
|
-
"oauthIssuer": "https://auth.apify.com",
|
|
361
|
-
"scopes": ["tools:read", "tools:write", "resources:read"],
|
|
362
|
-
"createdAt": "2025-12-14T10:00:00Z",
|
|
363
|
-
"authenticatedAt": "2025-12-14T10:00:00Z"
|
|
364
|
-
},
|
|
365
|
-
"work": {
|
|
366
|
-
"name": "work",
|
|
367
|
-
"serverUrl": "https://mcp.apify.com",
|
|
368
|
-
"authType": "oauth",
|
|
369
|
-
"oauthIssuer": "https://auth.apify.com",
|
|
370
|
-
"scopes": ["tools:read"],
|
|
371
|
-
"createdAt": "2025-12-10T15:30:00Z",
|
|
372
|
-
"authenticatedAt": "2025-12-10T15:30:00Z"
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
561
|
+
When listing sessions, proxy info is displayed prominently:
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
mcpc
|
|
565
|
+
# @relay → https://mcp.apify.com (HTTP, OAuth: default) [proxy: 127.0.0.1:8080]
|
|
377
566
|
```
|
|
378
567
|
|
|
379
|
-
**OS Keychain entries:**
|
|
380
|
-
- OAuth tokens: `mcpc:auth:https://mcp.apify.com:personal:tokens`
|
|
381
|
-
- OAuth client info: `mcpc:auth:https://mcp.apify.com:personal:client`
|
|
382
|
-
- HTTP headers (per-session): `mcpc:session:apify:headers`
|
|
383
568
|
|
|
384
|
-
##
|
|
569
|
+
## Automation
|
|
385
570
|
|
|
386
|
-
|
|
387
|
-
to negotiate protocol version and capabilities, then communicate within a persistent session.
|
|
388
|
-
Each session maintains:
|
|
389
|
-
- Negotiated protocol version and capabilities (which tools/resources/prompts/notifications are supported)
|
|
390
|
-
- For Streamable HTTP transport: persistent connection with bidirectional streaming, with automatic reconnection
|
|
391
|
-
- For stdio transport: persistent bidirectional pipe to subprocess
|
|
571
|
+
`mcpc` is designed for automation: shell scripting, schema validation for stable behavior, and AI agent integration.
|
|
392
572
|
|
|
393
|
-
|
|
394
|
-
`mcpc` uses a lightweight **bridge process** per session that:
|
|
573
|
+
### Scripting
|
|
395
574
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
- Multiplexes multiple concurrent requests (up to 10 concurrent, 100 queued)
|
|
399
|
-
- Enables piping data between multiple MCP servers simultaneously
|
|
575
|
+
Use `--json` for machine-readable output (stdout on success, stderr on error).
|
|
576
|
+
JSON output of all MCP commands follows the [MCP specification](https://modelcontextprotocol.io/specification/latest) strictly.
|
|
400
577
|
|
|
401
|
-
|
|
578
|
+
```bash
|
|
579
|
+
# Chain tools across sessions
|
|
580
|
+
mcpc --json @apify tools-call search-actors keywords:="scraper" \
|
|
581
|
+
| jq '.content[0].text | fromjson | .items[0].id' \
|
|
582
|
+
| xargs -I {} mcpc @apify tools-call get-actor actorId:="{}"
|
|
583
|
+
|
|
584
|
+
# Batch operations
|
|
585
|
+
for tool in $(mcpc --json @server tools-list | jq -r '.[].name'); do
|
|
586
|
+
mcpc --json @server tools-get "$tool" > "schemas/$tool.json"
|
|
587
|
+
done
|
|
588
|
+
```
|
|
402
589
|
|
|
403
|
-
|
|
404
|
-
- `~/.mcpc/profiles.json` - Authentication profiles (OAuth metadata, scopes, expiry)
|
|
405
|
-
- `~/.mcpc/bridges/` - Unix domain socket files for each bridge process
|
|
406
|
-
- `~/.mcpc/logs/bridge-*.log` - Log files for each bridge process
|
|
407
|
-
- OS keychain - Sensitive credentials (OAuth tokens, bearer tokens, client secrets)
|
|
590
|
+
### Schema validation
|
|
408
591
|
|
|
409
|
-
|
|
592
|
+
Validate tool/prompt schemas to detect breaking changes early:
|
|
410
593
|
|
|
411
594
|
```bash
|
|
412
|
-
#
|
|
413
|
-
mcpc
|
|
595
|
+
# Save expected schema
|
|
596
|
+
mcpc --json @apify tools-get search-actors > expected.json
|
|
414
597
|
|
|
415
|
-
#
|
|
416
|
-
mcpc
|
|
598
|
+
# Validate before calling (fails if schema changed incompatibly)
|
|
599
|
+
mcpc @apify tools-call search-actors --schema expected.json keywords:="test"
|
|
600
|
+
```
|
|
417
601
|
|
|
418
|
-
|
|
419
|
-
|
|
602
|
+
Schema modes (`--schema-mode`):
|
|
603
|
+
- `compatible` (default) - New optional fields OK, required fields must match. Output schema validated (new output fields OK, removed fields cause error).
|
|
604
|
+
- `strict` - Exact match required for all fields, types, and descriptions
|
|
605
|
+
- `ignore` - Skip validation
|
|
420
606
|
|
|
421
|
-
# Active sessions:
|
|
422
|
-
# @apify → https://mcp.apify.com (http, profile: personal)
|
|
423
|
-
#
|
|
424
|
-
# Saved authentication profiles:
|
|
425
|
-
# https://mcp.apify.com
|
|
426
|
-
# • personal (authenticated: 2 days ago)
|
|
427
|
-
# • work (authenticated: 1 week ago)
|
|
428
607
|
|
|
429
|
-
|
|
430
|
-
mcpc @apify tools-list
|
|
431
|
-
mcpc @apify shell
|
|
608
|
+
### AI agents
|
|
432
609
|
|
|
433
|
-
|
|
434
|
-
|
|
610
|
+
`mcpc` is designed for use by AI agents, in both interactive MCP tool calling mode
|
|
611
|
+
and "[code mode](https://blog.cloudflare.com/code-mode/)".
|
|
435
612
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
613
|
+
- **Tool calling mode** - CLI-based AI agents can dynamically explore and interact with the MCP server, thanks to the default Markdown-ish output.
|
|
614
|
+
Similar to MCP connectors in ChatGPT or Claude, but via CLI and with much longer command timeouts.
|
|
615
|
+
- **Code mode** - AI coding agents can write and execute shell [scripts](#scripting) composing multiple MCP server operations,
|
|
616
|
+
thanks to the `--json` output mode and access to MCP server schemas.
|
|
617
|
+
For well-defined workflow scenarios, this approach can be [more accurate](https://www.anthropic.com/engineering/code-execution-with-mcp)
|
|
618
|
+
and use fewer tokens.
|
|
439
619
|
|
|
440
|
-
|
|
620
|
+
AI agents can discover and use tools via shell commands:
|
|
441
621
|
|
|
442
622
|
```bash
|
|
443
|
-
mcpc
|
|
444
|
-
|
|
445
|
-
|
|
623
|
+
mcpc @server tools-list
|
|
624
|
+
mcpc --json @server tools-get search | jq '.inputSchema'
|
|
625
|
+
mcpc @server tools-call search query:="hello world"
|
|
446
626
|
```
|
|
447
627
|
|
|
448
|
-
|
|
628
|
+
and then generate shell scripts to execute sequences of actions,
|
|
629
|
+
with `--schema` checks to ensure stability of integrations and faster failure recovery.
|
|
630
|
+
Agents, make no harm!
|
|
449
631
|
|
|
450
|
-
####
|
|
632
|
+
#### AI sandbox access
|
|
451
633
|
|
|
452
|
-
|
|
453
|
-
|
|
634
|
+
To ensure AI coding agents don't perform destructive actions or leak credentials,
|
|
635
|
+
it's always a good idea to run them in a code sandbox
|
|
636
|
+
with limited access to your resources.
|
|
454
637
|
|
|
455
|
-
|
|
638
|
+
The [proxy MCP server](#mcp-proxy) feature provides a security boundary for AI agents:
|
|
456
639
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
640
|
+
1. **Human creates authentication profile**: `mcpc mcp.apify.com login --profile ai-access`
|
|
641
|
+
2. **Human creates session**: `mcpc mcp.apify.com connect @ai-sandbox --profile ai-access --proxy 8080`
|
|
642
|
+
3. **AI runs inside a sandbox**: If sandbox has access limited to `localhost:8080`,
|
|
643
|
+
it can only interact with the MCP server through the `@ai-sandbox` session,
|
|
644
|
+
without access to the original OAuth credentials, HTTP headers, or `mcpc` configuration.
|
|
460
645
|
|
|
461
|
-
|
|
646
|
+
This ensures AI agents operate only with pre-authorized credentials, preventing unauthorized access to MCP servers.
|
|
647
|
+
The human controls which servers the AI can access and with what permissions (OAuth scopes).
|
|
648
|
+
|
|
649
|
+
**IMPORTANT:** Beware that MCP proxy will not make an insecure MCP server secure.
|
|
650
|
+
Local stdio servers will still have access to your local system, and HTTP servers to provided auth credentials,
|
|
651
|
+
and both can easily perform destructive actions or leak credentials on their own, or let MCP clients do such actions.
|
|
652
|
+
**Always use only trusted local and remote MCP servers and limit their access to the necessary minimum.**
|
|
653
|
+
|
|
654
|
+
#### Agent skills
|
|
655
|
+
|
|
656
|
+
To help Claude Code use `mcpc`, you can install this [Claude skill](./docs/claude-skill/README.md):
|
|
657
|
+
|
|
658
|
+
<!-- TODO: Add also AGENTS.md, GitHub skills etc. -->
|
|
659
|
+
|
|
660
|
+
## MCP support
|
|
661
|
+
|
|
662
|
+
`mcpc` is built on the official [MCP SDK for TypeScript](https://github.com/modelcontextprotocol/typescript-sdk) and supports most [MCP protocol features](https://modelcontextprotocol.io/specification/latest).
|
|
663
|
+
|
|
664
|
+
### Transport
|
|
462
665
|
|
|
463
|
-
|
|
464
|
-
|
|
666
|
+
- **stdio**: Direct bidirectional JSON-RPC communication over
|
|
667
|
+
stdio server from the [config file](#mcp-server-config-file).
|
|
668
|
+
- **Streamable HTTP**: Fully supported.
|
|
669
|
+
- **HTTP with SSE** (deprecated): Legacy mode, not supported.
|
|
465
670
|
|
|
466
|
-
|
|
467
|
-
- On error, the JSON object is printed to stderr
|
|
671
|
+
### Authorization
|
|
468
672
|
|
|
469
|
-
|
|
673
|
+
- [Anonymous access](#anonymous-access)
|
|
674
|
+
- [HTTP header authorization](#bearer-token-authentication)
|
|
675
|
+
- [OAuth 2.1](#oauth-profiles)
|
|
470
676
|
|
|
471
|
-
|
|
472
|
-
or if there are invalid arguments, as those take precedence.
|
|
677
|
+
### MCP session
|
|
473
678
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
679
|
+
The bridge process manages the full MCP session lifecycle:
|
|
680
|
+
- Performs initialization handshake (`initialize` → `initialized`)
|
|
681
|
+
- Negotiates protocol version (currently `2025-11-25`) and capabilities
|
|
682
|
+
- Fetches server-provided `instructions`
|
|
683
|
+
- Maintains persistent HTTP connections with bidirectional streaming, or stdio bidirectional pipe to subprocess
|
|
684
|
+
- Handles `MCP-Protocol-Version` and `MCP-Session-Id` headers automatically
|
|
685
|
+
- Handles multiple concurrent requests
|
|
686
|
+
- Recovers transparently from network disconnections and bridge process crashes
|
|
477
687
|
|
|
478
|
-
|
|
479
|
-
is to keep backwards compatibility to maximum extent possible, to ensure the scripts using `mcpc`
|
|
480
|
-
will not break over time.
|
|
688
|
+
### MCP feature support
|
|
481
689
|
|
|
482
|
-
|
|
690
|
+
| **Feature** | **Status** |
|
|
691
|
+
|:---------------------------------------------------|:-----------------------------------|
|
|
692
|
+
| 📖 [**Instructions**](#server-instructions) | ✅ Supported |
|
|
693
|
+
| 🔧 [**Tools**](#tools) | ✅ Supported |
|
|
694
|
+
| 💬 [**Prompts**](#prompts) | ✅ Supported |
|
|
695
|
+
| 📦 [**Resources**](#resources) | ✅ Supported |
|
|
696
|
+
| 📝 [**Logging**](#server-logs) | ✅ Supported |
|
|
697
|
+
| 🔔 [**Notifications**](#list-change-notifications) | ✅ Supported |
|
|
698
|
+
| 📄 [**Pagination**](#pagination) | ✅ Supported |
|
|
699
|
+
| 🏓 [**Ping**](#ping) | ✅ Supported |
|
|
700
|
+
| ⏳ **Async tasks** | 🚧 Planned |
|
|
701
|
+
| 📁 **Roots** | 🚧 Planned |
|
|
702
|
+
| ❓ **Elicitation** | 🚧 Planned |
|
|
703
|
+
| 🔤 **Completion** | 🚧 Planned |
|
|
704
|
+
| 🤖 **Sampling** | ❌ Not applicable (no LLM access) |
|
|
483
705
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
If the MCP server's current schema is incompatible, the command returns an error.
|
|
706
|
+
#### Server instructions
|
|
707
|
+
|
|
708
|
+
MCP servers can provide instructions describing their capabilities and usage. These are displayed when you connect to a server or run the `help` command:
|
|
488
709
|
|
|
489
710
|
```bash
|
|
490
|
-
#
|
|
491
|
-
mcpc
|
|
711
|
+
# Show server info, capabilities, and instructions (both commands behave the same)
|
|
712
|
+
mcpc @apify
|
|
713
|
+
mcpc @apify help
|
|
492
714
|
|
|
493
|
-
#
|
|
494
|
-
mcpc @apify
|
|
495
|
-
--schema search-actors-schema.json \
|
|
496
|
-
--schema-mode strict \
|
|
497
|
-
--args keywords="tiktok scraper"
|
|
715
|
+
# JSON mode
|
|
716
|
+
mcpc @apify --json
|
|
498
717
|
```
|
|
499
718
|
|
|
500
|
-
|
|
719
|
+
In [JSON mode](#json-mode), the resulting object adheres
|
|
720
|
+
to [`InitializeResult`](https://modelcontextprotocol.io/specification/latest/schema#initializeresult) object schema,
|
|
721
|
+
and `mcpc` includes additional `_meta` fields to provide server metadata.
|
|
501
722
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
723
|
+
```json
|
|
724
|
+
{
|
|
725
|
+
"_meta": {
|
|
726
|
+
"sessionName": "@apify",
|
|
727
|
+
"profileName": "default",
|
|
728
|
+
"server": {
|
|
729
|
+
"url": "https://mcp.apify.com"
|
|
730
|
+
}
|
|
731
|
+
},
|
|
732
|
+
"protocolVersion": "2025-06-18",
|
|
733
|
+
"capabilities": {
|
|
734
|
+
"logging": {},
|
|
735
|
+
"prompts": {},
|
|
736
|
+
"resources": {},
|
|
737
|
+
"tools": { "listChanged": true }
|
|
738
|
+
},
|
|
739
|
+
"serverInfo": {
|
|
740
|
+
"name": "apify-mcp-server",
|
|
741
|
+
"version": "1.0.0"
|
|
742
|
+
},
|
|
743
|
+
"instructions": "Apify is the largest marketplace of tools for web scraping..."
|
|
744
|
+
}
|
|
745
|
+
```
|
|
508
746
|
|
|
509
|
-
|
|
747
|
+
#### Tools
|
|
510
748
|
|
|
511
|
-
|
|
512
|
-
But even then, the session can fail for a number of reasons:
|
|
749
|
+
List, inspect, and call server-provided tools:
|
|
513
750
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
751
|
+
```bash
|
|
752
|
+
# List available tools
|
|
753
|
+
mcpc @apify tools-list
|
|
517
754
|
|
|
518
|
-
|
|
755
|
+
# Get tool schema details
|
|
756
|
+
mcpc @apify tools-get search-actors
|
|
519
757
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
- If the server response indicates the `MCP-Session-Id` is no longer valid or authentication permanently failed (HTTP error 401 or 402),
|
|
523
|
-
the bridge process will flag the session as **expired** in `~/.mcpc/sessions.json` and terminate.
|
|
524
|
-
- If the bridge process crashes, `mcpc` attempts to restart it next time you use the specific session.
|
|
758
|
+
# Call a tool with arguments
|
|
759
|
+
mcpc @apify tools-call search-actors keywords:="web scraper"
|
|
525
760
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
761
|
+
# Pass complex JSON arguments
|
|
762
|
+
mcpc @apify tools-call create-task '{"name": "my-task", "options": {"memory": 1024}}'
|
|
763
|
+
|
|
764
|
+
# Load arguments from stdin
|
|
765
|
+
cat data.json | mcpc @apify tools-call bulk-import
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
#### Prompts
|
|
769
|
+
|
|
770
|
+
List and retrieve server-defined prompt templates:
|
|
529
771
|
|
|
530
772
|
```bash
|
|
531
|
-
|
|
773
|
+
# List available prompts
|
|
774
|
+
mcpc @apify prompts-list
|
|
775
|
+
|
|
776
|
+
# Get a prompt with arguments
|
|
777
|
+
mcpc @apify prompts-get analyze-website url:=https://example.com
|
|
532
778
|
```
|
|
533
779
|
|
|
534
|
-
|
|
780
|
+
<!-- TODO: Add example of prompt templates -->
|
|
781
|
+
|
|
782
|
+
#### Resources
|
|
783
|
+
|
|
784
|
+
Access server-provided data sources by URI:
|
|
535
785
|
|
|
536
786
|
```bash
|
|
537
|
-
|
|
787
|
+
# List available resources
|
|
788
|
+
mcpc @apify resources-list
|
|
789
|
+
|
|
790
|
+
# Read a resource
|
|
791
|
+
mcpc @apify resources-read "file:///config.json"
|
|
792
|
+
|
|
793
|
+
# Subscribe to resource changes (in shell mode)
|
|
794
|
+
mcpc @apify resources-subscribe "https://api.example.com/data"
|
|
795
|
+
|
|
796
|
+
# List resource templates
|
|
797
|
+
mcpc @apify resources-templates-list
|
|
538
798
|
```
|
|
539
799
|
|
|
540
|
-
|
|
800
|
+
#### List change notifications
|
|
541
801
|
|
|
542
|
-
|
|
802
|
+
When connected via a [session](#sessions), `mcpc` automatically handles `list_changed`
|
|
803
|
+
notifications for tools, resources, and prompts.
|
|
804
|
+
The bridge process updates the session record so the caller can detect and react on these notifications.
|
|
805
|
+
In [shell mode](#interactive-shell), notifications are displayed in real-time.
|
|
543
806
|
|
|
544
|
-
|
|
545
|
-
The main `mcpc` process doesn't save log files, but you can use `--verbose` flag to print all logs to stderr.
|
|
807
|
+
#### Server logs
|
|
546
808
|
|
|
547
|
-
|
|
548
|
-
|
|
809
|
+
`mcpc` supports server logging settings (`logging/setLevel`) and log messages (`notifications/message`).
|
|
810
|
+
Log messages are printed to bridge log or stderr, subject to [verbosity level](#verbose-mode).
|
|
811
|
+
|
|
812
|
+
You can instruct MCP servers to adjust their [logging level](https://modelcontextprotocol.io/specification/latest/server/utilities/logging)
|
|
813
|
+
using the `logging-set-level` command:
|
|
549
814
|
|
|
550
815
|
```bash
|
|
551
816
|
# Set server log level to debug for detailed output
|
|
@@ -555,47 +820,37 @@ mcpc @apify logging-set-level debug
|
|
|
555
820
|
mcpc @apify logging-set-level error
|
|
556
821
|
```
|
|
557
822
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
- `info` - General informational messages
|
|
561
|
-
- `notice` - Normal but significant events
|
|
562
|
-
- `warning` - Warning messages
|
|
563
|
-
- `error` - Error messages
|
|
564
|
-
- `critical` - Critical conditions
|
|
565
|
-
- `alert` - Action must be taken immediately
|
|
566
|
-
- `emergency` - System is unusable
|
|
823
|
+
Note that this sets the logging level on the **server side**.
|
|
824
|
+
The actual log output depends on the server's implementation.
|
|
567
825
|
|
|
568
|
-
|
|
826
|
+
#### Pagination
|
|
569
827
|
|
|
828
|
+
MCP servers may return paginated results for list operations
|
|
829
|
+
(`tools-list`, `resources-list`, `prompts-list`, `resources-templates-list`).
|
|
830
|
+
`mcpc` handles this automatically and always fetches all available pages using the `nextCursor`
|
|
831
|
+
token - you always get the complete list without manual iteration. Keep it simple.
|
|
570
832
|
|
|
571
|
-
|
|
833
|
+
#### Ping
|
|
572
834
|
|
|
573
|
-
|
|
835
|
+
Sessions automatically send periodic pings to keep the [connection alive](#session-lifecycle) and detect failures early.
|
|
836
|
+
Send a ping to check if a server connection is alive:
|
|
574
837
|
|
|
575
838
|
```bash
|
|
576
|
-
#
|
|
577
|
-
mcpc
|
|
578
|
-
|
|
579
|
-
# Clean specific resources (comma-separated)
|
|
580
|
-
mcpc --clean=sessions # Kill bridges, delete all sessions
|
|
581
|
-
mcpc --clean=profiles # Delete all authentication profiles
|
|
582
|
-
mcpc --clean=logs # Delete all log files
|
|
583
|
-
mcpc --clean=sessions,logs # Clean multiple resource types
|
|
584
|
-
|
|
585
|
-
# Nuclear option: remove everything
|
|
586
|
-
mcpc --clean=all # Delete all sessions, profiles, logs, and sockets
|
|
839
|
+
# Ping a session and measure round-trip time
|
|
840
|
+
mcpc @apify ping
|
|
841
|
+
mcpc @apify ping --json
|
|
587
842
|
```
|
|
588
843
|
|
|
589
844
|
## Configuration
|
|
590
845
|
|
|
591
|
-
|
|
846
|
+
You can configure `mcpc` using a config file, environment variables, or command-line flags.
|
|
592
847
|
|
|
593
848
|
**Precedence** (highest to lowest):
|
|
594
849
|
1. Command-line flags (including `--config` option)
|
|
595
850
|
2. Environment variables
|
|
596
851
|
3. Built-in defaults
|
|
597
852
|
|
|
598
|
-
### MCP config
|
|
853
|
+
### MCP server config file
|
|
599
854
|
|
|
600
855
|
`mcpc` supports the ["standard"](https://gofastmcp.com/integrations/mcp-json-configuration)
|
|
601
856
|
MCP server JSON config file, compatible with Claude Desktop, VS Code, and other MCP clients.
|
|
@@ -606,7 +861,7 @@ You can point to an existing config file with `--config`:
|
|
|
606
861
|
mcpc --config .vscode/mcp.json apify tools-list
|
|
607
862
|
|
|
608
863
|
# Open a session to a server specified in the custom config file
|
|
609
|
-
mcpc --config .vscode/mcp.json apify
|
|
864
|
+
mcpc --config .vscode/mcp.json apify connect @my-apify
|
|
610
865
|
```
|
|
611
866
|
|
|
612
867
|
**Example MCP config JSON file:**
|
|
@@ -637,7 +892,7 @@ mcpc --config .vscode/mcp.json apify session @my-apify
|
|
|
637
892
|
|
|
638
893
|
**Server configuration properties:**
|
|
639
894
|
|
|
640
|
-
For **HTTP
|
|
895
|
+
For **Streamable HTTP servers:**
|
|
641
896
|
- `url` (required) - MCP server endpoint URL
|
|
642
897
|
- `headers` (optional) - HTTP headers to include with requests
|
|
643
898
|
- `timeout` (optional) - Request timeout in seconds
|
|
@@ -653,10 +908,10 @@ When `--config` is provided, you can reference servers by name:
|
|
|
653
908
|
|
|
654
909
|
```bash
|
|
655
910
|
# With config file, use server names directly
|
|
656
|
-
mcpc --config .vscode/mcp.json filesystem
|
|
911
|
+
mcpc --config .vscode/mcp.json filesystem tools-list
|
|
657
912
|
|
|
658
913
|
# Create a named session from server in config
|
|
659
|
-
mcpc --config .vscode/mcp.json filesystem
|
|
914
|
+
mcpc --config .vscode/mcp.json filesystem connect @fs
|
|
660
915
|
mcpc @fs tools-call search
|
|
661
916
|
```
|
|
662
917
|
|
|
@@ -678,120 +933,71 @@ Config files support environment variable substitution using `${VAR_NAME}` synta
|
|
|
678
933
|
}
|
|
679
934
|
```
|
|
680
935
|
|
|
936
|
+
### Saved state
|
|
937
|
+
|
|
938
|
+
`mcpc` saves its state to `~/.mcpc/` directory (unless overridden by `MCPC_HOME_DIR`), in the following files:
|
|
939
|
+
|
|
940
|
+
- `~/.mcpc/sessions.json` - Active sessions with references to authentication profiles (file-locked for concurrent access)
|
|
941
|
+
- `~/.mcpc/profiles.json` - Authentication profiles (OAuth metadata, scopes, expiry)
|
|
942
|
+
- `~/.mcpc/bridges/` - Unix domain socket files for each bridge process
|
|
943
|
+
- `~/.mcpc/logs/bridge-*.log` - Log files for each bridge process
|
|
944
|
+
- OS keychain - Sensitive credentials (OAuth tokens, bearer tokens, client secrets)
|
|
945
|
+
|
|
681
946
|
### Environment variables
|
|
682
947
|
|
|
683
948
|
- `MCPC_HOME_DIR` - Directory for session and authentication profiles data (default is `~/.mcpc`)
|
|
684
949
|
- `MCPC_VERBOSE` - Enable verbose logging (set to `1`, `true`, or `yes`, case-insensitive)
|
|
685
950
|
- `MCPC_JSON` - Enable JSON output (set to `1`, `true`, or `yes`, case-insensitive)
|
|
686
951
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
TODO: explain in detail how MCP concepts work in mcpc
|
|
690
|
-
|
|
691
|
-
**Protocol initialization:**
|
|
692
|
-
- `mcpc` follows the MCP initialization handshake: sends `initialize` request with protocol version and capabilities, receives server capabilities and instructions, then sends `initialized` notification
|
|
693
|
-
- Protocol version negotiation: client proposes latest supported version (currently `2025-11-25`), server responds with version to use
|
|
694
|
-
|
|
695
|
-
**Transport handling:**
|
|
696
|
-
- **Streamable HTTP**: `mcpc` supports only the Streamable HTTP transport (the current standard). The deprecated HTTP with SSE transport is not supported. The bridge manages persistent HTTP connections with bidirectional streaming for server-to-client communication, with automatic reconnection using exponential backoff (1s → 30s max)
|
|
697
|
-
- Includes `MCP-Protocol-Version` header on all HTTP requests (per MCP spec)
|
|
698
|
-
- Handles `MCP-Session-Id` for stateful server sessions
|
|
699
|
-
- During reconnection, new requests are queued (fails after 3 minutes of disconnection)
|
|
700
|
-
- **Stdio**: Direct bidirectional JSON-RPC communication over standard input/output
|
|
701
|
-
|
|
702
|
-
**Protocol features:**
|
|
703
|
-
- `mcpc` supports all MCP primitives in both Streamable HTTP and stdio transports:
|
|
704
|
-
- **Instructions**: Fetches and stores MCP server-provided `instructions`
|
|
705
|
-
- **Tools**: Executable functions with JSON Schema-validated arguments.
|
|
706
|
-
- **Resources**: Data sources identified by URIs (e.g., `file:///path/to/file`, `https://example.com/data`), with optional subscriptions for change notifications
|
|
707
|
-
- **Prompts**: Reusable message templates with customizable arguments
|
|
708
|
-
- **Completion**: Provides access to Completion API for tools and resources
|
|
709
|
-
- **Asynchronous tasks**: Not implemented yet
|
|
710
|
-
- **Roots**: Not implemented yet
|
|
711
|
-
- Supports server logging settings (`logging/setLevel`) and messages (`notifications/message`), and prints them to stderr or stdout based on verbosity level.
|
|
712
|
-
- Handles server notifications: progress tracking, logging, and change notifications (`notifications/tools/list_changed`, `notifications/resources/list_changed`, `notifications/prompts/list_changed`)
|
|
713
|
-
- Request multiplexing: supports up to 10 concurrent requests, queues up to 100 additional requests
|
|
714
|
-
- Pagination: List operations automatically fetch all pages when the server returns paginated results
|
|
715
|
-
- Pings: `mcpc` periodically issues the MCP `ping` request to keep the connection alive
|
|
716
|
-
- Sampling is not supported as `mcpc` has no access to an LLM
|
|
717
|
-
|
|
718
|
-
## Security
|
|
719
|
-
|
|
720
|
-
`mcpc` implements the [MCP security best practices](https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices) specification. MCP enables arbitrary tool execution and data access; treat servers like you treat shells:
|
|
721
|
-
|
|
722
|
-
* Use least-privilege tokens/headers
|
|
723
|
-
* Prefer trusted endpoints
|
|
724
|
-
* Audit what tools do before running them
|
|
725
|
-
* Review server permissions in interactive mode
|
|
726
|
-
|
|
727
|
-
### Authentication
|
|
952
|
+
### Cleanup
|
|
728
953
|
|
|
729
|
-
|
|
730
|
-
- Full OAuth 2.1 flow with PKCE (Proof Key for Code Exchange) via the MCP SDK
|
|
731
|
-
- OAuth callback server binds to `127.0.0.1` only (not `0.0.0.0`)
|
|
732
|
-
- Warning displayed for OAuth over plain HTTP (except localhost)
|
|
733
|
-
- Dynamic client registration supported
|
|
954
|
+
You can clean up the `mcpc` state and data using the `--clean` option:
|
|
734
955
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
- URLs normalized and validated (HTTPS enforced, credentials stripped)
|
|
956
|
+
```bash
|
|
957
|
+
# Safe non-destructive cleanup: remove expired sessions, delete old orphaned logs
|
|
958
|
+
mcpc --clean
|
|
739
959
|
|
|
740
|
-
|
|
960
|
+
# Clean specific resources (comma-separated)
|
|
961
|
+
mcpc --clean=sessions # Kill bridges, delete all sessions
|
|
962
|
+
mcpc --clean=profiles # Delete all authentication profiles
|
|
963
|
+
mcpc --clean=logs # Delete all log files
|
|
964
|
+
mcpc --clean=sessions,logs # Clean multiple resource types
|
|
741
965
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
- All HTTP headers from `--header` flags are stored per-session in the keychain (as JSON)
|
|
746
|
-
- The `~/.mcpc/profiles.json` file only contains metadata (server URL, scopes, timestamps) - never tokens
|
|
966
|
+
# Nuclear option: remove everything
|
|
967
|
+
mcpc --clean=all # Delete all sessions, profiles, logs, and sockets
|
|
968
|
+
```
|
|
747
969
|
|
|
748
|
-
|
|
749
|
-
- OAuth tokens: `mcpc:auth-profile:<host>:<profileName>:tokens`
|
|
750
|
-
- OAuth client: `mcpc:auth-profile:<host>:<profileName>:client`
|
|
751
|
-
- HTTP headers: `mcpc:session:<sessionName>:headers`
|
|
970
|
+
## Security
|
|
752
971
|
|
|
753
|
-
|
|
972
|
+
`mcpc` follows [MCP security best practices](https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices).
|
|
973
|
+
MCP enables arbitrary tool execution and data access - treat servers like you treat shells:
|
|
754
974
|
|
|
755
|
-
|
|
975
|
+
- Use least-privilege tokens/headers
|
|
976
|
+
- Only use trusted servers!
|
|
977
|
+
- Audit tools before running them
|
|
756
978
|
|
|
757
|
-
|
|
758
|
-
1. **CLI retrieves refresh token** from OS keychain when creating or restarting a session
|
|
759
|
-
2. **CLI sends refresh token to bridge** via Unix socket IPC (not command line arguments)
|
|
760
|
-
3. **Bridge stores refresh token in memory only** - never written to disk
|
|
761
|
-
4. **Bridge refreshes access tokens** periodically using the refresh token
|
|
762
|
-
5. **Access tokens are kept in bridge memory** - never persisted to disk
|
|
979
|
+
### Credential protection
|
|
763
980
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
981
|
+
| What | How |
|
|
982
|
+
|------------------------|-------------------------------------------------|
|
|
983
|
+
| **OAuth tokens** | Stored in OS keychain, never on disk |
|
|
984
|
+
| **HTTP headers** | Stored in OS keychain per-session |
|
|
985
|
+
| **Bridge credentials** | Passed via Unix socket IPC, kept in memory only |
|
|
986
|
+
| **Process arguments** | No secrets visible in `ps aux` |
|
|
987
|
+
| **Config files** | Contain only metadata, never tokens |
|
|
988
|
+
| **File permissions** | `0600` (user-only) for all config files |
|
|
771
989
|
|
|
772
|
-
|
|
773
|
-
- Credentials are never stored in plaintext on disk
|
|
774
|
-
- Headers are not visible in process arguments (`ps aux`)
|
|
775
|
-
- Bridge processes don't need direct keychain access (which may require user interaction)
|
|
776
|
-
- Credentials are securely transmitted via Unix socket (local IPC only)
|
|
777
|
-
- Failover works correctly - headers are preserved across bridge restarts
|
|
990
|
+
### Network security
|
|
778
991
|
|
|
779
|
-
|
|
992
|
+
- HTTPS enforced for remote servers (auto-upgraded from HTTP)
|
|
993
|
+
- OAuth callback binds to `127.0.0.1` only
|
|
994
|
+
- Credentials never logged, even in verbose mode
|
|
780
995
|
|
|
781
|
-
|
|
782
|
-
- `~/.mcpc/profiles.json` is created with `0600` permissions (user-only read/write)
|
|
783
|
-
- Bridge sockets in `~/.mcpc/bridges/` use default umask (typically user-only)
|
|
784
|
-
- File locking via `proper-lockfile` prevents race conditions on concurrent access
|
|
996
|
+
### AI security
|
|
785
997
|
|
|
786
|
-
|
|
998
|
+
See [AI sandbox access](#ai-sandbox-access) for details.
|
|
787
999
|
|
|
788
|
-
|
|
789
|
-
- URL normalization removes username, password, and hash from URLs
|
|
790
|
-
- Local OAuth callback server binds to `127.0.0.1` only
|
|
791
|
-
- No credentials logged even in verbose mode
|
|
792
|
-
- `MCP-Protocol-Version` and `MCP-Session-Id` headers handled per MCP spec
|
|
793
|
-
|
|
794
|
-
## Error handling
|
|
1000
|
+
## Errors
|
|
795
1001
|
|
|
796
1002
|
`mcpc` provides clear error messages for common issues:
|
|
797
1003
|
|
|
@@ -801,8 +1007,6 @@ This architecture ensures:
|
|
|
801
1007
|
- **Tool execution errors**: Returns server error messages with context
|
|
802
1008
|
- **Bridge crashes**: Detects and cleans up orphaned processes, offers restart
|
|
803
1009
|
|
|
804
|
-
Use `--verbose` to print detailed debugging information to stderr (includes JSON-RPC messages, streaming events, and protocol negotiation).
|
|
805
|
-
|
|
806
1010
|
### Exit codes
|
|
807
1011
|
|
|
808
1012
|
- `0` - Success
|
|
@@ -811,88 +1015,23 @@ Use `--verbose` to print detailed debugging information to stderr (includes JSON
|
|
|
811
1015
|
- `3` - Network error (connection failed, timeout, etc.)
|
|
812
1016
|
- `4` - Authentication error (invalid credentials, forbidden, etc.)
|
|
813
1017
|
|
|
814
|
-
###
|
|
815
|
-
|
|
816
|
-
- **Network errors**: Automatic retry with exponential backoff (3 attempts)
|
|
817
|
-
- **Stream reconnection**: Starts at 1s, doubles to max 30s
|
|
818
|
-
- **Bridge restart**: Automatic on crash detection (recreates session on next command)
|
|
819
|
-
- **Timeouts**: Configurable per-request timeout (default: 5 minutes)
|
|
820
|
-
|
|
821
|
-
## Interactive shell
|
|
822
|
-
|
|
823
|
-
The interactive shell provides a REPL-style interface for MCP servers:
|
|
824
|
-
|
|
825
|
-
```bash
|
|
826
|
-
mcpc @apify shell
|
|
827
|
-
```
|
|
828
|
-
|
|
829
|
-
**Features:**
|
|
830
|
-
- Command history with arrow key navigation (saved to `~/.mcpc/history`, last 1000 commands)
|
|
831
|
-
- Real-time server notifications displayed during session
|
|
832
|
-
- Prompt shows session name: `mcpc(@apify)> `
|
|
833
|
-
|
|
834
|
-
**Shell-specific commands:**
|
|
835
|
-
- `help` - Show available commands
|
|
836
|
-
- `exit` or `quit` or Ctrl+D - Exit shell
|
|
837
|
-
- Ctrl+C - Cancel current operation
|
|
838
|
-
|
|
839
|
-
**Example session:**
|
|
840
|
-
```
|
|
841
|
-
$ mcpc @apify shell
|
|
842
|
-
Connected to apify (https://mcp.apify.com)
|
|
843
|
-
MCP version: 2025-11-25
|
|
844
|
-
|
|
845
|
-
mcpc(@apify)> tools-list
|
|
846
|
-
Available tools:
|
|
847
|
-
- search-actors
|
|
848
|
-
- get-actor
|
|
849
|
-
- run-actor
|
|
850
|
-
|
|
851
|
-
mcpc(@apify)> tools-call search-actors --args query="tiktok scraper"
|
|
852
|
-
[results...]
|
|
1018
|
+
### Verbose mode
|
|
853
1019
|
|
|
854
|
-
|
|
855
|
-
```
|
|
856
|
-
|
|
857
|
-
## Claude Code skill
|
|
858
|
-
|
|
859
|
-
For AI coding agents using [Claude Code](https://claude.ai/code), we provide a skill that teaches Claude how to use mcpc effectively.
|
|
860
|
-
|
|
861
|
-
**Installation:**
|
|
862
|
-
```bash
|
|
863
|
-
mkdir -p ~/.claude/skills/mcpc
|
|
864
|
-
cp claude-skill/SKILL.md ~/.claude/skills/mcpc/
|
|
865
|
-
```
|
|
866
|
-
|
|
867
|
-
Then restart Claude Code. The skill enables Claude to interact with MCP servers via mcpc commands instead of function calling, which is more efficient and uses fewer tokens.
|
|
868
|
-
|
|
869
|
-
See [`claude-skill/README.md`](./claude-skill/README.md) for details.
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
## Troubleshooting
|
|
873
|
-
|
|
874
|
-
To see what's happening, enable detailed logging with `--verbose`:
|
|
1020
|
+
To see what's happening, enable detailed logging with `--verbose`.
|
|
875
1021
|
|
|
876
1022
|
```bash
|
|
877
1023
|
mcpc --verbose @apify tools-list
|
|
878
1024
|
```
|
|
879
1025
|
|
|
880
|
-
This
|
|
881
|
-
- Protocol negotiation details
|
|
882
|
-
- JSON-RPC request/response messages
|
|
883
|
-
- Streaming events and reconnection attempts
|
|
884
|
-
- Bridge communication (socket messages)
|
|
885
|
-
- File locking operations
|
|
886
|
-
- Prints server log messages with severity `debug`, `info`, and `notice` to standard output
|
|
1026
|
+
This causes `mcpc` to print detailed debug messages to stderr.
|
|
887
1027
|
|
|
888
1028
|
### Logs
|
|
889
1029
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
Log rotation: Keep last 10MB per session, max 5 files.
|
|
1030
|
+
The background bridge processes log to `~/.mcpc/logs/bridge-@<session>.log`.
|
|
1031
|
+
The main `mcpc` process doesn't save log files, but supports [verbose mode](#verbose-mode).
|
|
1032
|
+
`mcpc` automatically rotates log files: keep last 10MB per session, max 5 files.
|
|
894
1033
|
|
|
895
|
-
###
|
|
1034
|
+
### Troubleshooting
|
|
896
1035
|
|
|
897
1036
|
**"Cannot connect to bridge"**
|
|
898
1037
|
- Bridge may have crashed. Try: `mcpc @<session-name> tools-list` to restart the bridge
|
|
@@ -901,7 +1040,7 @@ Log rotation: Keep last 10MB per session, max 5 files.
|
|
|
901
1040
|
|
|
902
1041
|
**"Session not found"**
|
|
903
1042
|
- List existing sessions: `mcpc`
|
|
904
|
-
- Create new session if expired: `mcpc @<session-name> close` and `mcpc <target>
|
|
1043
|
+
- Create new session if expired: `mcpc @<session-name> close` and `mcpc <target> connect @<session-name>`
|
|
905
1044
|
|
|
906
1045
|
**"Authentication failed"**
|
|
907
1046
|
- List saved OAuth profiles: `mcpc`
|
|
@@ -909,13 +1048,12 @@ Log rotation: Keep last 10MB per session, max 5 files.
|
|
|
909
1048
|
- For bearer tokens: provide `--header "Authorization: Bearer ${TOKEN}"` again
|
|
910
1049
|
|
|
911
1050
|
|
|
912
|
-
##
|
|
1051
|
+
## Development
|
|
913
1052
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
## Authors
|
|
1053
|
+
`mcpc` was built by [Jan Curn](https://x.com/jancurn) of [Apify](https://apify.com) with the help of Claude Code during the late nights of Xmas
|
|
1054
|
+
2025 in North Beach, San Francisco.
|
|
917
1055
|
|
|
918
|
-
|
|
1056
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, architecture overview, and contribution guidelines.
|
|
919
1057
|
|
|
920
1058
|
## License
|
|
921
1059
|
|