MCPorter
repository·main·Indexed 26 days ago
https://github.com/openclaw/mcporterA TypeScript runtime, CLI, and code-generation toolkit for the Model Context Protocol (MCP). MCPorter enables developers to discover configured MCP servers from tools like Cursor, Claude, and VS Code, and interact with them via a typed TypeScript API or CLI. Key features include zero-config discovery, CLI generation via `generate-cli`, typed client emission with `emit-ts`, a daemon for stateful server lifecycle management, and a bridge mode to expose multiple servers as a single MCP bridge.
What's inside mcporter
- MCPorter is a TypeScript runtime, CLI, and code-generation toolkit for the Model Context Protocol (MCP). It is designed to help developers discover configured MCP servers, call them directly, compose automations in TypeScript, and generate single-purpose CLIs. It supports zero-config discovery by merging local configuration files and imports from tools like Cursor, Claude, and VS Code.
Key Capabilities of MCPorter
mainMCPorter provides several core features for working with MCP servers:
- Zero-config discovery: Automatically merges configuration from
~/.mcporter/mcporter.json[c],$XDG_CONFIG_HOME/mcporter/mcporter.json[c], localconfig/mcporter.json, and imports from Cursor, Claude, Codex, Windsurf, OpenCode, or VS Code. - CLI generation: Use
mcporter generate-clito turn MCP server definitions into ready-to-run CLIs. - Typed tool clients: Use
mcporter emit-tsto generate.d.tsinterfaces or client wrappers for strong TypeScript typing. - Composable API:
createServerProxy()exposes tools as camelCase methods with automatic JSON-schema default application and argument validation. It returns aCallResultwith helpers like.text(),.markdown(),.json(),.images(), and.content(). - Record/replay:
mcporter recordcaptures JSON-RPC traffic as NDJSON, andmcporter replayserves those responses deterministically. - Ad-hoc connections: Connect to any HTTP or stdio endpoint via the CLI without modifying config files. For hosted MCPs requiring browser login, use
mcporter auth <url>to promote the definition to OAuth.
- Zero-config discovery: Automatically merges configuration from
Authenticate OAuth-protected MCP servers
mainFor HTTP MCP servers requiring OAuth, set the
authproperty to"oauth".- Add the server:
npx mcporter config add <name> <url> --auth oauth - Perform login: Run
npx mcporter auth <name>.
Headless Environments: Use
npx mcporter auth <name> --no-browserto get a URL to open manually. Ensure the process remains alive until the browser redirects back to the callback port.Pre-registered Apps: If the provider requires a specific client ID/secret, use the following schema:
oauthClientId: Your client ID.oauthClientSecretEnv: Environment variable name containing the secret.oauthRedirectUrl: The registered callback URL.
npx mcporter config add notion https://mcp.notion.com/mcp --auth oauth npx mcporter auth notion- Add the server:
Handle configuration imports and conflicts
mainMCPorter supports importing configurations from external sources.
- Resolution Order:
mcportersearches the local repository first, then user-level directories. The first valid file found is used. - Conflict Resolution: Imported entries are treated as read-only snapshots. If a local definition exists with the same name, the local definition takes precedence and the imported one is skipped.
- Copying Imports: To turn an imported server into a local one, use:
mcporter config import <kind> --copy --filter <name>mcporter config add <name> --copy-from <kind>:<name>
To disable imports entirely, set
imports: []in your top-level configuration.- Resolution Order:
Authenticate with an OAuth MCP server
mainUse the
authcommand to handle OAuth flows. You can use the--resetflag to clear existing token caches.For headless environments (like SSH), use the
--no-browserflag. When using--no-browser, the output will contain an authorization URL. If using--json --no-browser, the output will be a JSON object containingauthorizationUrlandredirectUrl.Override server or tool selectors
mainIf command inference is insufficient, you can explicitly specify the server or tool using the
--serveror--toolflags.mcporter call --server linear resolve_library_id libraryName=value mcporter call --tool scrape firecrawl url=https://example.comManage MCP server lifecycles with the Daemon
mainCertain stateful servers (like
chrome-devtoolsormobile-mcp) can be kept alive using the MCPorter daemon. This prevents sessions from dropping between calls.Daemon Commands:
mcporter daemon start: Pre-warm the daemon.mcporter daemon status: Check if the daemon is running and see connected servers.mcporter daemon stop: Stop the daemon.mcporter daemon restart: Restart the daemon.
Configuration:
- To make a server use the daemon, set its
"lifecycle": "keep-alive"in the config or use the environment variableMCPORTER_KEEPALIVE=<name>. - To opt-out, use
"lifecycle": "ephemeral"orMCPORTER_DISABLE_KEEPALIVE=<name>.
Exposing servers via bridge: Use
mcporter serve --stdioto expose all daemon-managed keep-alive servers as a single MCP stdio bridge for clients like Claude Code. Use--servers a,bto limit the bridge or--http <port>to serve via Streamable HTTP.mcporter daemon status mcporter daemon stop mcporter daemon start mcporter daemon restart mcporter serve --stdioConfigure ad-hoc MCP servers
mainYou can interact with MCP servers without adding them to your permanent configuration by providing their connection details inline. To make an ad-hoc server reusable, use the
--persistflag to save it to a config file.Examples:
- HTTP Server:
npx mcporter list --http-url https://mcp.linear.app/mcp --name linear - Local STDIO Server:
npx mcporter call --stdio "bun run ./local-server.ts" --name local-tools
To save the definition:
npx mcporter list --http-url <URL> --name <name> --persist config/mcporter.local.json.npx mcporter list --http-url https://mcp.linear.app/mcp --name linear npx mcporter call --stdio "bun run ./local-server.ts" --name local-tools- HTTP Server:
Authenticate MCP servers
mainUsemcporter auth <server|url>to provide credentials. This command supports the same ad-hoc flags used for server registration, allowing you to authenticate immediately after encountering a 401 error without manually editing configuration files.mcporter auth <server|url>Inspect and regenerate a generated CLI artifact
mainEvery generated CLI embeds metadata (generator version, server definition, etc.). You can inspect or recreate these artifacts without needing the original configuration.
- Inspect: Use
mcporter inspect-cli <artifact>to see a human-readable summary of the embedded metadata. Use--jsonfor raw output. This includes a command you can use to regenerate the CLI. - Regenerate: Use
mcporter generate-cli --from <artifact>to replay the stored invocation. You can override specific metadata (like--timeout,--runtime, or--output) during regeneration.
- Inspect: Use
Manage sensitive data and project layers
mainTo maintain security and allow for different environments (Project vs. Machine), follow these patterns:
Project Layer (Version Controlled)
- Keep
config/mcporter.jsonin your repository. - Do not commit secrets. Use environment variable interpolation for sensitive data:
${LINEAR_API_KEY}. - For OAuth, store the public
oauthClientIdin the config and useoauthClientSecretEnvto point to a local environment variable.
Machine Layer (Local Only)
- Store machine-specific configurations in
~/.mcporter/local.jsonor$XDG_CONFIG_HOME/mcporter/local.json. - To add a server to your local config instead of the project config, use:
mcporter config --config ~/.mcporter/local.json add <name>. - OAuth tokens and caches should always remain in
~/.mcporter/or$XDG_DATA_HOME/mcporter/and never be committed to version control.
Headless Deployments
For environments that already have OAuth credentials, seed the vault using:
mcporter vault set <server> --tokens-file <path>ormcporter vault set <server> --stdinwith a JSON payload containingtokensandclientInfo.- Keep
Call tools using explicit flags
mainUse the
callcommand followed by the tool name and long-form CLI flags (--flag value). You can mix flag syntax with key/value pairs.Special Argument Handling:
- File Input: Use
body=@filename.mdor--body @filename.mdto read a UTF-8 string from a file. To pass a literal value starting with@, usebody=@@literal. - JSON Payloads: Use
--args '{"key":"value"}'to ingest JSON directly. - Error Handling: Unknown long flags will cause an error. If you need to pass a positional value that starts with
--, use--before it.
mcporter call linear.create_issue --team ENG --title "Bug report" mcporter call chrome-devtools.take_snapshot output=markdown mcporter call linear.create_issue --team ENG title=value due: tomorrow- File Input: Use