@apify/mcpc 0.1.2 → 0.1.4

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.
Files changed (124) hide show
  1. package/.claude/settings.local.json +35 -2
  2. package/.idea/codeStyles/Project.xml +4 -0
  3. package/.idea/workspace.xml +290 -274
  4. package/CONTRIBUTING.md +210 -0
  5. package/README.md +225 -344
  6. package/TODOs.md +29 -76
  7. package/dist/bridge/index.js +153 -86
  8. package/dist/bridge/index.js.map +1 -1
  9. package/dist/cli/commands/auth.d.ts.map +1 -1
  10. package/dist/cli/commands/auth.js +9 -4
  11. package/dist/cli/commands/auth.js.map +1 -1
  12. package/dist/cli/commands/clean.d.ts.map +1 -1
  13. package/dist/cli/commands/clean.js +42 -73
  14. package/dist/cli/commands/clean.js.map +1 -1
  15. package/dist/cli/commands/prompts.d.ts.map +1 -1
  16. package/dist/cli/commands/prompts.js +24 -1
  17. package/dist/cli/commands/prompts.js.map +1 -1
  18. package/dist/cli/commands/sessions.d.ts +5 -1
  19. package/dist/cli/commands/sessions.d.ts.map +1 -1
  20. package/dist/cli/commands/sessions.js +162 -132
  21. package/dist/cli/commands/sessions.js.map +1 -1
  22. package/dist/cli/commands/tools.d.ts.map +1 -1
  23. package/dist/cli/commands/tools.js +39 -1
  24. package/dist/cli/commands/tools.js.map +1 -1
  25. package/dist/cli/helpers.d.ts +5 -2
  26. package/dist/cli/helpers.d.ts.map +1 -1
  27. package/dist/cli/helpers.js +114 -74
  28. package/dist/cli/helpers.js.map +1 -1
  29. package/dist/cli/index.js +50 -14
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/output.d.ts +19 -3
  32. package/dist/cli/output.d.ts.map +1 -1
  33. package/dist/cli/output.js +395 -85
  34. package/dist/cli/output.js.map +1 -1
  35. package/dist/cli/parser.d.ts +4 -0
  36. package/dist/cli/parser.d.ts.map +1 -1
  37. package/dist/cli/parser.js +88 -1
  38. package/dist/cli/parser.js.map +1 -1
  39. package/dist/cli/shell-parser.d.ts.map +1 -1
  40. package/dist/cli/shell-parser.js.map +1 -1
  41. package/dist/cli/shell.js +13 -13
  42. package/dist/cli/shell.js.map +1 -1
  43. package/dist/core/factory.d.ts +4 -4
  44. package/dist/core/factory.d.ts.map +1 -1
  45. package/dist/core/factory.js +4 -34
  46. package/dist/core/factory.js.map +1 -1
  47. package/dist/core/mcp-client.d.ts +2 -2
  48. package/dist/core/mcp-client.d.ts.map +1 -1
  49. package/dist/core/mcp-client.js +18 -22
  50. package/dist/core/mcp-client.js.map +1 -1
  51. package/dist/core/transports.d.ts +6 -2
  52. package/dist/core/transports.d.ts.map +1 -1
  53. package/dist/core/transports.js +58 -37
  54. package/dist/core/transports.js.map +1 -1
  55. package/dist/lib/auth/keychain.d.ts.map +1 -1
  56. package/dist/lib/auth/keychain.js +5 -2
  57. package/dist/lib/auth/keychain.js.map +1 -1
  58. package/dist/lib/auth/oauth-flow.d.ts.map +1 -1
  59. package/dist/lib/auth/oauth-flow.js +14 -2
  60. package/dist/lib/auth/oauth-flow.js.map +1 -1
  61. package/dist/lib/auth/oauth-provider.d.ts +19 -8
  62. package/dist/lib/auth/oauth-provider.d.ts.map +1 -1
  63. package/dist/lib/auth/oauth-provider.js +79 -29
  64. package/dist/lib/auth/oauth-provider.js.map +1 -1
  65. package/dist/lib/auth/oauth-token-manager.d.ts +8 -0
  66. package/dist/lib/auth/oauth-token-manager.d.ts.map +1 -1
  67. package/dist/lib/auth/oauth-token-manager.js +33 -0
  68. package/dist/lib/auth/oauth-token-manager.js.map +1 -1
  69. package/dist/lib/auth/{auth-profiles.d.ts → profiles.d.ts} +7 -2
  70. package/dist/lib/auth/profiles.d.ts.map +1 -0
  71. package/dist/lib/auth/profiles.js +188 -0
  72. package/dist/lib/auth/profiles.js.map +1 -0
  73. package/dist/lib/auth/token-refresh.js +1 -1
  74. package/dist/lib/auth/token-refresh.js.map +1 -1
  75. package/dist/lib/bridge-client.js.map +1 -1
  76. package/dist/lib/bridge-manager.d.ts +2 -3
  77. package/dist/lib/bridge-manager.d.ts.map +1 -1
  78. package/dist/lib/bridge-manager.js +48 -63
  79. package/dist/lib/bridge-manager.js.map +1 -1
  80. package/dist/lib/cleanup.d.ts +5 -0
  81. package/dist/lib/cleanup.d.ts.map +1 -0
  82. package/dist/lib/cleanup.js +48 -0
  83. package/dist/lib/cleanup.js.map +1 -0
  84. package/dist/lib/config.d.ts +3 -3
  85. package/dist/lib/config.d.ts.map +1 -1
  86. package/dist/lib/config.js.map +1 -1
  87. package/dist/lib/errors.d.ts +1 -1
  88. package/dist/lib/errors.d.ts.map +1 -1
  89. package/dist/lib/errors.js +5 -1
  90. package/dist/lib/errors.js.map +1 -1
  91. package/dist/lib/index.d.ts +1 -0
  92. package/dist/lib/index.d.ts.map +1 -1
  93. package/dist/lib/index.js +1 -0
  94. package/dist/lib/index.js.map +1 -1
  95. package/dist/lib/logger.d.ts +5 -1
  96. package/dist/lib/logger.d.ts.map +1 -1
  97. package/dist/lib/logger.js +10 -1
  98. package/dist/lib/logger.js.map +1 -1
  99. package/dist/lib/schema-validator.d.ts +36 -0
  100. package/dist/lib/schema-validator.d.ts.map +1 -0
  101. package/dist/lib/schema-validator.js +220 -0
  102. package/dist/lib/schema-validator.js.map +1 -0
  103. package/dist/lib/session-client.d.ts +2 -2
  104. package/dist/lib/session-client.d.ts.map +1 -1
  105. package/dist/lib/session-client.js +9 -9
  106. package/dist/lib/session-client.js.map +1 -1
  107. package/dist/lib/sessions.d.ts +6 -1
  108. package/dist/lib/sessions.d.ts.map +1 -1
  109. package/dist/lib/sessions.js +72 -14
  110. package/dist/lib/sessions.js.map +1 -1
  111. package/dist/lib/types.d.ts +17 -25
  112. package/dist/lib/types.d.ts.map +1 -1
  113. package/dist/lib/types.js.map +1 -1
  114. package/dist/lib/utils.d.ts +4 -1
  115. package/dist/lib/utils.d.ts.map +1 -1
  116. package/dist/lib/utils.js +24 -3
  117. package/dist/lib/utils.js.map +1 -1
  118. package/{claude-skill → docs/claude-skill}/SKILL.md +2 -2
  119. package/package.json +17 -8
  120. package/TESTING.md +0 -212
  121. package/dist/lib/auth/auth-profiles.d.ts.map +0 -1
  122. package/dist/lib/auth/auth-profiles.js +0 -105
  123. package/dist/lib/auth/auth-profiles.js.map +0 -1
  124. /package/{claude-skill → docs/claude-skill}/README.md +0 -0
