mcporter Roadmap
Inspired in part by Anthropic’s guidance on MCP code execution agents: https://www.anthropic.com/engineering/code-execution-with-mcp
#Goals
- Provide a TypeScript runtime + CLI that exposes all MCP servers defined in
~/Projects/sweetistics/config/mcporter.json. - Preserve current one-shot
pnpm mcporter:callergonomics while enabling reusable connections for Bun/Node agents. - Keep feature parity with the Python helper (env interpolation, stdio wrapping, OAuth caching) and extend test coverage.
#Deliverables
packages/mcporter(standalone npm package) exporting:createRuntime()for shared connections (list/call tools, resolve resources).callOnce()convenience matching today’s single-call flow.- Typed utilities for env/header resolution and stdio command execution.
- CLI entry point (
npx mcporter list|call) built on the same runtime with configurable log levels (--log-levelflag,MCPORTER_LOG_LEVELenv) defaulting towarn. Single-server listings must render as TypeScript-style headers: dimmed/** ... */doc blocks followed byfunction name(...)signatures, inferred return annotations when schemas expose atitle, inline enum/format hints, and an optional-parameter summary (// optional (N): a, b, ...). Optional fields are hidden by default (unless there are ≤2 of them and <4 required parameters) and the CLI should tell users to run--all-parameterswhenever anything is suppressed. The CLI should also infer the verb when users omit it: bare server names runlist <server>(with the same typo-friendly heuristic used bymcporter list), while dotted tokens such aslinear.list_issuesdispatch tocallautomatically. Anonymous HTTP MCP servers (e.g., shadcn) must be auto-detected: if an ad-hoc URL returns MCP-shaped JSON even with a non-200 status, mcporter treats it as authenticated instead of launching the OAuth flow. Likewise,callmust recognise HTTP selectors that inline the tool name (e.g.,https://www.shadcn.io/api/mcp.getComponent(...)), strip the.toolsuffix to derive the base server, parse any function-call arguments, and reuse an existing definition when the base URL matches a configured server. Selectors may omit the protocol entirely—we assume HTTPS when no scheme is present and treat hosts that only differ by a leadingwww.as identical for reuse purposes. See docs/cli-reference.md for day-to-day usage/flag details. - CLI generator (
npx mcporter generate-cli) that emits standalone CLIs (plain TypeScript or bundled JS) with embedded schemas and Commander-based subcommands, targeting Node or Bun. - CLI generator (
npx mcporter generate-cli) that emits standalone CLIs (plain TypeScript or bundled JS) with embedded schemas and Commander-based subcommands, targeting Node or Bun. It must accept server references by name (positional), JSON, HTTP URL (with optional.toolsuffix / missing scheme), or inline stdio commands (split intocommand+argsso invocations like--command "npx -y chrome-devtools-mcp@latest"or positional equivalents work without a config entry) just like the main CLI. - Test harness using the Sweetistics MCP fixtures to validate every configured server definition.
- Documentation: README, usage examples, migration guide for replacing
pnpm mcp:*.
#Architecture Notes
- Load MCP definitions from JSON (support relative paths + HTTPS).
- Reuse
@modelcontextprotocol/sdktransports; invoke stdio servers directly (e.g., callnpxwith env overrides) without an extra wrapper script. - Automatically detect OAuth requirements for ad-hoc HTTP servers by retrying failed handshakes and promoting the definition to
auth: "oauth"when a 401/403 is encountered, then launching the browser flow immediately. - Mirror Python helper behavior:
${VAR},${VAR:-default},$env:VARinterpolation.- Optional OAuth token cache directory handling (defaulting to
~/.mcporter/<server>when none is provided, or XDG paths when configured). - Tool signature + schema fetching for
list. - Provide lazy connection pooling per server to minimize startup cost.
- Expose a lightweight server proxy (
createServerProxy) that maps camelCase method accesses to tool names, fills JSON-schema defaults, validates required arguments, and returns a helper (CallResult) for extracting text/markdown/JSON without re-parsing the content envelope. - Document Cursor-compatible
config/mcporter.jsonstructure; support env-sourced headers and stdio commands while keeping inline overrides available for scripts.
#Schema-Aware Proxy Strategy
- Cache tool schemas on first access, persist them under
~/.mcporter/<server>/schema.jsonor$XDG_CACHE_HOME/mcporter/<server>/schema.jsonfor reuse across processes, and tolerate failures by falling back to rawcallTool. - Allow direct method-style invocations such as
context7.getLibraryDocs("react")by: - Mapping camelCase properties to kebab-case tool names.
- Detecting positional arguments and assigning them to required schema fields in order.
- Handling multi-argument tools (e.g., Firecrawl’s
scrape/map) via positional arrays, plain objects, or mixed option bags. - Merging JSON-schema defaults and validating required fields before dispatch.
- Return
CallResultobjects exposing.raw,.text(),.markdown(),.json()helpers for consistent post-processing. - Keep implementation generic—no hardcoded knowledge of specific servers—so new MCP servers automatically gain the ergonomic API.
- Encourage lightweight composition helpers in examples (e.g., resolving then fetching Context7 docs) while keeping library exports generic.
- Back the proxy with targeted unit tests that cover primitive-only calls, positional tuples + option bags, and error fallbacks when schemas are missing.
#Standalone CLI Generation
generate-clishould accept inline JSON, file paths, inline stdio commands (either via--commandor as the first positional argument), or existing config names and produce a ready-to-run CLI that maps tools to Commander subcommands.- Embed schemas (via
listTools { includeSchema: true }) directly in the generated source so repeat executions avoid additional metadata calls. - Support optional bundling through esbuild, producing Node-friendly
.cjsfiles or Bun-ready.jsbinaries with executable shebangs. - Surface flags for output path, runtime target (
nodeorbun), bundle destination, and per-call timeout (default 30s). - Add integration tests asserting the generated CLI can list tools, execute with positional/flag arguments, and hydrate cache files without additional list calls.
#Configuration
- Single file
config/mcporter.jsonmirrors Cursor/Claude schema:mcpServersmap with entries containingbaseUrlorcommand+args, optionalheaders,env,description,auth,tokenCacheDir, and conveniencebearerToken/bearerTokenEnvfields. - Optional
importsarray (defaulting to ['cursor', 'claude-code', 'claude-desktop', 'codex', 'windsurf', 'vscode']) controls auto-merging of editor configs; entries earlier in the list win conflicts while local definitions can still override. - Provide
configPathoverride for scripts/tests; keep inline overrides in examples for completeness but default to file-based configuration. - Add fixtures validating HTTP vs. stdio normalization, header/env behavior, and editor config imports (Cursor, Claude Code/Desktop, Codex, Windsurf, VS Code) to ensure priority ordering matches defaults.
#Work Phases
- Scaffold Package
- Init pnpm workspace config, tsconfig, lint/test scaffolding, build script.
- Core Runtime
- Port config parsing + env/header logic.
- Implement connection cache, tool invocation, resource helpers.
- CLI Surface
- Implement
list(with optional schema) andcallcommands. - Render tool metadata as pseudo-TypeScript declarations: blue
functionsignatures, grey doc comments using@paramlines, inferred return names, and compact optional summaries that collapse longer lists until users pass--all-parameters. The default view must still surface at least five parameters (even if they’re optional) before summarising the remainder. - Ensure output parity with existing helper.
callhas to parse bothserver.tooltokens and HTTP selectors likehttps://host/path.tool(args); in the HTTP case we need to peel off the.toolsuffix, infer/auto-register the ad-hoc server (respecting--allow-http), and hydrate arguments from parentheses or trailingkey=valuepairs.- Add
generate-clifor standalone/bundled CLIs with embedded schema caching. - Ensure
generate-cli,inspect-cli, andemit-tsshare the same server-resolution logic aslist/call, including HTTP URL matching and scheme-less selectors with.toolsuffixes.
- Testing & Fixtures
- Mock representative MCP servers (stdio + HTTP + OAuth) for integration tests.
- Snapshot output for
listvs.call.
- Docs & Migration
- Write README + migration doc.
- Update Sweetistics docs to point to the new package.
#Open Questions
- How aggressively should we parallelize list calls? Current helper serializes to avoid load.
- Should we bundle a minimal REPL for ad-hoc debugging, or keep CLI focused on list/call?
- Do we expose streaming/async iterator interfaces for tools returning logs?
- What UX do we provide for completing OAuth browser flows (automated callback server vs. copy/paste codes)?