{"id":35797552,"url":"https://github.com/apify/mcpc","last_synced_at":"2026-06-03T22:00:24.676Z","repository":{"id":331380790,"uuid":"1112733896","full_name":"apify/mcpc","owner":"apify","description":"A universal CLI client for MCP. mcpc supports persistent sessions, stdio/HTTP, OAuth 2.1, tasks, JSON output for code mode, proxy for AI sandboxes, x402, and more.","archived":false,"fork":false,"pushed_at":"2026-06-01T16:45:34.000Z","size":6584,"stargazers_count":665,"open_issues_count":16,"forks_count":62,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-06-01T18:21:40.750Z","etag":null,"topics":["ai-agents","bash","claude","cli","code-mode","command-line","mcp","mcp-client","model-context-protocol","shell"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@apify/mcpc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-09T03:00:11.000Z","updated_at":"2026-06-01T13:01:17.000Z","dependencies_parsed_at":"2026-02-20T10:08:01.557Z","dependency_job_id":null,"html_url":"https://github.com/apify/mcpc","commit_stats":null,"previous_names":["apify/mcpc","apify/mcp-cli"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/apify/mcpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Fmcpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Fmcpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Fmcpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Fmcpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apify","download_url":"https://codeload.github.com/apify/mcpc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apify%2Fmcpc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33881107,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","bash","claude","cli","code-mode","command-line","mcp","mcp-client","model-context-protocol","shell"],"created_at":"2026-01-07T10:00:54.771Z","updated_at":"2026-06-03T22:00:24.663Z","avatar_url":"https://github.com/apify.png","language":"TypeScript","funding_links":[],"categories":["📚 Projects (2474 total)","TypeScript"],"sub_categories":["MCP Servers"],"readme":"# mcpc — a universal MCP CLI client\n\n![mcpc logo](https://apify.github.io/mcpc/client-logo.svg?v=2)\n\n[![npm version](https://img.shields.io/npm/v/@apify/mcpc.svg)](https://www.npmjs.com/package/@apify/mcpc)\n[![npm downloads](https://img.shields.io/npm/dm/@apify/mcpc.svg)](https://www.npmjs.com/package/@apify/mcpc)\n[![CI](https://github.com/apify/mcpc/actions/workflows/ci.yml/badge.svg)](https://github.com/apify/mcpc/actions/workflows/ci.yml)\n[![License](https://img.shields.io/npm/l/@apify/mcpc.svg)](https://github.com/apify/mcpc/blob/main/LICENSE)\n\n`mcpc` is a command-line client for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)\nthat maps MCP operations to intuitive commands for interactive shell use, scripting, and AI agents.\n\n`mcpc` is your new Swiss Army knife for MCP. It's great for manual inspection and debugging of MCP servers,\nas well as for agents to leverage all modern MCP capabilities through the most universal\ncoding interface: the UNIX shell.\n\n**Key features:**\n\n- 🔧 **Full MCP support** - HTTP/stdio transports, instructions, tools, async tasks, resources, prompts, ...\n- 🔄 **Persistent sessions** - Keep multiple stateful connections alive simultaneously.\n- 🗺️ **Progressive tool discovery** - Find relevant MCP tools on the fly to save tokens and increase accuracy.\n- 🔌 **Code mode** - JSON output composes with `jq`, `xargs`, and shell pipelines for MCP workflows as shell scripts.\n- 🔒 **Secure** - Full OAuth 2.1 support with CMID and DCR, uses OS keychain for credentials storage.\n- 🤖 **AI sandboxing** - Proxy MCP server connections to protect credentials from AI-generated code.\n- 🪶 **Lightweight** - Minimal dependencies, works on Mac/Win/Linux, doesn't use LLMs on its own.\n- 💸 **Agentic payments** - Experimental support for the [x402](https://www.x402.org/) protocol on [Base](https://www.base.org/).\n\n![mcpc screenshot](https://raw.githubusercontent.com/apify/mcpc/main/docs/images/mcpc-demo.gif)\n\n## Table of contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Motivation](#motivation)\n- [Install](#install)\n- [Quickstart](#quickstart)\n- [Usage](#usage)\n- [Sessions](#sessions)\n- [Authentication](#authentication)\n- [MCP proxy](#mcp-proxy)\n- [AI agents](#ai-agents)\n- [Agentic payments (x402)](#agentic-payments-x402)\n- [MCP support](#mcp-support)\n- [Configuration](#configuration)\n- [Security](#security)\n- [Errors](#errors)\n- [Development](#development)\n- [Related work](#related-work)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Motivation\n\nMany AI agents misuse MCP. They treat tools as prompt-time function calls, repeatedly injecting\ntool definitions and results into the context. Tokens get wasted, context rots, the\nagent gets slower and less reliable, and popular conclusion that: _\"MCP sucks, CLIs are better\"_.\n\n`mcpc` challenges that narrative. It maps every MCP operation to an intuitive CLI command that\nagents pick up from `--help` alone. Any agent with shell access gets full MCP support without\nwiring up dozens of MCP functions. Just one `Bash()` tool, and `mcpc` handles the rest:\n\n```\n\n ┌──────────┐   Bash()   ┌────────┐    MCP    ┌────────────┐\n │ AI agent │ ─────────► │  mcpc  │ ────────► │ MCP server │\n └──────────┘            └────────┘           └────────────┘\n                                     Sessions, OAuth, Tools,\n                                     Resources, Prompts,\n                                     Tasks, x402, ...\n```\n\nCLI is the perfect _local_ interface between agents and MCP, while MCP remains the\nstandard _remote_ interface for server discovery, authentication, payments, and access control.\nThe two aren't exclusive – they're complementary.\n\nAs a bonus, the same `mcpc` configuration, OAuth profiles, and live sessions can be shared across\nmany AI agents on the same machine. Authenticate once, reuse everywhere.\n\n## Install\n\nRequires a JavaScript runtime — install the latest [Node.js](https://nodejs.org/en/download) or [Bun](https://bun.sh) if you don't have one yet.\n\n```bash\nnpm install -g @apify/mcpc\n\n# Or with Bun\nbun install -g @apify/mcpc\n```\n\n**Linux:** credentials use the OS keychain via the [Secret Service API](https://specifications.freedesktop.org/secret-service/).\nGNOME/KDE desktops work out of the box. On headless/CI systems, `mcpc` falls back to a\nfile-based store (`~/.mcpc/credentials`, mode `0600`).\n\nTo force the keychain on headless systems, install `libsecret` + `gnome-keyring`\n(via `apt-get`, `dnf`, or `pacman`) and run:\n\n```bash\ndbus-run-session -- bash -c \"echo -n 'password' | gnome-keyring-daemon --unlock \u0026\u0026 mcpc ...\"\n```\n\n## Quickstart\n\n```bash\n# List all active sessions and saved authentication profiles\nmcpc\n\n# Login to remote MCP server and save OAuth credentials for future use\nmcpc login mcp.apify.com\n\n# Create a persistent session and interact with it\nmcpc connect mcp.apify.com @test\nmcpc @test                                            # show server info\nmcpc @test tools-list\nmcpc @test tools-call search-actors keywords:=\"website crawler\"\nmcpc @test shell\n\n# Use JSON mode for scripting\nmcpc --json @test tools-list\n\n# Use a local MCP server package (stdio) referenced from config file\nmcpc connect ./.vscode/mcp.json:filesystem @fs\nmcpc @fs tools-list\n```\n\n## Usage\n\n\u003c!-- AUTO-GENERATED: mcpc --help --\u003e\n\n```\nUsage: mcpc [\u003c@session\u003e] [\u003ccommand\u003e] [options]\n\nUniversal command-line client for the Model Context Protocol (MCP).\n\nCommands:\n  connect [\u003cserver\u003e] [@session]  Connect to an MCP server and start a new named @session\n  close \u003c@session\u003e               Close a session\n  restart \u003c@session\u003e             Restart a session (losing all state)\n  login \u003cserver\u003e                 Interactively login to a server using OAuth and save profile\n  logout \u003cserver\u003e                Delete an OAuth profile for a server\n  clean [resources...]           Clean up mcpc data (sessions, profiles, logs, all)\n  grep \u003cpattern\u003e                 Search tools and instructions across all active sessions\n  x402 [subcommand] [args...]    Configure an x402 payment wallet (EXPERIMENTAL)\n  help [command] [subcommand]    Show help for a specific command\n\nOptions:\n  --json                         Output in JSON format for scripting\n  --verbose                      Enable debug logging\n  --profile \u003cname\u003e               OAuth profile for the server (\"default\" if not provided)\n  --timeout \u003cseconds\u003e            Request timeout in seconds (default: 300)\n  --max-chars \u003cn\u003e                Truncate output to n characters (ignored in --json mode)\n  --insecure                     Skip TLS certificate verification (for self-signed certs)\n  -v, --version                  Output the version number\n  -h, --help                     Display help\n\nMCP session commands (after connecting):\n  \u003c@session\u003e                   Show MCP server info, capabilities, and tools overview\n  \u003c@session\u003e grep \u003cpattern\u003e    Search tools and instructions\n  \u003c@session\u003e tools-list        List all server tools\n  \u003c@session\u003e tools-get \u003cname\u003e  Get tool details and schema\n  \u003c@session\u003e tools-call \u003cname\u003e [arg:=val ... | \u003cjson\u003e | \u003cstdin]\n  \u003c@session\u003e prompts-list\n  \u003c@session\u003e prompts-get \u003cname\u003e [arg:=val ... | \u003cjson\u003e | \u003cstdin]\n  \u003c@session\u003e resources-list\n  \u003c@session\u003e resources-read \u003curi\u003e\n  \u003c@session\u003e resources-subscribe \u003curi\u003e\n  \u003c@session\u003e resources-unsubscribe \u003curi\u003e\n  \u003c@session\u003e resources-templates-list\n  \u003c@session\u003e skills-list\n  \u003c@session\u003e skills-get \u003cname\u003e [--raw]\n  \u003c@session\u003e tasks-list\n  \u003c@session\u003e tasks-get \u003ctaskId\u003e\n  \u003c@session\u003e tasks-result \u003ctaskId\u003e\n  \u003c@session\u003e tasks-cancel \u003ctaskId\u003e\n  \u003c@session\u003e logging-set-level \u003clevel\u003e\n  \u003c@session\u003e ping\n  \u003c@session\u003e logs [-n N] [--follow] [--since 1h]\n\nRun \"mcpc\" without arguments to show active sessions and OAuth profiles.\nRun \"mcpc --json\" to get the same data as `{ sessions: [...], profiles: [...] }`.\n```\n\n### General actions\n\nWith no arguments, `mcpc` lists all active sessions and saved OAuth profiles:\n\n```bash\n# List all sessions and OAuth profiles (also in JSON mode)\nmcpc\nmcpc --json\n\n# Show command help or version\nmcpc --help\nmcpc --version\n\n# Clean stale sessions and old log files\nmcpc clean\n```\n\n### Server formats\n\nThe `connect`, `login`, and `logout` commands accept a `\u003cserver\u003e` argument in these formats:\n\n- **Remote URL** (e.g. `mcp.apify.com` or `https://mcp.apify.com`) — scheme defaults to `https://`\n- **Config file entry** (e.g. `~/.vscode/mcp.json:filesystem`) — `file:entry-name` syntax\n\n`connect` additionally supports two **bulk** forms that connect many servers at once:\n\n- **Config file** without an entry (e.g. `~/.vscode/mcp.json`) — connect every server in the file\n- **No argument** (`mcpc connect`) — auto-discover MCP config files in the current directory and\n  your home dir (`.mcp.json`, `mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `~/.claude.json`,\n  Claude Desktop, Windsurf, Kiro, …) and connect everything found (run `mcpc connect --help` for the\n  full list). Set `APIFY_API_TOKEN` to also connect `mcp.apify.com` as `@apify`.\n\n```bash\nmcpc connect                      # discover standard config files and connect all servers\nmcpc connect ~/.vscode/mcp.json   # connect every server in one file\n```\n\nBulk connects auto-generate session names (so they don't take an `@session`) and **skip local\nstdio servers by default** — pass `--stdio` to include them. Each discovered config file is listed\nwith its servers and their status (`● live`, `● connecting`); files that can't be used are shown as\n`(0 servers)` or `(invalid)` with the reason, rather than silently ignored. Without `--json` the\ncommand returns right away without waiting for every connection to finish (still-connecting sessions\nshow `● connecting`); `--json` waits and reports each server's details.\n\n### MCP commands\n\nAll MCP commands go through a named session created with `connect`:\n\n```bash\n# Connect to a remote server and create a session\nmcpc connect mcp.apify.com @apify\nmcpc @apify tools-list\nmcpc @apify tools-call search-apify-docs query:=\"What are Actors?\"\n\n# Connect to a local server via config file entry\nmcpc connect ~/.vscode/mcp.json:filesystem @fs\nmcpc @fs tools-list\nmcpc @fs tools-call list_directory path:=/\n```\n\nSee [MCP feature support](#mcp-feature-support) for details about all supported MCP features and commands.\n\n#### Command arguments\n\nThe `tools-call` and `prompts-get` commands accept arguments as positional parameters after the tool/prompt name:\n\n```bash\n# Key:=value pairs (auto-parsed: tries JSON, falls back to string)\nmcpc @session tools-call \u003ctool-name\u003e greeting:=\"hello world\" count:=10 enabled:=true\nmcpc @session tools-call \u003ctool-name\u003e config:='{\"key\":\"value\"}' items:='[1,2,3]'\n\n# Force string type with JSON quotes\nmcpc @session tools-call \u003ctool-name\u003e id:='\"123\"' flag:='\"true\"'\n\n# Inline JSON object (if first arg starts with { or [)\nmcpc @session tools-call \u003ctool-name\u003e '{\"greeting\":\"hello world\",\"count\":10}'\n\n# Read from stdin (automatic when no positional args and input is piped)\necho '{\"greeting\":\"hello\",\"count\":10}' | mcpc @session tools-call \u003ctool-name\u003e\ncat args.json | mcpc @session tools-call \u003ctool-name\u003e\n```\n\n**Auto-parsing rules** for `key:=value`: valid JSON keeps its type\n(`count:=10` → number, `enabled:=true` → boolean, `cfg:='{\"k\":\"v\"}'` → object); anything\nelse is a string (`greeting:=hello` → `\"hello\"`). Force a string literal with JSON quotes:\n`id:='\"123\"'`. Inline JSON is detected when the first arg starts with `{` or `[`. Stdin is\nread when no positional args are given and input is piped.\n\n**Pitfalls:** no spaces around `:=` (use `query:=hello world`, not `query := ...`); quote\nthe whole argument when it contains shell expansions (`\"query:=${VAR}\"`). For complex\ninputs, prefer piping JSON via stdin.\n\n### Interactive shell\n\n`mcpc` provides an interactive shell for discovery and testing of MCP servers.\n\n```bash\nmcpc @apify shell\n```\n\nShell commands: `help`, `exit`/`quit`/Ctrl+D, Ctrl+C to cancel.\nArrow keys navigate history (saved to `~/.mcpc/history`).\n\n### Grep (search across sessions)\n\n`mcpc grep` searches tools, resources, and prompts across all active sessions or within a single session:\n\n```bash\n# Search tools and server instructions in all active sessions\nmcpc grep \"search\"\n\n# Search within a single session\nmcpc @apify grep \"actor\"\n\n# Search resources and prompts instead of the default tools and instructions\nmcpc grep \"config\" --resources --prompts\n\n# Regex search\nmcpc grep \"search|find\" -E\n\n# Case-sensitive search (default is case-insensitive)\nmcpc grep \"Search\" --case-sensitive\n\n# Limit results\nmcpc grep \"e\" -m 5\n\n# JSON output for scripting\nmcpc grep \"actor\" --json\n```\n\nBy default, `grep` searches only tools. Use `--resources` or `--prompts` to search those types\n(combine with `--tools` to include tools too). Sessions that are crashed or unavailable are shown\nwith their status rather than silently skipped.\n\nThe `grep` command is useful for **dynamic tool discovery**,\nalso called [Tool search tool](https://www.anthropic.com/engineering/advanced-tool-use) by Anthropic\nor [Dynamic context discovery](https://cursor.com/blog/dynamic-context-discovery) by Cursor.\nRather than loading all tools into AI agent's context, the agent can use `grep` to discover the right tool\nfor the job, and only load the relevant tools into the context when needed to reduce token usage and improve accuracy.\n\n\u003c!-- TODO: explain this more, show diagram --\u003e\n\n### JSON mode\n\nBy default, `mcpc` prints output in Markdown-ish text format with colors, making it easy to read by both humans and AIs.\n\nWith `--json` option, `mcpc` always emits only a single JSON object (or array), to enable [scripting](#scripting).\n**For all MCP commands, the returned objects are always consistent with the\n[MCP specification](https://modelcontextprotocol.io/specification/latest).**\nOn success, the JSON object is printed to stdout, on error to stderr.\n\nNote that `--json` is not available for `shell`, `login`, and `mcpc --help` commands.\n\n## Sessions\n\nMCP is a [stateful protocol](https://modelcontextprotocol.io/specification/latest/basic/lifecycle):\nclients and servers negotiate protocol version and capabilities, and then communicate within a persistent session.\nTo support these sessions, `mcpc` can start a lightweight **bridge process** that maintains the connection and state.\nThis is more efficient than forcing every MCP command to reconnect and reinitialize,\nand enables long-term stateful sessions.\n\nThe sessions are given names prefixed with `@` (e.g. `@apify`),\nwhich then serve as unique reference in commands.\n\n```bash\n# Create a persistent session\nmcpc connect mcp.apify.com @apify\n\n# List all sessions and OAuth profiles\nmcpc\n\n# Run MCP commands in the session\nmcpc @apify tools-list\nmcpc @apify shell\n\n# Restart the session (kills and restarts the bridge process)\nmcpc @apify restart    # or: mcpc restart @apify\n\n# Close the session, terminates bridge process\nmcpc @apify close      # or: mcpc close @apify\n\n# ...now session name \"@apify\" is forgotten and available for future use\n```\n\n### Session lifecycle\n\nSession metadata is saved in `~/.mcpc/sessions.json`, [authentication tokens](#authentication)\nin the OS keychain. The bridge process keeps the session alive with periodic [pings](#ping)\nand auto-reconnects on network failures or its own crashes (10s cooldown on failed retries).\n\n**Session states:**\n\n| State            | Meaning                                                                                         |\n| ---------------- | ----------------------------------------------------------------------------------------------- |\n| 🟢`live`         | Bridge process running and server responding                                                    |\n| 🟡`connecting`   | Initial bridge startup in progress (`mcpc connect`)                                             |\n| 🟡`reconnecting` | Bridge crashed or lost auth; auto-reconnecting in the background                                |\n| 🟡`disconnected` | Bridge process running but server unreachable; auto-recovers when server responds               |\n| 🟡`crashed`      | Bridge process crashed or was killed; auto-reconnects in the background                         |\n| 🔴`unauthorized` | Server rejected authentication (401/403) or token refresh failed; re-run `login` then `restart` |\n| 🔴`expired`      | Server rejected session ID (404); requires `restart`                                            |\n\n`mcpc` never removes sessions automatically — failed ones stay flagged with a recovery hint\nin the error message. Use `mcpc @apify restart` to kill the bridge and open a fresh\n`MCP-Session-Id`, or `mcpc @apify close` to remove the session entirely.\nYou can also remove dead sessions by running `mcpc clean`,\nand all sessions by running `mcpc clean all` (see [Cleanup](#cleanup)).\n\n## Authentication\n\n`mcpc` supports all standard [MCP authorization methods](https://modelcontextprotocol.io/specification/latest/basic/authorization).\n\n### Anonymous access\n\nFor local servers (stdio) or remote servers (Streamable HTTP) which do not require credentials,\n`mcpc` can be used without authentication:\n\n```bash\nmcpc connect mcp.apify.com @test\nmcpc @test tools-list\n```\n\n### Bearer token authentication\n\nFor remote servers that require a Bearer token (but not OAuth), use the `--header` flag to pass the token.\nAll headers are stored securely in the OS keychain for the session, but they are **not** saved as reusable\n[OAuth profiles](#oauth-profiles). This means `--header` needs to be provided whenever\nrunning a one-shot command or connecting new session.\n\n```bash\n# Create session with Bearer token (token saved to keychain for this session only)\nmcpc connect https://mcp.apify.com @apify --header \"Authorization: Bearer ${APIFY_TOKEN}\"\n\n# Use the session (Bearer token is loaded from keychain automatically)\nmcpc @apify tools-list\n```\n\n### OAuth profiles\n\nFor OAuth-enabled remote MCP servers, `mcpc` implements the full OAuth 2.1 flow with PKCE as\nmandated by the [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization):\n`WWW-Authenticate` 401 challenges, Protected Resource Metadata and authorization server metadata\ndiscovery, all three [client registration approaches](#client-registration-approaches),\n[resource indicators (RFC 8707)](https://www.rfc-editor.org/rfc/rfc8707), and automatic\nrefresh-token rotation.\n\nThe OAuth authentication **always** needs to be initiated by the user calling the `login` command,\nwhich opens a web browser with login screen. `mcpc` never opens the web browser on its own.\n\nThe OAuth credentials to specific servers are securely stored as **authentication profiles** - reusable\ncredentials that allow you to:\n\n- Authenticate once, use credentials across multiple commands or sessions\n- Use different accounts (profiles) with the same server\n- Manage credentials independently from sessions\n\nKey concepts:\n\n- **Authentication profile**: Named set of OAuth credentials for a specific server (stored in `~/.mcpc/profiles.json` + OS keychain)\n- **Session**: Active connection to a server that may reference an authentication profile (stored in `~/.mcpc/sessions.json`)\n- **Default profile**: When `--profile` is not specified, `mcpc` uses the authentication profile named `default`\n\n**Example:**\n\n```bash\n# Login to server and save 'default' authentication profile for future use\nmcpc login mcp.apify.com\n\n# Use named authentication profile instead of 'default'\nmcpc login mcp.apify.com --profile work\n\n# Create two sessions using the two different credentials\nmcpc connect mcp.apify.com @apify-personal\nmcpc connect mcp.apify.com @apify-work --profile work\n\n# Both sessions now work independently\nmcpc @apify-personal tools-list  # Uses personal account\nmcpc @apify-work tools-list      # Uses work account\n\n# Re-authenticate existing profile (e.g., to refresh or change scopes)\nmcpc login mcp.apify.com --profile work\n\n# Delete \"default\" and \"work\" authentication profiles\nmcpc logout mcp.apify.com\nmcpc logout mcp.apify.com --profile work\n```\n\n### Client registration approaches\n\nWhen logging in, `mcpc` supports all three OAuth client registration approaches defined in the\n[MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-registration-approaches),\npicking the one the authorization server advertises in its OAuth metadata:\n\n| **Approach**                            | **`mcpc login` flags**                              |\n| :-------------------------------------- | :-------------------------------------------------- |\n| **Pre-registration**                    | `--client-id` (and optional `--client-secret`)      |\n| **Client ID Metadata Documents (CIMD)** | default (or `--client-metadata-url \u003curl\u003e`)          |\n| **Dynamic Client Registration (DCR)**   | fallback (or force with `--no-client-metadata-url`) |\n\n`mcpc` ships with a hosted [Client ID Metadata Document](https://apify.github.io/mcpc/client-metadata.json)\nso every installation presents the same client identity to CIMD-capable authorization servers.\nWhen the authorization server advertises `client_id_metadata_document_supported: true`, the CIMD\nURL is used as the `client_id`; otherwise mcpc falls back to Dynamic Client Registration.\n\n```bash\n# Default: mcpc's hosted CIMD is used automatically (no flags needed).\nmcpc login mcp.apify.com\n\n# Pre-registered OAuth client (public or confidential) — skips CIMD.\nmcpc login mcp.example.com --client-id \u003cid\u003e [--client-secret \u003csecret\u003e]\n\n# Custom CIMD: override the default with your own hosted document.\nmcpc login mcp.example.com --client-metadata-url https://example.com/my-client.json\n\n# Disable CIMD: force Dynamic Client Registration even if the server supports CIMD.\nmcpc login mcp.example.com --no-client-metadata-url\n```\n\nSee the [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-registration-approaches)\nfor details on each approach and the format of Client ID Metadata Documents.\n\n### Authentication precedence\n\nWhen connecting, `mcpc` picks one auth source based on the flags you pass — explicit flags\nalways win over stored profiles, and credentials are never silently downgraded. If a profile\nis missing, expired, or invalid, `mcpc` fails with an error that includes the right\n`mcpc login` command to recover.\n\n| Flag                            | Behavior                                                                                                                                        |\n| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |\n| `--header \"Authorization: ...\"` | Use explicit header; skip OAuth auto-detection. Cannot combine with `--profile`.                                                                |\n| `--profile \u003cname\u003e`              | Require the named profile to exist.                                                                                                             |\n| `--no-profile`                  | Connect anonymously even if a `default` profile exists.                                                                                         |\n| `--x402 [scheme]`               | Skip OAuth auto-detection; use x402 payments instead. Optional scheme: `auto` (default), `upto`, `exact`. Combine with `--profile` to use both. |\n| _(none)_                        | Use `default` profile if it exists; otherwise connect anonymously.                                                                              |\n\nConfig file headers (from `--config`) apply to servers loaded from that file.\n\n```bash\n# Default: 'default' profile if it exists, else anonymous\nmcpc connect mcp.apify.com @apify-personal\n\n# Specific profile (fails if missing)\nmcpc connect mcp.apify.com @apify-work --profile work\n\n# Explicit bearer token (no profile)\nmcpc connect mcp.apify.com @apify --header \"Authorization: Bearer ${APIFY_TOKEN}\"\n\n# Skip default profile, connect anonymously\nmcpc connect mcp.apify.com @apify-anon --no-profile\n\n# x402 micropayments instead of OAuth\nmcpc connect mcp.apify.com @apify --x402\n```\n\n## MCP proxy\n\nFor stronger isolation, `mcpc` can expose an MCP session under a new local proxy MCP server using the `--proxy` option.\nThe proxy forwards all MCP requests to the upstream server but **never exposes the original authentication tokens** to the client.\nThis is useful when you want to give someone or something MCP access without revealing your credentials.\nSee also [AI sandboxes](#ai-sandboxes).\n\n```bash\n# Human authenticates to a remote server\nmcpc login mcp.apify.com\n\n# Create authenticated session with proxy server on localhost:8080\nmcpc connect mcp.apify.com @open-relay --proxy 8080\n\n# Now any MCP client can connect to proxy like to a regular MCP server\n# The client has NO access to the original OAuth tokens or HTTP headers\n# Note: localhost/127.0.0.1 URLs default to http:// (no scheme needed)\nmcpc connect localhost:8080 @sandboxed\nmcpc @sandboxed tools-call search-actors keywords:=\"web scraper\"\n\n# Optionally protect proxy with bearer token for better security (stored in OS keychain)\nmcpc connect mcp.apify.com @secure-relay --proxy 8081 --proxy-bearer-token secret123\n# To use the proxy, caller needs to pass the bearer token in HTTP header\nmcpc connect localhost:8081 @sandboxed2 --header \"Authorization: Bearer secret123\"\n```\n\n**Proxy options for `connect` command:**\n\n| Option                         | Description                                                                    |\n| ------------------------------ | ------------------------------------------------------------------------------ |\n| `--proxy [host:]port`          | Start proxy MCP server. Default host: `127.0.0.1` (localhost only)             |\n| `--proxy-bearer-token \u003ctoken\u003e` | Requires `Authorization: Bearer \u003ctoken\u003e` header to access the proxy MCP server |\n\n**Security model:**\n\n- **Localhost by default**: `--proxy 8080` binds to `127.0.0.1` only, preventing network access\n- **Tokens hidden**: Original OAuth tokens and/or HTTP headers are never exposed to proxy clients\n- **Optional auth**: Use `--proxy-bearer-token` to add another layer of security\n- **Explicit opt-in**: Proxy only starts when `--proxy` flag is provided\n\n**Binding to network interfaces:**\n\n```bash\n# Localhost only (default, most secure)\nmcpc connect mcp.apify.com @relay --proxy 8080\n\n# Bind to all interfaces (allows network access - use with caution!)\nmcpc connect mcp.apify.com @relay --proxy 0.0.0.0:8080\n\n# Bind to specific interface\nmcpc connect mcp.apify.com @relay --proxy 192.168.1.100:8080\n```\n\nWhen listing sessions, proxy info is displayed prominently:\n\n```bash\nmcpc\n# @relay → https://mcp.apify.com (HTTP, OAuth: default) [proxy: 127.0.0.1:8080]\n```\n\n## AI agents\n\n`mcpc` is designed for CLI-enabled AI agents like Claude Code or Codex CLI, supporting both\ninteractive **tool calling** and **[code mode](https://www.anthropic.com/engineering/code-execution-with-mcp)**.\n\n**Tool calling mode** - Agents call `mcpc` commands to dynamically explore and interact with MCP servers,\nusing the default text output. This is similar to how MCP connectors in ChatGPT or Claude work,\nbut CLI gives you more flexibility and longer operation timeouts.\n\n```bash\n# Discover available tools\nmcpc @server tools-list\n\n# Get tool schema\nmcpc @server tools-get search\n\n# Call a tool\nmcpc @server tools-call search query:=\"hello world\"\n```\n\n**Code mode** - Once agents understand the server's capabilities, they can write shell\nscripts that compose multiple `mcpc` commands with `--json` output — see\n[Scripting](#scripting) below. This can be\n[more accurate](https://www.anthropic.com/engineering/code-execution-with-mcp) and use\nfewer tokens than tool calling for complex workflows. Pair with\n[schema validation](#schema-validation) to catch breaking changes early.\n\n### Scripting\n\nUse `--json` for machine-readable output (stdout on success, stderr on error).\nJSON output of all MCP commands follows the [MCP specification](https://modelcontextprotocol.io/specification/latest) strictly.\n\n```bash\n# Chain tools across sessions\nmcpc --json @apify tools-call search-actors keywords:=\"scraper\" \\\n  | jq '.content[0].text | fromjson | .items[0].id' \\\n  | xargs -I {} mcpc @apify tools-call get-actor actorId:=\"{}\"\n\n# Batch operations\nfor tool in $(mcpc --json @server tools-list | jq -r '.[].name'); do\n  mcpc --json @server tools-get \"$tool\" \u003e \"schemas/$tool.json\"\ndone\n```\n\nFor a complete example script, see [`docs/examples/company-lookup.sh`](./docs/examples/company-lookup.sh).\n\n### Schema validation\n\nThe `tools-get` and `tools-call` commands support `--schema` to validate a tool's schema against an expected snapshot. This helps detect breaking changes early in scripts and CI:\n\n```bash\n# Save expected schema\nmcpc --json @apify tools-get search-actors \u003e expected.json\n\n# Validate without calling (read-only check)\nmcpc @apify tools-get search-actors --schema expected.json\n\n# Validate before calling (fails if schema changed incompatibly)\nmcpc @apify tools-call search-actors --schema expected.json keywords:=\"test\"\n```\n\nAvailable schema validation modes (`--schema-mode`):\n\n- `compatible` (default)\n  - Input schema: new optional fields OK, required fields must have the same type.\n  - Output schema: new fields OK, removed required fields cause error.\n- `strict` - Both input and output schemas must match exactly, including all fields, types, and descriptions\n- `ignore` - Skip validation completely (YOLO)\n\n### AI sandboxes\n\nTo ensure AI coding agents don't perform destructive actions or leak credentials,\nit's always a good idea to run them in a code sandbox with limited access to your resources.\n\nThe [proxy MCP server](#mcp-proxy) feature provides a security boundary for AI agents:\n\n1. **Human creates authentication profile**: `mcpc login mcp.apify.com --profile ai-access`\n2. **Human creates session**: `mcpc connect mcp.apify.com @ai-sandbox --profile ai-access --proxy 8080`\n3. **AI runs inside a sandbox**: If sandbox has access limited to `localhost:8080`,\n   it can only interact with the MCP server through the `@ai-sandbox` session,\n   without access to the original OAuth credentials, HTTP headers, or `mcpc` configuration.\n\nThis ensures AI agents operate only with pre-authorized credentials, preventing unauthorized access to MCP servers.\nThe human controls which servers the AI can access and with what permissions (OAuth scopes).\n\n**IMPORTANT:** Beware that MCP proxy will not make an insecure MCP server secure.\nLocal stdio servers will still have access to your local system, and HTTP servers to provided auth credentials,\nand both can easily perform destructive actions or leak credentials on their own, or let MCP clients do such actions.\n**Always use only trusted local and remote MCP servers and limit their access to the necessary minimum.**\n\n### Agent skills\n\nTo help Claude Code use `mcpc`, you can install this [Claude skill](./docs/claude-skill/README.md):\n\n\u003c!-- TODO: Add also AGENTS.md, GitHub skills etc. --\u003e\n\n`mcpc` also acts as a **client for skills served by MCP servers** (experimental, SEP-2640) — see\n[Skills](#skills) for the `skills-list` / `skills-get` commands.\n\n## Agentic payments (x402)\n\n\u003e ⚠️ **Experimental.** This feature is under active development and may change.\n\n`mcpc` has experimental support for the [x402 payment protocol](https://www.x402.org/),\nwhich enables AI agents to autonomously pay for MCP tool calls using cryptocurrency.\nWhen an MCP server charges for a tool call (HTTP 402), `mcpc` automatically signs a USDC payment\non the [Base](https://base.org/) blockchain and retries the request — no human intervention needed.\n\nThis is entirely **opt-in**: existing functionality is unaffected unless you explicitly pass the `--x402` flag.\n\n### How it works\n\nTwo schemes are supported, both signed by your local wallet:\n\n- **`exact`** — EIP-3009 `TransferWithAuthorization`. Settles on-chain at call-time.\n- **`upto`** — Permit2 `PermitWitnessTransferFrom`. You sign a max cap; the facilitator settles accumulated usage later. First use auto-grants a one-time `USDC.approve(PERMIT2, MAX_UINT256)` (needs a tiny native ETH float for gas).\n\nFlow: server returns HTTP 402 with a `PAYMENT-REQUIRED` header → `mcpc` picks the best scheme per your preference, signs, and retries with `PAYMENT-SIGNATURE` → server verifies and fulfills. Tools that advertise pricing in `_meta.x402` are signed proactively, skipping the 402 round-trip.\n\n### Wallet setup\n\n`mcpc` stores a single wallet in `~/.mcpc/wallets.json` (file permissions `0600`).\nYou need to create or import a wallet before using x402 payments.\n\n```bash\n# Create a new wallet (generates a random private key)\nmcpc x402 init\n\n# Or import an existing wallet from a private key\nmcpc x402 import \u003cprivate-key\u003e\n\n# Show wallet address and creation date\nmcpc x402 info\n\n# Remove the wallet\nmcpc x402 remove\n```\n\nAfter creating a wallet, **fund it with USDC on Base** (mainnet or Sepolia testnet) to enable payments.\n\n### Manual payment signing\n\nYou can manually sign a payment from a server's `PAYMENT-REQUIRED` header using `x402 sign`.\nThis is useful for pre-signing payments or integrating with tools outside of `mcpc`.\n\n```bash\n# Sign a payment using the base64-encoded PAYMENT-REQUIRED header\nmcpc x402 sign \u003cbase64-payment-required\u003e\n\n# Override the amount (in USD, e.g. 2.50 = $2.50)\nmcpc x402 sign \u003cbase64-payment-required\u003e --amount 2.50\n\n# Override the expiry (in seconds from now)\nmcpc x402 sign \u003cbase64-payment-required\u003e --expiry 7200\n\n# Combine overrides and use JSON output\nmcpc x402 sign \u003cbase64-payment-required\u003e --amount 1.00 --expiry 3600 --json\n```\n\n**Options:**\n\n| Option               | Description                                                             |\n| -------------------- | ----------------------------------------------------------------------- |\n| `--amount \u003cusd\u003e`     | Override the payment amount in USD (e.g. `0.50` for $0.50)              |\n| `--expiry \u003cseconds\u003e` | Override the payment expiry in seconds from now (e.g. `3600`)           |\n| `--scheme \u003cval\u003e`     | Scheme preference: `auto` (default, upto \u003e exact), `upto`, or `exact`   |\n| `--no-approve`       | For `upto`, skip checking and auto-approving on-chain Permit2 allowance |\n\nThe command outputs the signed `PAYMENT-SIGNATURE` header value and an MCP config snippet\nthat can be used directly with other MCP clients.\n\n### Using x402 with MCP servers\n\nPass the `--x402` flag when connecting to a session. It accepts an optional scheme preference\n(`auto`, `upto`, or `exact`); bare `--x402` defaults to `auto`.\n\n```bash\n# Create a session with x402 payment support (auto picks the best advertised scheme)\nmcpc connect mcp.apify.com @apify --x402\n\n# Pin a specific scheme — position doesn't matter, before or after positional args\nmcpc connect --x402 upto mcp.apify.com @apify\nmcpc connect mcp.apify.com @apify --x402 exact\n\n# The session now automatically handles 402 responses using your preference\nmcpc @apify tools-call expensive-tool query:=\"hello\"\n\n# Restart re-uses the saved scheme from sessions.json — no need to repeat the flag\nmcpc @apify restart\n```\n\nWhen `--x402` is active, a fetch middleware wraps all HTTP requests to the MCP server.\nIf any request returns HTTP 402, the middleware transparently signs and retries. Your scheme preference is persisted in `sessions.json` and reused on every reconnect or restart.\n\n### Supported networks\n\n| Network              | Status       |\n| -------------------- | ------------ |\n| Base Mainnet         | ✅ Supported |\n| Base Sepolia testnet | ✅ Supported |\n\n## MCP support\n\n`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).\n\n### Transport\n\n- **stdio**: Direct bidirectional JSON-RPC communication over\n  stdio server from the [config file](#mcp-server-config-file).\n- **Streamable HTTP**: Fully supported.\n- **HTTP with SSE** (deprecated): Legacy mode, not supported.\n\n### Authorization\n\n- [Anonymous access](#anonymous-access)\n- [HTTP header authorization](#bearer-token-authentication)\n- [OAuth 2.1](#oauth-profiles)\n\n### MCP session\n\nThe bridge process manages the full MCP session lifecycle:\n\n- Performs initialization handshake (`initialize` → `initialized`)\n- Negotiates protocol version and capabilities\n- Fetches server-provided `instructions`\n- Maintains persistent HTTP connections with bidirectional streaming, or stdio bidirectional pipe to subprocess\n- Handles `MCP-Protocol-Version` and `MCP-Session-Id` headers automatically\n- Handles multiple concurrent requests\n- Recovers transparently from network disconnections and bridge process crashes\n\n### MCP feature support\n\n| **Feature**                                        | **Status**                         |\n| :------------------------------------------------- | :--------------------------------- |\n| 📖 [**Instructions**](#server-instructions)        | ✅ Supported                       |\n| 🔧 [**Tools**](#tools)                             | ✅ Supported                       |\n| 💬 [**Prompts**](#prompts)                         | ✅ Supported                       |\n| 📦 [**Resources**](#resources)                     | ✅ Supported                       |\n| 🧠 [**Skills**](#skills)                           | 🧪 Experimental (SEP-2640)         |\n| 📝 [**Logging**](#server-logs)                     | ✅ Supported (deprecated by MCP)   |\n| 🔔 [**Notifications**](#list-change-notifications) | ✅ Supported                       |\n| 📄 [**Pagination**](#pagination)                   | ✅ Supported                       |\n| 🏓 [**Ping**](#ping)                               | ✅ Supported                       |\n| ⏳ [**Async tasks**](#async-tasks)                 | ✅ Supported                       |\n| 📁 **Roots**                                       | ❌ Not planned (deprecated by MCP) |\n| ❓ **Elicitation**                                 | 🚧 Planned                         |\n| 🔤 **Completion**                                  | 🚧 Planned                         |\n| 🤖 **Sampling**                                    | ❌ Not applicable (no LLM access)  |\n\n#### Server instructions\n\nMCP servers can provide instructions describing their capabilities and usage. These are displayed when you connect to a server or run the `help` command:\n\n```bash\n# Show server info, capabilities, and instructions (both commands behave the same)\nmcpc @apify\nmcpc @apify help\n\n# JSON mode\nmcpc @apify --json\n```\n\nIn [JSON mode](#json-mode), the resulting object adheres\nto [`InitializeResult`](https://modelcontextprotocol.io/specification/latest/schema#initializeresult) object schema,\nand includes the `_mcpc` field with relevant server/session metadata.\n\n```json\n{\n  \"_mcpc\": {\n    \"sessionName\": \"@apify\",\n    \"profileName\": \"default\",\n    \"server\": {\n      \"url\": \"https://mcp.apify.com\"\n    },\n    \"notifications\": {\n      \"tools\": { \"listChangedAt\": \"2026-01-01T00:42:58.049Z\" }\n    }\n  },\n  \"protocolVersion\": \"2025-06-18\",\n  \"capabilities\": {\n    \"logging\": {},\n    \"prompts\": {},\n    \"resources\": {},\n    \"tools\": { \"listChanged\": true }\n  },\n  \"serverInfo\": {\n    \"name\": \"apify-mcp-server\",\n    \"version\": \"1.0.0\"\n  },\n  \"instructions\": \"Apify is the largest marketplace of tools for web scraping...\"\n}\n```\n\n#### Tools\n\nList, inspect, and call server-provided tools:\n\n```bash\n# List available tools (only names and attributes - useful for dynamic discovery)\nmcpc @apify tools-list\n\n# List available tools (full details including input/output args and description)\nmcpc @apify tools-list --full\n\n# Get tool schema with full details\nmcpc @apify tools-get search-actors\n\n# Call a tool with arguments\nmcpc @apify tools-call search-actors keywords:=\"web scraper\"\n\n# Pass complex JSON arguments\nmcpc @apify tools-call create-task '{\"name\": \"my-task\", \"options\": {\"memory\": 1024}}'\n\n# Load arguments from stdin\ncat data.json | mcpc @apify tools-call bulk-import\n```\n\n#### Prompts\n\nList and retrieve server-defined prompt templates:\n\n```bash\n# List available prompts\nmcpc @apify prompts-list\n\n# Get a prompt with arguments\nmcpc @apify prompts-get analyze-website url:=https://example.com\n```\n\n\u003c!-- TODO: Add example of prompt templates --\u003e\n\n#### Resources\n\nAccess server-provided data sources by URI:\n\n```bash\n# List available resources\nmcpc @apify resources-list\n\n# Read a resource\nmcpc @apify resources-read \"file:///config.json\"\n\n# Subscribe to resource changes (in shell mode)\nmcpc @apify resources-subscribe \"https://api.example.com/data\"\n\n# List resource templates\nmcpc @apify resources-templates-list\n```\n\n#### Skills\n\n\u003e 🧪 **Experimental.** Implements the draft [MCP skills extension (SEP-2640)](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640).\n\u003e The spec is in active iteration; the index shape, recognized entry types, and capability key may change.\n\n[Agent Skills](https://agentskills.io/) are reusable markdown workflow instructions (`SKILL.md` with YAML frontmatter)\nthat AI agents load on demand. `mcpc` lets you discover and pull skills served by any MCP server that exposes\nthem under the `skill://` URI convention — no SDK changes required, since skills are just resources:\n\n```bash\n# List skills exposed by the server (tries skill://index.json, falls back to scanning skill://*/SKILL.md)\nmcpc @apify skills-list\n\n# Read a skill's SKILL.md by bare name, nested path, or full URI\nmcpc @apify skills-get git-workflow\nmcpc @apify skills-get acme/billing/refunds\nmcpc @apify skills-get skill://git-workflow/SKILL.md\n\n# Print just the markdown (no header/fences) — pipe straight to an LLM or a file\nmcpc @apify skills-get git-workflow --raw \u003e /tmp/skill.md\n\n# JSON for scripts: [{ name, description, type, url }]\nmcpc --json @apify skills-list | jq '.[].name'\n```\n\nRecognized index entry types (per SEP-2640): `skill-md` (concrete skill), `mcp-resource-template`\n(parameterized namespace), and `archive` (`.tar.gz`/`.zip` bundle — fetch the URL via `resources-read`).\nEntries with an unrecognized `type` are silently skipped.\n\nSkills appear under capabilities in `mcpc @session` output when a server advertises the extension\nunder either `capabilities.extensions[\"io.modelcontextprotocol/skills\"]` (per spec) or\n`capabilities.experimental[\"io.modelcontextprotocol/skills\"]` (the SDK-preserved escape hatch some\nSDKs still use). Skill content is treated as untrusted input — `mcpc` only reads and prints it; it\nnever executes hooks, scripts, or other frontmatter-declared behavior.\n\n#### List change notifications\n\nWhen connected via a [session](#sessions), `mcpc` automatically handles `list_changed`\nnotifications for tools, resources, and prompts.\nThe bridge process tracks when each notification type was last received.\nIn [shell mode](#interactive-shell), notifications are displayed in real-time.\nThe timestamps are available in JSON output of `mcpc @session --json` under the `_mcpc.notifications`\nfield - see [Server instructions](#server-instructions).\n\n#### Server logs\n\n`mcpc` supports server logging settings (`logging/setLevel`) and log messages (`notifications/message`).\nLog messages are printed to bridge log or stderr, subject to [verbosity level](#verbose-mode).\n\nYou can instruct MCP servers to adjust their [logging level](https://modelcontextprotocol.io/specification/latest/server/utilities/logging)\nusing the `logging-set-level` command:\n\n```bash\n# Set server log level to debug for detailed output\nmcpc @apify logging-set-level debug\n\n# Reduce server logging to only errors\nmcpc @apify logging-set-level error\n```\n\nNote that this sets the logging level on the **server side**.\nThe actual log output depends on the server's implementation.\n\n#### Pagination\n\nMCP servers may return paginated results for list operations\n(`tools-list`, `resources-list`, `prompts-list`, `resources-templates-list`).\n`mcpc` handles this automatically and always fetches all available pages using the `nextCursor`\ntoken - you always get the complete list without manual iteration. Keep it simple.\n\n#### Ping\n\nSessions automatically send periodic pings to keep the [connection alive](#session-lifecycle) and detect failures early.\nSend a ping to check if a server connection is alive:\n\n```bash\n# Ping a session and measure round-trip time\nmcpc @apify ping\nmcpc @apify ping --json\n```\n\n#### Async tasks\n\nMCP servers can execute tools as [async tasks](https://modelcontextprotocol.io/specification/latest/server/utilities/tasks)\nthat run in the background and report progress. `mcpc` supports the full task lifecycle:\n\n```bash\n# Call a tool as a task (waits for completion, shows progress spinner)\nmcpc @apify tools-call long-running-job input:=\"data\" --task\n\n# Start a task and return immediately with the task ID\nmcpc @apify tools-call long-running-job input:=\"data\" --detach\n\n# List active tasks\nmcpc @apify tasks-list\n\n# Check task status\nmcpc @apify tasks-get \u003ctaskId\u003e\n\n# Get the task result (blocks until the task reaches a terminal state)\nmcpc @apify tasks-result \u003ctaskId\u003e\n\n# Cancel a running task\nmcpc @apify tasks-cancel \u003ctaskId\u003e\n```\n\nWith `--task`, the CLI shows a progress spinner with elapsed time, server status messages,\nand progress notifications. Press **ESC** during execution to detach and get the task ID\nfor later retrieval. With `--detach`, the task starts and returns the task ID immediately.\nUse `tasks-result \u003ctaskId\u003e` to fetch the final `CallToolResult` payload once the task\ncompletes.\n\n`tools-list` and `tools-get` show task support annotations per tool:\n`[task:optional]`, `[task:required]`, or `[task:forbidden]`.\n\n## Configuration\n\nYou can configure `mcpc` using a config file, environment variables, or command-line flags.\n\n**Precedence** (highest to lowest):\n\n1. Command-line flags (including `--config` option)\n2. Environment variables\n3. Built-in defaults\n\n### MCP server config file\n\n`mcpc` supports the [\"standard\"](https://gofastmcp.com/integrations/mcp-json-configuration)\nMCP server JSON config file, compatible with Claude Desktop, VS Code, and other MCP clients.\nUse the `file:entry` syntax to reference a server from a config file:\n\n```bash\n# Open a session to a server specified in the Visual Studio Code config\nmcpc connect .vscode/mcp.json:apify @my-apify\nmcpc @my-apify tools-list\n```\n\n`mcpc` also finds these files for you: run `mcpc connect` with no arguments to auto-discover config\nfiles in standard locations and connect every server, or pass a file without an entry to connect all\nof its servers. See [Server formats](#server-formats).\n\n**Example MCP config JSON file:**\n\n```json\n{\n  \"mcpServers\": {\n    \"apify\": {\n      \"url\": \"https://mcp.apify.com\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${APIFY_TOKEN}\"\n      }\n    },\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"],\n      \"env\": {\n        \"DEBUG\": \"mcp:*\"\n      }\n    },\n    \"local-package\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/server.js\"]\n    }\n  }\n}\n```\n\n**Server configuration properties:**\n\nFor **Streamable HTTP servers:**\n\n- `url` (required) - MCP server endpoint URL\n- `headers` (optional) - HTTP headers to include with requests\n- `timeout` (optional) - Request timeout in seconds\n\nFor **stdio servers:**\n\n- `command` (required) - Command to execute (e.g., `node`, `npx`, `python`)\n- `args` (optional) - Array of command arguments\n- `env` (optional) - Environment variables for the process\n\n\u003e **Note:** Stdio servers inherit only a minimal env whitelist from the shell\n\u003e (`PATH`, `HOME`, `SHELL`, …). Other vars — `NODE_EXTRA_CA_CERTS`, `HTTPS_PROXY`,\n\u003e `SSL_CERT_FILE`, etc. — must be forwarded explicitly via the `env` block using\n\u003e `${VAR_NAME}`. Anything the server writes to stderr is captured to\n\u003e `~/.mcpc/logs/bridge-\u003csession\u003e.log` with a `[server stderr]` prefix, and the\n\u003e tail is appended to the error message if `mcpc connect` fails, so you can see\n\u003e why a stdio server failed to start.\n\n**Environment variable substitution:**\n\nConfig files support environment variable substitution using `${VAR_NAME}` syntax:\n\n```json\n{\n  \"mcpServers\": {\n    \"secure-server\": {\n      \"url\": \"https://mcp.apify.com\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${APIFY_TOKEN}\",\n        \"X-User-ID\": \"${USER_ID}\"\n      }\n    }\n  }\n}\n```\n\n### Saved state\n\n`mcpc` saves its state to `~/.mcpc/` directory (unless overridden by `MCPC_HOME_DIR`), in the following files:\n\n- `~/.mcpc/sessions.json` - Active sessions with references to authentication profiles (file-locked for concurrent access)\n- `~/.mcpc/profiles.json` - Authentication profiles (OAuth metadata, scopes, expiry)\n- `~/.mcpc/wallets.json` - x402 wallet data (file permissions `0600`)\n- `~/.mcpc/bridges/` - Unix domain socket files for each bridge process\n- `~/.mcpc/logs/bridge-*.log` - Log files for each bridge process\n- OS keychain - Sensitive credentials (OAuth tokens, bearer tokens, client secrets)\n\n### Environment variables\n\n- `MCPC_HOME_DIR` - Directory for session and authentication profiles data (default is `~/.mcpc`)\n- `MCPC_VERBOSE` - Enable verbose logging (set to `1`, `true`, or `yes`, case-insensitive)\n- `MCPC_JSON` - Enable JSON output (set to `1`, `true`, or `yes`, case-insensitive)\n- `HTTPS_PROXY` / `https_proxy` / `HTTP_PROXY` / `http_proxy` - Proxy URL for outbound connections (e.g. `http://proxy.example.com:8080`); `HTTPS_PROXY` takes precedence\n- `NO_PROXY` / `no_proxy` - Comma-separated list of hostnames/IPs to bypass the proxy (e.g. `localhost,127.0.0.1`)\n\n### Cleanup\n\nYou can clean up the `mcpc` state and data using the `clean` command:\n\n```bash\n# Safe non-destructive cleanup: remove expired sessions, delete old orphaned logs\nmcpc clean\n\n# Clean specific resources\nmcpc clean sessions    # Kill bridges, delete all sessions\nmcpc clean profiles    # Delete all authentication profiles\nmcpc clean logs        # Delete all log files\n\n# Nuclear option: remove everything\nmcpc clean all         # Delete all sessions, profiles, logs, and sockets\n```\n\n## Security\n\n`mcpc` follows [MCP security best practices](https://modelcontextprotocol.io/specification/latest/basic/security_best_practices).\nMCP enables arbitrary tool execution and data access - treat servers like you treat shells:\n\n- Use least-privilege tokens/headers\n- Only use trusted servers!\n- Audit tools before running them\n\n### Credential protection\n\n| What                   | How                                             |\n| ---------------------- | ----------------------------------------------- |\n| **OAuth tokens**       | Stored in OS keychain, never on disk            |\n| **HTTP headers**       | Stored in OS keychain per-session               |\n| **Bridge credentials** | Passed via Unix socket IPC, kept in memory only |\n| **Process arguments**  | No secrets visible in `ps aux`                  |\n| **x402 private key**   | Stored in `wallets.json` (`0600` permissions)   |\n| **Config files**       | Contain only metadata, never tokens             |\n| **File permissions**   | `0600` (user-only) for all config files         |\n\n### Network security\n\n- HTTPS enforced for remote servers (auto-upgraded from HTTP)\n- OAuth callback binds to `127.0.0.1` only\n- Credentials never logged, even in verbose mode\n\n### AI security\n\nSee [AI sandboxes](#ai-sandboxes) for details.\n\n## Errors\n\n`mcpc` provides clear error messages for common issues:\n\n- **Connection failures**: Displays transport-level errors with retry suggestions\n- **Session timeouts**: Automatically attempts to reconnect or prompts for session recreation\n- **Invalid commands**: Shows available commands and correct syntax\n- **Tool execution errors**: Returns server error messages with context\n- **Bridge crashes**: Detects and cleans up orphaned processes, offers restart\n\n### Exit codes\n\n- `0` - Success\n- `1` - Client error (invalid arguments, command not found, etc.)\n- `2` - Server error (tool execution failed, resource not found, etc.)\n- `3` - Network error (connection failed, timeout, etc.)\n- `4` - Authentication error (invalid credentials, forbidden, etc.)\n\n### Verbose mode\n\nTo see what's happening, enable detailed logging with `--verbose`.\n\n```bash\nmcpc --verbose @apify tools-list\n```\n\nThis causes `mcpc` to print detailed debug messages to stderr.\n\n### Logs\n\nView the bridge log for a session with `mcpc @\u003csession\u003e logs` (run with\n`--help` for `--follow`, `-n`, and `--since` options). The underlying file\nlives at `~/.mcpc/logs/bridge-@\u003csession\u003e.log` and is rotated automatically\n(10MB per file, max 5 files). The main `mcpc` process doesn't save log\nfiles, but supports [verbose mode](#verbose-mode).\n\n### Troubleshooting\n\n**\"Cannot connect to bridge\"**\n\n- Bridge may have crashed. Try: `mcpc @\u003csession-name\u003e tools-list` to restart the bridge\n- Check bridge is running: `ps aux | grep -e 'mcpc-bridge' -e '[m]cpc/dist/bridge'`\n- Check socket exists: `ls ~/.mcpc/bridges/`\n\n**\"Session not found\"**\n\n- List existing sessions: `mcpc`\n- Create new session if expired: `mcpc @\u003csession-name\u003e close` and `mcpc connect \u003cserver\u003e @\u003csession-name\u003e`\n\n**\"Authentication failed\"**\n\n- List saved OAuth profiles: `mcpc`\n- Re-authenticate: `mcpc login \u003cserver\u003e [--profile \u003cname\u003e]`\n- For bearer tokens: provide `--header \"Authorization: Bearer ${TOKEN}\"` again\n\n## Development\n\nThe initial version of `mcpc` was developed and [launched by Jan Curn](https://x.com/jancurn/status/2007144080959291756) of [Apify](https://apify.com)\nwith the help of Claude Code, during late nights over Christmas 2025 in North Beach, San Francisco.\n\nSee [CONTRIBUTING](./CONTRIBUTING.md) for development setup, architecture overview, and contribution guidelines.\n\n## Related work\n\n### MCP CLI clients\n\n\u003c!-- Stars, contributors, commits, and activity as of May 2026. --\u003e\n\n| Tool                                                                    | Lang   | Stars | Contrib / Commits | Active | Tools | Resources | Prompts | Tasks | Code mode | Sessions | OAuth | Stdio | HTTP | Tool search | x402 | LLM |\n| ----------------------------------------------------------------------- | ------ | ----: | ----------------: | ------ | ----- | --------- | ------- | ----- | --------- | -------- | ----- | ----- | ---- | ----------- | ---- | --- |\n| **[apify/mcpc](https://github.com/apify/mcpc)**                         | TS     |  ~590 |          8 / ~640 | ✅     | ✅    | ✅        | ✅      | ✅    | ✅        | ✅       | ✅    | ✅    | ✅   | ✅          | ✅   | —   |\n| [steipete/mcporter](https://github.com/steipete/mcporter)               | TS     | ~4.4k |         29 / ~650 | ✅     | ✅    | —         | —       | —     | ✅        | ✅       | ✅    | ✅    | ✅   | —           | —    | —   |\n| [knowsuchagency/mcp2cli](https://github.com/knowsuchagency/mcp2cli)     | Python | ~2.1k |          11 / ~91 | ✅     | ✅    | ✅        | ✅      | —     | ✅        | ✅       | ✅    | ✅    | ✅   | ✅          | —    | —   |\n| [IBM/mcp-cli](https://github.com/IBM/mcp-cli)                           | Python | ~2.0k |         24 / ~790 | ✅     | ✅    | ✅        | ✅      | —     | ✅        | ✅       | ✅    | ✅    | ✅   | —           | —    | ✅  |\n| [f/mcptools](https://github.com/f/mcptools)                             | Go     | ~1.6k |         15 / ~175 | ⚠️     | ✅    | ✅        | ✅      | —     | ✅        | —        | —     | ✅    | ✅   | —           | —    | —   |\n| [philschmid/mcp-cli](https://github.com/philschmid/mcp-cli)             | TS     | ~1.1k |           3 / ~30 | ⚠️     | ✅    | —         | —       | —     | ✅        | ✅       | —     | ✅    | ✅   | ✅          | —    | —   |\n| [adhikasp/mcp-client-cli](https://github.com/adhikasp/mcp-client-cli)   | Python |  ~670 |          6 / ~110 | ⚠️     | ✅    | ✅        | ✅      | —     | —         | —        | —     | ✅    | —    | —           | —    | ✅  |\n| [thellimist/clihub](https://github.com/thellimist/clihub)               | Go     |  ~670 |           1 / ~60 | ✅     | ✅    | —         | —       | —     | —         | —        | ✅    | ✅    | ✅   | ✅          | —    | —   |\n| [wong2/mcp-cli](https://github.com/wong2/mcp-cli)                       | JS     |  ~430 |           4 / ~63 | ⚠️     | ✅    | ✅        | ✅      | —     | —         | —        | ✅    | —     | ✅   | —           | —    | —   |\n| [mcpshim/mcpshim](https://github.com/mcpshim/mcpshim)                   | Go     |   ~58 |           1 / ~13 | ✅     | ✅    | —         | —       | —     | ✅        | ✅       | ✅    | —     | ✅   | ✅          | —    | —   |\n| [evantahler/mcpx](https://github.com/evantahler/mcpx)                   | TS     |   ~32 |          2 / ~100 | ✅     | ✅    | ✅        | ✅      | ✅    | ✅        | —        | ✅    | ✅    | ✅   | ✅          | —    | —   |\n| [EstebanForge/mcp-cli-ent](https://github.com/EstebanForge/mcp-cli-ent) | Go     |   ~15 |           3 / ~46 | ✅     | ✅    | —         | —       | —     | ✅        | ✅       | —     | ✅    | ✅   | ✅          | —    | —   |\n\n**Legend:** ✅ = supported, ⚠️ = stale (no commits in 3+ months), **Contrib / Commits** = contributors / total commits, **Tasks** = [async tasks](https://modelcontextprotocol.io/specification/latest/server/utilities/tasks), **x402** = [x402 payment protocol](https://www.x402.org/) support, **LLM** = requires/uses an LLM.\n\n**Notes:**\n\n- [thellimist/clihub](https://github.com/thellimist/clihub) is a code generator that compiles MCP tools into standalone CLI binaries, rather than a runtime client ([HN discussion](https://news.ycombinator.com/item?id=47157398)).\n- [knowsuchagency/mcp2cli](https://github.com/knowsuchagency/mcp2cli) also supports OpenAPI specs directly and uses a custom TOON encoding for token-efficient tool schemas.\n- [IBM/mcp-cli](https://github.com/IBM/mcp-cli) and [mcp-client-cli](https://github.com/adhikasp/mcp-client-cli) integrate an LLM (Ollama, OpenAI, etc.) for chat-style interaction, while the other tools are pure CLI clients.\n\n### Code mode and dynamic tool discovery\n\nThese resources describe the \"code mode\" pattern (replacing many tool definitions with `search` + `execute`) and dynamic tool discovery:\n\n- [Code mode](https://www.anthropic.com/engineering/code-execution-with-mcp) - Anthropic's blog post on code execution with MCP\n- [Code mode at Cloudflare](https://blog.cloudflare.com/code-mode/) - Cloudflare's implementation of the code mode pattern\n- [Advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use) - Anthropic's engineering post on tool search\n  - [Claude tool search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool) - Claude platform docs\n- [Dynamic context discovery](https://cursor.com/blog/dynamic-context-discovery) - Cursor's approach to dynamic tool discovery\n- [cmcp](https://github.com/assimelha/cmcp) (~27 stars, Rust) - MCP proxy aggregating servers behind `search()` + `execute()`\n- [cloudflare-mcp](https://github.com/mattzcarey/cloudflare-mcp) (~124 stars, TS) - MCP server for the Cloudflare API using code mode\n- [infinite-mcp](https://github.com/day50-dev/infinite-mcp) (Python) - Meta-MCP server that exposes 1000+ pre-indexed MCP servers via semantic search and dynamic tool discovery\n\n### Other\n\n- [mcpGraph](https://github.com/TeamSparkAI/mcpGraph) - MCP server that orchestrates directed graphs of MCP tool calls\n\n## License\n\nApache-2.0 - see [LICENSE](./LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapify%2Fmcpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapify%2Fmcpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapify%2Fmcpc/lists"}