package/README.md CHANGED
@@ -1,30 +1,86 @@
1
- # mcpc: Universal MCP command-line client
1
+ # `mcpc`: Universal MCP command-line client
2
2
 
3
3
  `mcpc` is a CLI for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/),
4
- which maps MCP requests to intuitive commands for shell access, scripts, and AI coding agents.
4
+ which 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
7
  securely login via OAuth credentials and store credentials,
8
- and keep long-term sessions to multiple servers in parallel.
8
+ and keep long-term sessions to multiple servers.
9
9
  It supports all major MCP features, including tools, resources, prompts, asynchronous tasks, and notifications.
10
10
 
11
11
  `mcpc` is handy for manual testing of MCP servers, scripting,
12
12
  and AI coding agents to use MCP in ["code mode"](https://www.anthropic.com/engineering/code-execution-with-mcp),
13
13
  for better accuracy and lower token compared to traditional tool function calling.
14
- After all, UNIX-compatible shell script is THE most universal coding language, for both people and LLMs.
14
+ After all, UNIX-compatible shell script is THE most universal coding language, for people and LLMs alike.
15
15
 
16
- Note that `mcpc` is deterministic and does not use any LLM on its own; that's for the higher layer to do.
16
+ Note that `mcpc` does not use LLMs on its own; that's a job for the higher layer.
17
17
 
18
- ## Features
18
+ **Key features**
19
19
 
20
- - 🔌 **Universal MCP client** - Works with any MCP server over Streamable HTTP or stdio.
20
+ - 🔌 **Super compatible** - Works with any MCP server over Streamable HTTP or stdio.
21
21
  - 🔄 **Persistent sessions** - Keep multiple server connections alive simultaneously.
22
22
  - 🚀 **Zero setup** - Connect to remote servers instantly with just a URL.
23
- - 🔧 **Full protocol support** - Tools, resources, prompts, sampling, dynamic discovery, and async notifications.
24
- - 📊 **`--json` output** - Easy integration with `jq`, scripts, and other CLI tools.
23
+ - 🔧 **Full protocol support** - Tools, resources, prompts, dynamic discovery, and async notifications.
24
+ - 📊 **JSON output** - Easy integration with `jq`, scripts, and other CLI tools.
25
25
  - 🤖 **AI-friendly** - Designed for code generation and automated workflows.
26
26
  - 🔒 **Secure** - OS keychain integration for credentials, encrypted auth storage.
27
27
 
28
+
29
+ ## Table of contents
30
+
31
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
32
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
33
+
34
+ - [Install](#install)
35
+ - [Quickstart](#quickstart)
36
+ - [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
+ - [Sessions](#sessions)
49
+ - [Managing sessions](#managing-sessions)
50
+ - [Piping between sessions](#piping-between-sessions)
51
+ - [Output format](#output-format)
52
+ - [Human-readable (default)](#human-readable-default)
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)
59
+ - [Configuration](#configuration)
60
+ - [MCP config JSON file](#mcp-config-json-file)
61
+ - [Environment variables](#environment-variables)
62
+ - [MCP protocol notes](#mcp-protocol-notes)
63
+ - [Security](#security)
64
+ - [Authentication](#authentication-1)
65
+ - [Credential storage](#credential-storage)
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)
79
+ - [License](#license)
80
+
81
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
82
+
83
+
28
84
  ## Install
29
85
 
30
86
  ```bash
@@ -37,69 +93,55 @@ npm install -g @apify/mcpc
37
93
  # List all active sessions and saved authentication profiles
38
94
  mcpc
39
95
 
40
- # Use a local server package referenced by MCP config file
41
- mcpc --config ~/.vscode/mcp.json filesystem tools-list
42
-
43
- # Login to OAuth-enabled MCP server and save authentication for future use
96
+ # Login to remote MCP server and save OAuth credentials for future use
44
97
  mcpc mcp.apify.com login
45
98
 
46
- # Show information about a remote MCP server and open interactive shell
99
+ # Show information about a remote MCP server
47
100
  mcpc mcp.apify.com
48
- mcpc mcp.apify.com shell
49
101
 
50
102
  # Use JSON mode for scripting
51
- mcpc --json mcp.apify.com tools-list
103
+ mcpc mcp.apify.com tools-list --json
52
104
 
53
- # Create a persistent session (or reconnect if it exists but bridge is dead)
105
+ # Create and use persistent MCP session
54
106
  mcpc mcp.apify.com session @test
55
- mcpc @test tools-call search-actors --args query="web crawler"
107
+ mcpc @test tools-call search-actors --args keywords="web crawler"
56
108
  mcpc @test shell
109
+
110
+ # Interact with a local MCP server package (stdio) referenced from config file
111
+ mcpc --config ~/.vscode/mcp.json filesystem tools-list
57
112
  ```
58
113
 
59
114
  ## Usage
60
115
 
61
116
  ```bash
62
- mcpc [--json] [--config <file>] [-H|--header "K: V"] [-v|--verbose]
63
- [--schema <file>] [--schema-mode <mode>] [--timeout <seconds>]
64
- [--clean|--clean=sessions,logs,profiles,all]
65
- <target> <command...>
66
-
67
- # Lists all active sessions and saved authentication profiles
68
- mcpc
69
-
70
- # Shows server or session info, instructions, and capabilities
71
- mcpc <target>
72
-
73
- # MCP commands
74
- mcpc <target> tools
75
- mcpc <target> tools-list
76
- mcpc <target> tools-schema <tool-name>
77
- mcpc <target> tools-call <tool-name> [--args key=val key2:=json ...] [--args-file <file>]
78
-
79
- mcpc <target> prompts
80
- mcpc <target> prompts-list
81
- mcpc <target> prompts-get <prompt-name> [--args key=val key2:=json ...] [--args-file <file>]
82
-
83
- mcpc <target> resources
84
- mcpc <target> resources-list
85
- mcpc <target> resources-read <uri> [-o <file>] [--max-size <bytes>]
86
- mcpc <target> resources-subscribe <uri> # TODO
87
- mcpc <target> resources-unsubscribe <uri>
88
- mcpc <target> resources-templates-list
89
-
90
- mcpc <target> logging-set-level <level>
91
-
92
- # Interactive MCP shell
93
- mcpc <target> shell
94
-
95
- # Persistent sessions
96
- mcpc <server> session @<session-name> [--profile <name>]
97
- mcpc @<session-name> <command...>
98
- mcpc @<session-name> close
99
-
100
- # Saved OAuth profiles for remote MCP servers
101
- mcpc <server> login [--profile <name>]
102
- mcpc <server> logout [--profile <name>]
117
+ Usage: mcpc [options] [target] [command]
118
+
119
+ Options:
120
+ -v, --version Output the version number
121
+ -j, --json Output in JSON format for scripting
122
+ --verbose Enable verbose logging
123
+ -c, --config <file> Path to MCP config JSON file (e.g. ".vscode/mcp.json")
124
+ -H, --header <header> Add HTTP header (can be repeated)
125
+ --timeout <seconds> Request timeout in seconds (default: 300)
126
+ --profile <name> Authentication profile to use (default: "default")
127
+ --schema <file> Validate against expected tool/prompt schema
128
+ --schema-mode <mode> Schema validation mode: "strict", "compatible" (default), or "ignore"
129
+ --clean[=types] Clean up mcpc data (types: "sessions,logs,profiles,all")
130
+ -h, --help Display general help
131
+
132
+ Targets:
133
+ <server-url> Remote MCP server URL (e.g. "mcp.apify.com")
134
+ <config-entry> Entry from MCP config file specified in --config (e.g. "fs")
135
+ @<session> Named persistent session (e.g. "@apify")
136
+
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
103
145
  ```
104
146
 
105
147
  where `<target>` can be one of (in this order of precedence):
@@ -146,16 +188,6 @@ echo '{"query":"hello","count":10}' | mcpc @server tools-call my-tool
146
188
  - `=` assigns as string, `:=` parses as JSON
147
189
  - Stdin is automatically detected when input is piped (not interactive terminal)
148
190
 
149
- ## Global flags
150
-
151
- - `--json` - Input and output in JSON format for scripting
152
- - `--config <file>` - Use MCP config JSON file (e.g., `.vscode/mcp.json`)
153
- - `-H, --header "Key: Value"` - Add HTTP header (can be repeated)
154
- - `-v, --verbose` - Enable verbose logging (shows protocol details)
155
- - `--timeout <seconds>` - Request timeout in seconds (default: 300)
156
- - `--schema <file>` - Validate against expected tool/prompt schema
157
- - `--schema-mode <mode>` - Schema validation mode: `strict`, `compatible`, or `ignore` (default: `compatible`)
158
-
159
191
  ## Authentication
160
192
 
161
193
  `mcpc` supports all standard [authentication methods](https://modelcontextprotocol.io/specification/latest/basic/authorization) for MCP servers,
@@ -210,7 +242,7 @@ This allows you to:
210
242
  - Manage credentials independently from sessions
211
243
 
212
244
  **Key concepts:**
213
- - **Authentication profile**: Named set of OAuth credentials for a specific server (stored in `~/.mcpc/auth-profiles.json` + OS keychain)
245
+ - **Authentication profile**: Named set of OAuth credentials for a specific server (stored in `~/.mcpc/profiles.json` + OS keychain)
214
246
  - **Session**: Active connection to a server that may reference an authentication profile (stored in `~/.mcpc/sessions.json`)
215
247
  - **Default profile**: When `--profile` is not specified, `mcpc` uses the authentication profile named `default`
216
248
 
@@ -315,7 +347,7 @@ When multiple authentication methods are available, `mcpc` uses this precedence
315
347
 
316
348
  ### Authentication profiles storage format
317
349
 
318
- By default, authentication profiles are stored in the `~/.mcpc/auth-profiles.json` file with the following structure:
350
+ By default, authentication profiles are stored in the `~/.mcpc/profiles.json` file with the following structure:
319
351
 
320
352
  ```json
321
353
  {
@@ -369,7 +401,7 @@ Instead of forcing every command to reconnect and reinitialize (which is slow an
369
401
  `mcpc` saves its state to `~/.mcpc/` directory (unless overridden by `MCPC_HOME_DIR`), in the following files:
370
402
 
371
403
  - `~/.mcpc/sessions.json` - Active sessions with references to authentication profiles (file-locked for concurrent access)
372
- - `~/.mcpc/auth-profiles.json` - Authentication profiles (OAuth metadata, scopes, expiry)
404
+ - `~/.mcpc/profiles.json` - Authentication profiles (OAuth metadata, scopes, expiry)
373
405
  - `~/.mcpc/bridges/` - Unix domain socket files for each bridge process
374
406
  - `~/.mcpc/logs/bridge-*.log` - Log files for each bridge process
375
407
  - OS keychain - Sensitive credentials (OAuth tokens, bearer tokens, client secrets)
@@ -398,6 +430,9 @@ mcpc
398
430
  mcpc @apify tools-list
399
431
  mcpc @apify shell
400
432
 
433
+ # Restart the session (kills and restarts the bridge process)
434
+ mcpc @apify restart
435
+
401
436
  # Close the session (terminates bridge process, but keeps authentication profile)
402
437
  mcpc @apify close
403
438
  ```
@@ -410,28 +445,66 @@ mcpc --json @apify tools-call search-actors --args query="tiktok scraper" \
410
445
  | mcpc @playwright tools-call run-browser
411
446
  ```
412
447
 
448
+ ### Output format
449
+
450
+ #### Human-readable (default)
451
+
452
+ Default output is formatted for human and AI readability with plain text, colors, and Markdown-like formatting.
453
+ The text is formatted in Markdown-compatible format for AIs with colors for easy human readability.
454
+
455
+ #### JSON mode
456
+
457
+ If `--json` option is provided, `mcpc` always emits only a single JSON object, in order to enable scripting.
458
+ For MCP commands, the returned objects are always consistent with the [MCP protocol specification](https://modelcontextprotocol.io/specification/latest).
459
+ On success, the JSON object is printed to stdout, otherwise to stderr.
460
+
413
461
  ### Scripting
414
462
 
415
- `mcpc` is designed to be easily usable in (AI-generated) scripts. To ensure consistency
416
- of your scripts with the current MCP server interface, you can use `--schema <file>` argument
417
- to pass `mcpc` the expected schema. If the MCP server's current schema is incompatible,
418
- the command returns an error.
463
+ `mcpc` is designed for us in (AI-generated) scripts.
464
+ With the `--json` option, `mcpc` returns a single JSON object (object or array) as follows:
465
+
466
+ - On success, the JSON object is printed to stdout
467
+ - On error, the JSON object is printed to stderr
468
+
469
+ You can use tools like `jq` to process the output.
470
+
471
+ Note that `--json` option has no effect on `--help` command,
472
+ or if there are invalid arguments, as those take precedence.
473
+
474
+ For all MCP operations, the **returned JSON is and always will be strictly consistent
475
+ with the [MCP specification](https://modelcontextprotocol.io/specification/latest)**,
476
+ based to the protocol version negotiated between client and server in the initial handshake.
477
+
478
+ Additionally, one of the core [design principles](CONTRIBUTING.md#design-principles) of `mcpc`
479
+ is to keep backwards compatibility to maximum extent possible, to ensure the scripts using `mcpc`
480
+ will not break over time.
481
+
482
+ #### MCP server schema changes
483
+
484
+ MCP is a fluid protocol, and MCP servers can change operations and their schema at any time.
485
+ To ensure your scripts fail fast whenever such schema change occurs, rather than fail silently later,
486
+ you can use the `--schema <file>` option to pass `mcpc` the expected operation schema.
487
+ If the MCP server's current schema is incompatible, the command returns an error.
419
488
 
420
489
  ```bash
421
490
  # Save tool schema for future validation
422
- mcpc --json @apify tools-schema search-actors > search-actors-schema.json
491
+ mcpc --json @apify tools-get search-actors > search-actors-schema.json
423
492
 
424
493
  # Use schema to ensure compatibility (fails if schema changed)
425
494
  mcpc @apify tools-call search-actors \
426
495
  --schema search-actors-schema.json \
427
496
  --schema-mode strict \
428
- --args query="tiktok scraper"
497
+ --args keywords="tiktok scraper"
429
498
  ```
430
499
 
431
- **Schema validation modes using the `--schema-mode` parameter:**
432
- - `strict` - Exact schema match required (all fields, types must be identical)
433
- - `compatible` (default) - Backwards compatible (new optional fields OK, required fields and types must match)
434
- - `ignore` - Skip schema validation
500
+ The `--schema-mode <mode>` parameter determines how `mcpc` validates the schema:
501
+
502
+ - `compatible` (default) - Backwards compatible (new optional fields OK, types of required
503
+ fields and passed arguments must match, descriptions are ignored). For tools, the output schema
504
+ is ignored.
505
+ - `strict` - Exact schema match required (all fields, their types and descriptions must be
506
+ identical). For tools, the output schema must match exactly.
507
+ - `ignore` - Skip schema validation altogether
435
508
 
436
509
  ### Session failover
437
510
 
@@ -466,7 +539,9 @@ mcpc https://mcp.apify.com session @apify
466
539
 
467
540
  ## Logging
468
541
 
469
- The background bridge process logs to `~/.mcpc/bridges/mcpc-@<session-name>.log`.
542
+ TODO: Move this to MPC features section
543
+
544
+ The background bridge process logs to `~/.mcpc/logs/bridge-<session-name>.log`.
470
545
  The main `mcpc` process doesn't save log files, but you can use `--verbose` flag to print all logs to stderr.
471
546
 
472
547
  MCP servers can be instructed to adjust their [logging level](https://modelcontextprotocol.io/specification/latest/server/utilities/logging)
@@ -493,6 +568,24 @@ mcpc @apify logging-set-level error
493
568
  **Note:** This sets the logging level on the **server side**. The actual log output depends on the server's implementation.
494
569
 
495
570
 
571
+ ## Cleanup
572
+
573
+ You can clean up the `mcpc` state and data using the `--clean` option:
574
+
575
+ ```bash
576
+ # Safe non-destructive cleanup: remove expired sessions, delete old orphaned logs
577
+ mcpc --clean
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
587
+ ```
588
+
496
589
  ## Configuration
497
590
 
498
591
  Configuration can be provided via file, environment variables, or command-line flags.
@@ -593,6 +686,8 @@ Config files support environment variable substitution using `${VAR_NAME}` synta
593
686
 
594
687
  ## MCP protocol notes
595
688
 
689
+ TODO: explain in detail how MCP concepts work in mcpc
690
+
596
691
  **Protocol initialization:**
597
692
  - `mcpc` follows the MCP initialization handshake: sends `initialize` request with protocol version and capabilities, receives server capabilities and instructions, then sends `initialized` notification
598
693
  - Protocol version negotiation: client proposes latest supported version (currently `2025-11-25`), server responds with version to use
@@ -607,10 +702,12 @@ Config files support environment variable substitution using `${VAR_NAME}` synta
607
702
  **Protocol features:**
608
703
  - `mcpc` supports all MCP primitives in both Streamable HTTP and stdio transports:
609
704
  - **Instructions**: Fetches and stores MCP server-provided `instructions`
610
- - **Tools**: Executable functions with JSON Schema-validated arguments.
705
+ - **Tools**: Executable functions with JSON Schema-validated arguments.
611
706
  - **Resources**: Data sources identified by URIs (e.g., `file:///path/to/file`, `https://example.com/data`), with optional subscriptions for change notifications
612
707
  - **Prompts**: Reusable message templates with customizable arguments
613
- - **Completion**: Provides access to Completion API for tools and resources, and offers completions in shell mode
708
+ - **Completion**: Provides access to Completion API for tools and resources
709
+ - **Asynchronous tasks**: Not implemented yet
710
+ - **Roots**: Not implemented yet
614
711
  - Supports server logging settings (`logging/setLevel`) and messages (`notifications/message`), and prints them to stderr or stdout based on verbosity level.
615
712
  - Handles server notifications: progress tracking, logging, and change notifications (`notifications/tools/list_changed`, `notifications/resources/list_changed`, `notifications/prompts/list_changed`)
616
713
  - Request multiplexing: supports up to 10 concurrent requests, queues up to 100 additional requests
@@ -618,38 +715,39 @@ Config files support environment variable substitution using `${VAR_NAME}` synta
618
715
  - Pings: `mcpc` periodically issues the MCP `ping` request to keep the connection alive
619
716
  - Sampling is not supported as `mcpc` has no access to an LLM
620
717
 
621
- ## Output format
622
-
623
- ### Human-readable (default)
624
-
625
- Default output is formatted for human and AI readability with plain text, colors, and Markdown-like formatting.
626
-
627
- ### JSON mode (`--json`)
628
-
629
- In JSON mode, `mcpc` always emits only a single JSON object to enable scripting.
630
- For MCP commands, the object is always consistent with the MCP protocol specification.
631
- On success, the JSON object is printed to stdout, otherwise to stderr.
632
-
633
718
  ## Security
634
719
 
635
- MCP enables arbitrary tool execution and data access; treat servers like you treat shells:
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:
636
721
 
637
722
  * Use least-privilege tokens/headers
638
723
  * Prefer trusted endpoints
639
724
  * Audit what tools do before running them
640
725
  * Review server permissions in interactive mode
641
726
 
727
+ ### Authentication
728
+
729
+ **OAuth 2.1 with PKCE:**
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
734
+
735
+ **Input validation:**
736
+ - Session names validated: `^@[a-zA-Z0-9_-]{1,64}$`
737
+ - Profile names validated: `^[a-zA-Z0-9_-]{1,64}$`
738
+ - URLs normalized and validated (HTTPS enforced, credentials stripped)
739
+
642
740
  ### Credential storage
643
741
 
644
742
  **OS keychain integration:**
645
743
  - OAuth refresh tokens are stored in the OS keychain (access tokens are kept in memory only)
646
744
  - OAuth client credentials (client_id, client_secret from dynamic registration) are stored in the keychain
647
745
  - All HTTP headers from `--header` flags are stored per-session in the keychain (as JSON)
648
- - The `~/.mcpc/auth-profiles.json` file only contains metadata (server URL, scopes, timestamps) - never tokens
746
+ - The `~/.mcpc/profiles.json` file only contains metadata (server URL, scopes, timestamps) - never tokens
649
747
 
650
748
  **Keychain entries:**
651
- - OAuth tokens: `mcpc:auth:<serverUrl>:<profileName>:oauth-tokens`
652
- - OAuth client: `mcpc:auth:<serverUrl>:<profileName>:oauth-client`
749
+ - OAuth tokens: `mcpc:auth-profile:<host>:<profileName>:tokens`
750
+ - OAuth client: `mcpc:auth-profile:<host>:<profileName>:client`
653
751
  - HTTP headers: `mcpc:session:<sessionName>:headers`
654
752
 
655
753
  ### Bridge process authentication
@@ -680,17 +778,18 @@ This architecture ensures:
680
778
 
681
779
  ### File permissions
682
780
 
683
- - `~/.mcpc/sessions.json` is set to `0600` (user-only read/write)
684
- - `~/.mcpc/auth-profiles.json` is set to `0600` (user-only read/write)
685
- - Bridge sockets in `~/.mcpc/bridges/` are created with `0700` permissions
686
- - Log files in `~/.mcpc/logs/` are created with `0600` permissions
781
+ - `~/.mcpc/sessions.json` is created with `0600` permissions (user-only read/write)
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
687
785
 
688
786
  ### Network security
689
787
 
690
- - HTTPS enforced for remote servers (HTTP auto-upgraded)
691
- - `Origin` header validation to prevent DNS rebinding attacks
692
- - Local servers bind to localhost (127.0.0.1) only
788
+ - HTTPS enforced for remote servers (HTTP auto-upgraded when no scheme provided)
789
+ - URL normalization removes username, password, and hash from URLs
790
+ - Local OAuth callback server binds to `127.0.0.1` only
693
791
  - No credentials logged even in verbose mode
792
+ - `MCP-Protocol-Version` and `MCP-Session-Id` headers handled per MCP spec
694
793
 
695
794
  ## Error handling
696
795
 
@@ -728,9 +827,8 @@ mcpc @apify shell
728
827
  ```
729
828
 
730
829
  **Features:**
731
- - Command history (saved to `~/.mcpc/history`, last 1000 commands)
732
- - Tab completion for commands, tool names, and resource URIs
733
- - Multi-line editing with arrow keys
830
+ - Command history with arrow key navigation (saved to `~/.mcpc/history`, last 1000 commands)
831
+ - Real-time server notifications displayed during session
734
832
  - Prompt shows session name: `mcpc(@apify)> `
735
833
 
736
834
  **Shell-specific commands:**
@@ -770,195 +868,10 @@ Then restart Claude Code. The skill enables Claude to interact with MCP servers
770
868
 
771
869
  See [`claude-skill/README.md`](./claude-skill/README.md) for details.
772
870
 
773
- ## Implementation
774
-
775
- `mcpc` is under active development and some things might not work 100% yet. You have been warned.
776
-
777
- ### Design principles
778
-
779
- - Delightful for humans and AI agents alike (interactive + scripting)
780
- - One clear way to do things (orthogonal commands, no surprises, saving tokens)
781
- - Do not ask for user input (except `shell` and `login`)
782
- - Be forgiving, always help users make forward progress (great errors + guidance)
783
- - JSON strictly consistency with the MCP specification
784
- - Minimal and portable (few deps, cross-platform)
785
- - No slop!
786
-
787
- ### Architecture overview
788
-
789
- ```
790
- TODO: add interaction diagram
791
- mcpc ──> cli ├──> bridge (UNIX socket) ──> MCP server (stdio/HTTP)
792
- ├──> MCP server (stdio/HTTP)
793
-
794
- mcpc (single package)
795
- ├── src/
796
- │ ├── core/ # Core MCP protocol implementation
797
- │ ├── bridge/ # Bridge process logic
798
- │ ├── cli/ # CLI interface
799
- │ └── lib/ # Shared utilities
800
- ├── bin/
801
- │ ├── mcpc # Main CLI executable
802
- │ └── mcpc-bridge # Bridge process executable
803
- ```
804
-
805
- ### Core module (runtime-agnostic)
806
-
807
- Implemented with minimal dependencies to support both Node.js (≥18.0.0) and Bun (≥1.0.0).
808
-
809
- **Core responsibilities:**
810
- - Transport selection and initialization (Streamable HTTP vs stdio)
811
- - MCP protocol implementation and version negotiation
812
- - Session state machine management
813
- - Streamable HTTP connection management (reconnection with exponential backoff)
814
- - Request/response correlation (JSON-RPC style with request IDs)
815
- - Multiplexing concurrent requests (up to 10 concurrent)
816
- - Event emitter for async notifications
817
-
818
- **Key dependencies:**
819
- - Native `fetch` API (available in Node.js 18+ and Bun)
820
- - Native process APIs for stdio transport
821
- - Minimal: UUID generation, event emitter abstraction
822
-
823
- ### Bridge process
824
-
825
- Implemented as a separate executable (`mcpc-bridge`) that maintains persistent connections.
826
-
827
- **Bridge responsibilities:**
828
- - Session persistence (reads/writes `~/.mcpc/sessions.json` with file locking)
829
- - Process lifecycle management for local package servers
830
- - Stdio framing and protocol handling
831
- - Unix domain socket server for CLI communication
832
- - Heartbeat mechanism for health monitoring
833
- - Orphaned process cleanup on startup
834
-
835
- **IPC protocol:**
836
- - Unix domain sockets (located in `~/.mcpc/bridges/<session-name>.sock`)
837
- - Named pipes on Windows
838
- - JSON-RPC style messages over socket
839
- - Control messages: init, request, cancel, close, health-check
840
-
841
- **Bridge discovery:**
842
- - CLI reads `~/.mcpc/sessions.json` to find socket path and PID
843
- - Validates bridge is alive (connect to socket + health-check)
844
- - Auto-restarts crashed bridges (detected via socket connection failure)
845
- - Cleanup: removes stale socket files for dead processes
846
-
847
- **Concurrency safety:**
848
- - `~/.mcpc/sessions.json` protected with file locking (`proper-lockfile` package)
849
- - Atomic writes (write to temp file, then rename)
850
- - Lock timeout: 5 seconds (fails if can't acquire lock)
851
-
852
- ### CLI executable
853
-
854
- The main `mcpc` command provides the user interface.
855
-
856
- **CLI responsibilities:**
857
- - Argument parsing (using `minimist` or similar)
858
- - Output formatting (human-readable vs `--json`)
859
- - Bridge lifecycle: start/connect/stop
860
- - Communication with bridge via socket
861
- - Interactive shell (REPL using `@inquirer/prompts`)
862
- - Configuration file loading (standard MCP JSON format)
863
- - Credential management (OS keychain via `keytar` package)
864
-
865
- **Shell implementation:**
866
- - Built on `@inquirer/prompts` for input handling
867
- - Command history using `~/.mcpc/history`
868
- - Tab completion using inquirer autocomplete and MCP completion API
869
- - Graceful exit handling (cleanup on Ctrl+C/Ctrl+D)
870
-
871
- ### Session lifecycle
872
-
873
- 1. User: `mcpc https://mcp.apify.com session @apify`
874
- 2. CLI: Atomically creates session entry in `~/.mcpc/sessions.json`
875
- 3. CLI: Spawns bridge process (`mcpc-bridge`)
876
- 4. Bridge: Creates Unix socket at `~/.mcpc/bridges/apify.sock`
877
- 5. Bridge: Performs MCP initialization handshake with server:
878
- - Sends initialize request with protocol version and capabilities
879
- - Receives server info, version, and capabilities
880
- - Sends initialized notification to activate session
881
- 6. Bridge: Updates session in `~/.mcpc/sessions.json` (adds PID, socket path, protocol version)
882
- 7. CLI: Confirms session created
883
-
884
- Later...
885
-
886
- 8. User: mcpc @apify tools-list
887
- 9. CLI: Reads `~/.mcpc/sessions.json`, finds socket path
888
- 10. CLI: Connects to bridge socket
889
- 11. CLI: Sends `tools/list` JSON-RPC request via socket
890
- 12. Bridge: Forwards to MCP server via Streamable HTTP
891
- 13. Bridge: Returns response via socket
892
- 14. CLI: Formats and displays to user
893
-
894
-
895
- ### Error recovery
896
-
897
- **Bridge crashes:**
898
- 1. CLI detects socket connection failure
899
- 2. Reads `~/.mcpc/sessions.json` for last known config
900
- 3. Spawns new bridge process
901
- 4. Bridge re-initializes connection to MCP server
902
- 5. Continues request
903
-
904
- **Network failures:**
905
- 1. Bridge detects connection error
906
- 2. Begins exponential backoff reconnection
907
- 3. Queues incoming requests (up to 100, max 3min)
908
- 4. On reconnect: drains queue
909
- 5. On timeout: fails queued requests with network error
910
-
911
- **Orphaned processes:**
912
- 1. On startup, CLI scans `~/.mcpc/bridges/` directory
913
- 2. For each socket file, attempts connection
914
- 3. If connection fails, reads PID from sessions.json
915
- 4. Checks if process exists (via `kill -0` or similar)
916
- 5. If dead: removes socket file and session entry
917
- 6. If alive but unresponsive: kills process, removes entries
918
-
919
- ## Testing strategy
920
-
921
- **Unit tests:**
922
- - Core protocol implementation (mocked transports)
923
- - Argument parsing and validation
924
- - Output formatting (human and JSON modes)
925
-
926
- **Integration tests:**
927
- - Mock MCP server (simple Streamable HTTP + stdio servers)
928
- - Bridge lifecycle (start, connect, restart, cleanup)
929
- - Session management with file locking
930
- - Stream reconnection logic
931
-
932
- **E2E tests:**
933
- - Real MCP server implementations
934
- - Cross-runtime (Node.js and Bun)
935
- - Interactive shell workflows
936
-
937
- **Test utilities:**
938
- - `examples/test-server/` - Reference MCP server for testing
939
- - `test/mock-keychain.ts` - Mock OS keychain for testing
940
871
 
941
872
  ## Troubleshooting
942
873
 
943
- ### Common issues
944
-
945
- **"Cannot connect to bridge"**
946
- - Bridge may have crashed. Try: `mcpc <server> session @<session-name>`
947
- - Check bridge is running: `ps aux | grep -e 'mcpc-bridge' -e '[m]cpc/dist/bridge'`
948
- - Check socket exists: `ls ~/.mcpc/bridges/`
949
-
950
- **"Session not found"**
951
- - Session may have expired. Create new session: `mcpc <target> session @<session-name>`
952
- - List existing sessions: `mcpc`
953
-
954
- **"Authentication failed"**
955
- - List saved profiles: `mcpc`
956
- - Re-authenticate: `mcpc <server> login [--profile <name>]`
957
- - For bearer tokens: provide `--header "Authorization: Bearer ${TOKEN}"` again
958
-
959
- ### Debug mode
960
-
961
- Enable detailed logging with `--verbose`:
874
+ To see what's happening, enable detailed logging with `--verbose`:
962
875
 
963
876
  ```bash
964
877
  mcpc --verbose @apify tools-list
@@ -979,62 +892,30 @@ Bridge processes log to:
979
892
 
980
893
  Log rotation: Keep last 10MB per session, max 5 files.
981
894
 
982
- ## Contributing
983
-
984
- Contributions are welcome!
985
-
986
- ### Development setup
987
-
988
- ```bash
989
- # Clone repository
990
- git clone https://github.com/apify/mcpc.git
991
- cd mcpc
992
-
993
- # Install dependencies
994
- npm install
995
-
996
- # Run tests
997
- npm test
998
-
999
- # Build
1000
- npm run build
1001
-
1002
- # Test locally
1003
- npm link
1004
- mcpc --help
1005
- ```
1006
-
1007
- ### Release process
1008
-
1009
- ```bash
1010
- # Run tests
1011
- npm test
1012
-
1013
- # Build
1014
- npm run build
1015
-
1016
- # Bump version
1017
- npm version patch|minor|major
895
+ ### Common issues
1018
896
 
1019
- # Publish
1020
- npm publish
897
+ **"Cannot connect to bridge"**
898
+ - Bridge may have crashed. Try: `mcpc @<session-name> tools-list` to restart the bridge
899
+ - Check bridge is running: `ps aux | grep -e 'mcpc-bridge' -e '[m]cpc/dist/bridge'`
900
+ - Check socket exists: `ls ~/.mcpc/bridges/`
1021
901
 
1022
- # Push tags
1023
- git push --tags
1024
- ```
902
+ **"Session not found"**
903
+ - List existing sessions: `mcpc`
904
+ - Create new session if expired: `mcpc @<session-name> close` and `mcpc <target> session @<session-name>`
1025
905
 
1026
- Please open an issue or pull request on [GitHub](https://github.com/apify/mcpc).
906
+ **"Authentication failed"**
907
+ - List saved OAuth profiles: `mcpc`
908
+ - Re-authenticate: `mcpc <server> login [--profile <name>]`
909
+ - For bearer tokens: provide `--header "Authorization: Bearer ${TOKEN}"` again
1027
910
 
1028
911
 
1029
- ### References
912
+ ## Contributing
1030
913
 
1031
- - [Official MCP documentation](https://modelcontextprotocol.io/llms.txt)
1032
- - [Official TypeScript SDK for MCP servers and clients](https://www.npmjs.com/package/@modelcontextprotocol/sdk)
1033
- - [MCP Inspector](https://github.com/modelcontextprotocol/inspector) - CLI client implementation for reference
914
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, architecture overview, and contribution guidelines.
1034
915
 
1035
916
  ## Authors
1036
917
 
1037
- Built by [Jan Curn](https://x.com/jancurn), [Apify](https://apify.com), and contributors welcome.
918
+ Built by [Jan Curn](https://x.com/jancurn) / [Apify](https://apify.com).
1038
919
 
1039
920
  ## License
1040
921