style: apply oxfmt formatting

This commit is contained in:
Peter Steinberger 2026-04-18 19:33:22 +01:00
parent 9bfc604e01
commit 34fe35e46c
No known key found for this signature in database
26 changed files with 276 additions and 155 deletions

View File

@ -6,15 +6,18 @@ Shared guardrails distilled from the various `~/Projects/*/AGENTS.md` files (sta
Usage: In repo copies, the shared content lives inside `<shared>…</shared>` and the tool list inside `<tools>…</tools>`. Keep those tagged blocks identical across repos; anything outside them is repo-local and can be customized freely.
## Codex Global Instructions
- Keep the system-wide Codex guidance at `~/.codex/AGENTS.md` (the Codex home; override via `CODEX_HOME` if needed) so every task inherits these rules by default.
## General Guardrails
### Intake & Scoping
- Open the local agent instructions plus any `docs:list` summaries at the start of every session. Re-run those helpers whenever you suspect the docs may have changed.
- Review any referenced tmux panes, CI logs, or failing command transcripts so you understand the most recent context before writing code.
### Tooling & Command Wrappers
- Use the command wrappers provided by the workspace (`./runner …`, `scripts/committer`, `pnpm mcp:*`, etc.). Skip them only for trivial read-only shell commands if thats explicitly allowed.
- Stick to the package manager and runtime mandated by the repo (pnpm-only, bun-only, swift-only, go-only, etc.). Never swap in alternatives without approval.
- When editing shared guardrail scripts (runners, committer helpers, browser tools, etc.), mirror the same change back into the `agent-scripts` folder so the canonical copy stays current.
@ -23,29 +26,34 @@ Usage: In repo copies, the shared content lives inside `<shared>…</shared>` an
- Keep the projects `AGENTS.md` `<tools></tools>` block in sync with the full tool list from `TOOLS.md` so downstream repos get the latest tool descriptions.
### tmux & Long Tasks
- Run any command that could hang (tests, servers, log streams, browser automation) inside tmux using the repositorys preferred entry point.
- Do not wrap tmux commands in infinite polling loops. Run the job, sleep briefly (≤30s), capture output, and surface status at least once per minute.
- Document which sessions you create and clean them up when they are no longer needed unless the workflow explicitly calls for persistent watchers.
### Build, Test & Verification
- Before handing off work, run the full “green gate” for that repo (lint, type-check, tests, doc scripts, etc.). Follow the same command set humans run—no ad-hoc shortcuts.
- Leave existing watchers running unless the owner tells you to stop them; keep their tmux panes healthy if you started them.
- Treat every bug fix as a chance to add or extend automated tests that prove the behavior.
- When someone asks to “fix CI,” use the GitHub CLI (`gh`) to inspect, rerun, and unblock failing workflows on GitHub until they are green.
### Code Quality & Naming
- Refactor in place. Never create duplicate files with suffixes such as “V2”, “New”, or “Fixed”; update the canonical file and remove obsolete paths entirely.
- Favor strict typing: avoid `any`, untyped dictionaries, or generic type erasure unless absolutely required. Prefer concrete structs/enums and mark public concurrency surfaces appropriately.
- Keep files at a manageable size. When a file grows unwieldy, extract helpers or new modules instead of letting it bloat.
- Match the repos established style (commit conventions, formatting tools, component patterns, etc.) by studying existing code before introducing new patterns.
### Git, Commits & Releases
- Invoke git through the provided wrappers, especially for status, diffs, and commits. Only commit or push when the user asks you to do so.
- To resolve a rebase, `git add`/`git commit` is allowed.
- Follow the documented release or deployment checklists instead of inventing new steps.
- Do not delete or rename unfamiliar files without double-checking with the user or the repo instructions.
### Documentation & Knowledge Capture
- Update existing docs whenever your change affects them, including front-matter metadata if the repos `docs:list` tooling depends on it.
- Whenever doing a large refactor, track work in `docs/refactor/<title><date>.md`, update it as you go, and delete it when the work is finished.
- Only create new documentation when the user or local instructions explicitly request it; otherwise, edit the canonical file in place.
@ -53,16 +61,19 @@ Usage: In repo copies, the shared content lives inside `<shared>…</shared>` an
- Routine test additions dont require changelog entries; reserve changelog lines for user-visible behavior changes.
### Troubleshooting & Observability
- Design workflows so they are observable without constant babysitting: use tmux panes, CI logs, log-tail scripts, MCP/browser helpers, and similar tooling to surface progress.
- If you get stuck, consult external references (web search, official docs, Stack Overflow, etc.) before escalating, and record any insights you find for the next agent.
- Keep any polling or progress loops bounded to protect hang detectors and make it obvious when something stalls.
### Stack-Specific Reminders
- Start background builders or watchers using the automation provided by the repo (daemon scripts, tmux-based dev servers, etc.) instead of running binaries directly.
- Use the official CLI wrappers for browser automation, screenshotting, or MCP interactions rather than crafting new ad-hoc scripts.
- Respect each workspaces testing cadence (e.g., always running the main `check` script after edits, never launching forbidden dev servers, keeping replies concise when requested).
## Swift Projects
- Kick off the workspaces build daemon or helper before running any Swift CLI or app; rely on the provided wrapper to rebuild targets automatically instead of launching stale binaries.
- Validate changes with `swift build` and the relevant filtered test suites, documenting any compiler crashes and rewriting problematic constructs immediately so the suite can keep running.
- Keep concurrency annotations (`Sendable`, actors, structured tasks) accurate and prefer static imports over dynamic runtime lookups that break ahead-of-time compilation.
@ -70,6 +81,7 @@ Usage: In repo copies, the shared content lives inside `<shared>…</shared>` an
- When encountering toolchain instability, capture the repro steps in the designated troubleshooting doc and note any required cache cleans (DerivedData, SwiftPM caches) you perform.
## TypeScript Projects
- Use the package manager declared by the workspace (often `pnpm` or `bun`) and run every command through the same wrapper humans use; do not substitute `npm`/`yarn` or bypass the runner.
- Start each session by running the repos doc-index script (commonly a `docs:list` helper), then keep required watchers (`lint:watch`, `test:watch`, dev servers) running inside tmux unless told otherwise.
- Treat `lint`, `typecheck`, and `test` commands (e.g., `pnpm run check`, `bun run typecheck`) as mandatory gates before handing off work; surface any failures with their exact command output.
@ -101,7 +113,7 @@ Edit guidance: keep the actual tool list inside this `<tools></tools>` block so
- `firecrawl`: MCP-powered site fetcher to Markdown; run `npx mcporter firecrawl`.
- `XcodeBuildMCP`: MCP wrapper around Xcode tooling; run `npx mcporter XcodeBuildMCP`.
- `gh`: GitHub CLI for PRs, CI logs, releases, repo queries; run `gh help`.
</tools>
</tools>
# Repo Notes

View File

@ -3,22 +3,27 @@
## [0.8.2] - Unreleased
### CLI
- Respect schema-declared string parameters when coercing numeric-looking `mcporter call` key=value arguments, so Slack timestamps like `thread_ts` stay strings. (PR #141, thanks @Hamzaa6296)
## [0.8.1] - 2026-03-29
### CLI
- Bun-compiled/Homebrew binaries now embed the package version before boot, so `mcporter --version` reports the real release (for example `0.8.1`) instead of falling back to `0.0.0-dev`.
### Tests
- Added regression coverage for the Bun compile wrapper so future release builds keep the embedded runtime version intact.
### Tooling / Dependencies
- npm publishes now use an explicit package allowlist, so local release tarballs/checksum files do not get bundled into the published package.
## [0.8.0] - 2026-03-29
### CLI
- Preserve OAuth flow vs post-auth transport failures so invalid OAuth/provider errors surface directly, while real legacy 404/405 transport mismatches still fall back to SSE correctly. (PR #97, thanks @mavam)
- Ignore static `Authorization` headers once OAuth is active so imported editor configs cannot override fresh OAuth tokens. (PR #123, thanks @ahonn)
- Keep `mcporter call --output json` parseable by emitting valid JSON even when the command falls back to raw output. (PR #128, thanks @armanddp)
@ -39,31 +44,39 @@
- Added generated `mcporter.schema.json` plus `pnpm generate:schema` for IDE autocomplete/validation, including `$schema` and `oauthScope`/`oauth_scope` coverage. (PR #43, thanks @aryasaatvik)
### Tooling / Dependencies
- Updated dependencies to latest releases (including MCP SDK, Rolldown RC, Zod, Biome, Oxlint, Vitest, Bun types).
- Synced `biome.json` schema URL to Biome `2.4.5`.
## [0.7.3] - 2025-12-29
### CLI
- Fixed generated CLIs to read Commander.js option values via camelCased properties so snake_case tool schemas map correctly. (Thanks @rawwerks, PR #28)
- Coerce generated CLI array arguments based on JSON Schema item types (including integer arrays). (Thanks @rawwerks, PR #27)
- `mcporter generate-cli` supports `--include-tools` / `--exclude-tools` to generate CLIs for a subset of server tools. (Thanks @zackleman, PR #24)
### Tests
- Added regression coverage for typed array parsing in generated CLIs.
- Added regression coverage for snake_case, camelCase, and numeric option names in generated CLIs.
- Increased the Bun bundler integration-test timeout to reduce flakes on slower runners.
- Added regression coverage for snake_case, camelCase, and numeric option names in generated CLIs.
- Increased the Bun bundler integration-test timeout to reduce flakes on slower runners.
### Tooling / Dependencies
- Updated dependency set (SDK, Rolldown, Zod, Biome, Oxlint, Bun types).
- Synced the Biome schema URL to the current CLI version.
## [0.7.1] - 2025-12-08
### Daemon
- Track config file mtimes for every loaded layer (home + project or explicit) in daemon metadata and auto-restart when any layer changes, so newly added keep-alive servers are picked up without manual restarts. Includes regression tests for stale-daemon detection.
## [0.7.0] - 2025-12-06
### CLI
- Centralized OAuth credentials in a shared vault (`~/.mcporter/credentials.json`) while still honoring per-server `tokenCacheDir` when present; legacy per-server caches are migrated automatically.
- `mcporter auth --reset` now clears the vault and legacy caches without crashing on corrupted credential files, making re-auth reliable for servers like Gmail.
- StdIO servers that expose a separate auth subcommand (e.g., Gmail MCP) can now declare `oauthCommand.args`; `mcporter auth <server>` will spawn that helper and wait for browser completion, so Gmail auth now works without running npx manually.
@ -71,68 +84,89 @@
- Added regression coverage to ensure future raw output changes cannot reintroduce truncation.
## [0.6.6] - 2025-11-28
### CLI
- Prevented ENOENT crashes when no config file exists anywhere by only passing an explicit `--config`/`MCPORTER_CONFIG` path to the runtime; implicit defaults now fall back cleanly across list/config/daemon flows.
## [0.6.5] - 2025-11-26
### CLI
- `mcporter call|auth|list help/--help` now print the command-specific usage text instead of attempting to run a server, matching the footers “mcporter <command> --help” hint.
- Added a hidden `list-tools` alias for `mcporter list` to preserve older muscle memory and avoid “Unknown MCP server” errors when copied from legacy docs.
- Ad-hoc HTTP flows now accept `--insecure` as a hidden synonym for `--allow-http`, making plain-HTTP testing flags match common intuition. `--sse` also aliases `--http-url` to keep older examples working.
### Security / Dependencies
- Override transitive `body-parser` to 2.2.1 (CVE-2025-13466) via pnpm overrides.
## [0.6.4] - 2025-11-25
### CLI
- `mcporter list` now uses cached OAuth access tokens (if present) for the all-servers view without opening browser windows, so previously authorized servers no longer show spurious “auth required” in non-interactive listings.
- `pnpm test --filter <pattern>` now works by translating to a Vitest file pattern, avoiding the prior “Unknown option --filter” error.
## [0.6.3] - 2025-11-22
### Runtime & CLI
- Updated to `@modelcontextprotocol/sdk` 1.22.0; inline stdio test server now uses Zod schemas to remain compatible with the SDKs JSON Schema conversion path.
### Runtime
- `listTools` now follows SDK pagination, looping through `nextCursor` so long catalogs return complete tool lists.
### Configuration
- Claude imports now preserve root-fallback parsing for legacy `.claude.json` and `.claude/mcp.json` files while treating `.claude/settings*.json` as container-only configs, preventing metadata fields like `statusLine` from being misdetected as MCP servers.
- Added regression coverage for Claude settings and mcp.json imports to guard the root-fallback behavior.
## [0.6.2] - 2025-11-18
### Runtime
- Propagate `--timeout` / `MCPORTER_CALL_TIMEOUT` into MCP tool calls (SDK `timeout`, `resetTimeoutOnProgress`, `maxTotalTimeout`) so long-running requests are no longer capped by the SDKs 60s default.
### CLI
- `mcporter generate-cli` once again treats single-token `--command` values (e.g., `./scripts/server.ts`) as STDIO transports instead of trying to coerce them into HTTP URLs, restoring the pre-0.6.1 behavior for ad-hoc scripts.
- Global flag parsing moved into `cli-factory` for consistent log-level/oauth-timeout handling across commands.
- `daemon` host/client hardened and covered with new tests; idle eviction and restart paths verified.
### Configuration
- Reintroduced support for `OPENCODE_CONFIG_DIR` so OpenCode imports continue to honor the documented directory override alongside `OPENCODE_CONFIG`.
- Platform-aware defaults for Cursor/Claude/Windsurf/VS Code/OpenCode configs now dedupe paths and include Windows-specific locations.
### Platform resilience (Windows/WSL)
- Added `fs-helpers` that treat chmod/copy failures on NTFS/DrvFs as best-effort so CLI generation keeps working on WSL mounts.
- Documented Windows/WSL workflows: install/test from ext4 copies, remount guidance for /mnt/c, and syncing tips.
### StdIO MCP coverage
- Added stdio e2e tests using in-repo filesystem & memory MCP fixtures to ensure list/call works via execPath.
### Content extraction
- `createCallResult` now reads nested `raw.content`/`raw.structuredContent` so tools that wrap responses render text/markdown/json correctly; new unit tests cover text joining, markdown, and JSON.
## [0.6.1] - 2025-11-17
### CLI
- `mcporter list --verbose` now surfaces every config path that registers the target server (primary first, then duplicates) in both text and JSON output, making it easier to trace where a name is coming from.
- JSON list payloads include a new `sources` array when `--verbose` is set, mirroring the on-screen path list for programmatic consumers.
- Verbose source listings now tag the import kind (cursor/vscode/codex, etc.) and explicitly label the primary entry vs. shadowed duplicates.
### Runtime
## [0.6.0] - 2025-11-16
### Configuration
- Default config resolution now layers the system config (`~/.mcporter/mcporter.json[c]`) before the project config (`config/mcporter.json`), so globally installed MCP servers remain available inside repos while allowing per-project overrides.
- `--config` and `MCPORTER_CONFIG` continue to select a single file without merging for explicit workflows.
- `mcporter config add --scope home|project` lets you choose the write target explicitly (project remains the default; `--persist <path>` still wins when provided).
@ -140,16 +174,19 @@
## [0.5.11] - 2025-11-16
### Code generation & metadata
- Quick start examples in generated CLIs now derive from actual embedded tools (up to three), showing real command names/flags instead of generic placeholders.
## [0.5.10] - 2025-11-16
### Code generation & metadata
- Generated CLIs now present the canonical kebab-cased tool names in help while accepting underscore aliases at runtime, eliminating the “unknown command” errors when copying names directly from server tool lists.
## [0.5.9] - 2025-11-15
### CLI
- `mcporter list` suppresses raw STDIO stderr dumps when enumerating all configured servers, keeping the summary output readable while still surfacing per-server health statuses.
- `mcporter config <subcommand> --help` (and `mcporter config help <subcommand>`) now display detailed usage, flags, and examples for every config subcommand instead of returning a placeholder message. Inline `--help` tokens are intercepted before executing the command, so flows like `mcporter config add --help` no longer throw usage errors.
- `mcporter config doctor` prints the project and system config paths before reporting diagnostics, making it obvious which files were inspected when tracking down configuration issues.
@ -157,17 +194,20 @@
## [0.5.8] - 2025-11-15
### CLI & runtime
- STDIO transports now interpolate `${VAR}`/`$env:VAR` tokens in the configured command and arguments before spawning child processes, so chrome-devtools inherits the live `CHROME_DEVTOOLS_URL` value instead of receiving the literal placeholder.
- Keep-alive detection skips any STDIO server whose command/args reference `CHROME_DEVTOOLS_URL`, ensuring daemon mode relaunches chrome-devtools for each Oracle browser session instead of pinning a stale port.
- Command arguments that escape placeholders as `\${VAR}` (common when using `String.raw` in TypeScript config helpers) now trim the backslash after interpolation so downstream servers receive clean URLs.
### CLI
- Ad-hoc STDIO invocations that start with `npx -y <package>` now infer the npm package name (stripping versions and ignoring arguments after `--`) instead of producing slugs like `npx-y`, so repeated `mcporter list|call` runs automatically reuse a readable server key without passing `--name`.
- Quoted inline commands such as `mcporter list "npx -y xcodebuildmcp"` now auto-detect the ad-hoc STDIO transport, so you can skip `--stdio` entirely when probing MCP packages via `npx`.
## [0.5.7] - 2025-11-14
### CLI
- Added `mcporter daemon restart`, a stop+start convenience that reuses logging flags so agents can bounce the keep-alive daemon with a single command.
- Added `list_tools` as a hidden shortcut for `mcporter list <server>`, so `chrome-devtools.list_tools` (and similar selectors) print the tool catalog instantly without requiring a real MCP tool.
- Warn when colon-style arguments omit a value (e.g., `command:`) and suggest quoting/`--args` JSON so agents dont accidentally send `undefined` to STDIO servers.
@ -175,53 +215,63 @@
## [0.5.6] - 2025-11-11
### CLI & runtime
- Reset cached keep-alive connections whenever STDIO transports hit fatal errors (timeouts, closed pipes, daemon restarts, etc.), so chrome-devtools automatically recovers after you close Chrome instead of requiring `mcporter daemon stop`.
- Daemon-routed calls now log a restart notice and automatically retry once after closing the stale transport, providing self-healing behavior when Chrome or other keep-alive servers crash mid-call.
## [0.5.5] - 2025-11-11
### CLI & runtime
- Added hidden agent shortcuts: `mcporter describe <server>` now aliases `mcporter list`, and calling `<server>.help` automatically falls back to the list output when a server lacks a `help` tool (also wired into the legacy `pnpm mcp call` path) so agents always get a readable summary.
## [0.5.4] - 2025-11-10
### CLI & runtime
- Propagate the CLIs per-call timeout (defaults to 60s or `--timeout`) through the keep-alive daemon, so chrome-devtools and other persistent STDIO servers stop as soon as the caller times out.
- `Runtime.callTool` now honors `timeoutMs` directly, ensuring TanStack MCP clients and the CLI share a single source of truth for cancellation even outside the daemon.
- Ad-hoc STDIO servers launched via `mcporter call "npx …"` (or `--stdio`) inherit the same keep-alive heuristics and canonical names as config-defined entries, so `MCPORTER_DISABLE_KEEPALIVE=chrome-devtools` and similar overrides work without passing `--name`.
### Tests
- Added regression coverage (`tests/daemon-client-timeout.test.ts`, `tests/runtime-call-timeout.test.ts`, and updated keep-alive suites) to guard timeout propagation and canonical keep-alive detection.
## [0.5.3] - 2025-11-10
### CLI & runtime
- Fixed Claude imports so `mcporter list` merges project-scoped servers from `.claude.json` (matching the current workspace) and ignores metadata-only keys like `tipsHistory`/`cachedStatsigGates`, resolving GitHub issues #6 and #7.
- OpenCode imports now read only the documented `mcp` container (no root-level fallback), matching the current OpenCode schema and preventing stray metadata from being misinterpreted as servers.
## [0.5.2] - 2025-11-10
### CLI & runtime
- `mcporter call "<stdio command>" ...` now auto-detects ad-hoc STDIO servers, so you can skip `--stdio/--stdio-arg` entirely and just quote the command you want to run.
- When a server exposes exactly one tool, `mcporter call` infers it automatically (and prints a dim log), letting one-tool servers like Vercel Domains run with only their arguments.
- STDIO transports now inherit your current shell environment by default, so ad-hoc commands see the same variables as your terminal; keep `--env KEY=value` for explicit overrides.
### Fixes
- `mcporter config list` and `mcporter config doctor` no longer crash when the project config is missing or contains malformed JSON; we log a single warning and keep going, matching the behavior of the top-level `mcporter list`.
## [0.5.1] - 2025-11-10
### CLI & runtime
- Added a per-login daemon that auto-starts when keep-alive MCP servers (e.g., Chrome DevTools, Mobile MCP, Playwright) are invoked. The daemon keeps STDIO transports alive across agents, exposes `mcporter daemon <start|status|stop>`, and supports idle shutdown plus manual restarts.
- Keep-alive detection now honors the `lifecycle` config flag/env overrides and also inspects STDIO command signatures, so renaming `chrome-devtools` (or other stateful servers) no longer disables the daemon accidentally.
- Introduced daemon logging controls (`mcporter daemon start --log|--log-file`, `--log-servers`, `MCPORTER_DAEMON_LOG*` env vars, and per-server `logging.daemon.enabled`). `mcporter daemon status` reports the active log path, and a new `tests/daemon.integration.test.ts` suite keeps the end-to-end flow covered.
### Fixes
- `mcporter list` (and every CLI entry point) once again treats missing project configs as empty instead of throwing ENOENT, matching the 0.4.x behavior when you run the CLI outside a repo.
## [0.5.0] - 2025-11-10
### CLI & runtime
- **Daemonized keep-alive servers.** A new per-login daemon automatically spins up whenever keep-alive MCP servers (Chrome DevTools, Mobile MCP, Playwright, etc.) are invoked. It keeps STDIO transports warm across agents, exposes `mcporter daemon <start|status|stop>`, supports idle shutdowns/manual restarts, and respects the `lifecycle` config flag plus STDIO command metadata so renamed servers stay eligible.
- Fixed `createKeepAliveRuntime` so the daemon wrappers `listTools` implementation matches the base `Runtime` signature; `pnpm build` (and any command that shells out to `pnpm build`) succeeds again.
- Cursor imports now cover both workspace and user `.cursor/mcp.json` files plus the platform-specific `Cursor/User/mcp.json` directories, and the VS Code/Windsurf walkers dedupe paths so editor-managed MCP servers are auto-discovered consistently across macOS, Linux, and Windows.
@ -230,63 +280,76 @@
## [0.4.5] - 2025-11-10
### CLI & runtime
- Fixed the npm `bin` entry so it points to `dist/cli.js` without a leading `./`, keeping the executable in the published tarball and restoring `npx mcporter` functionality. Also bumped the embedded runtime version to 0.4.4 so the CLI reports the correct release.
- Added `MCPORTER_CONFIG` plus a home-directory fallback (`~/.mcporter/mcporter.json[c]`) so the CLI automatically finds your system-wide config when a project file is missing.
### Docs
- Consolidated the external MCP import matrix into `docs/import.md`, removing the short-lived `docs/mcp-import.md` duplication, and clarified the release checklist to stop immediately on failing tests or lint warnings.
## [0.4.3] - 2025-11-10
### CLI & runtime
- Added OpenCode imports (project `opencode.json[c]`, `OPENCODE_CONFIG_DIR`, user config, and the `OPENCODE_CONFIG` override) plus JSONC parsing so `mcporter list/config` can auto-discover servers defined in OpenCode.
- Claude Code imports now honor `.claude/settings.local.json` and `.claude/settings.json` ahead of the legacy `mcp.json`, and we skip entries that lack a URL/command (e.g., permissions blocks) so malformed settings no longer break the merge.
### Docs
- Documented the full import matrix (including OpenCode + Claude settings hierarchy) directly in `docs/import.md` and `docs/config.md`.
## [0.4.2] - 2025-11-09
### CLI & runtime
- `mcporter list` (and other commands that load imports) now skip empty or malformed Claude Desktop / Cursor / Codex config files instead of throwing, so a blank `claude_desktop_config.json` no longer blocks the rest of the imports.
- Bundled sample config adds the Mobile Next MCP definition, making it available out of the box when you run `mcporter list` before customizing your own config.
## [0.4.1] - 2025-11-08
### CLI & runtime
- Fixed the fallback when `config/mcporter.json` is missing so `mcporter list` continues to import Cursor/Claude/Codex/etc. configs even when you run the CLI outside a repo that defines its own config, matching the 0.3.x behavior.
- Added regression coverage that exercises the “no config file” path to ensure future changes keep importing user-level MCP servers.
## [0.4.0] - 2025-11-08
### CLI & runtime
- `mcporter config list` now displays only local entries by default, appends a color-aware summary of every imported config (path, counts, sample names), and still lets you pass `--source import`/`--json` for the merged view.
- `mcporter config get`, `remove`, and `logout` now use the same fuzzy matching/suggestion logic as `mcporter list`/`call`, auto-correcting near-miss names and emitting “Did you mean …?” hints when ambiguity remains.
## [0.3.6] - 2025-11-08
### CLI & runtime
- `mcporter list` now prints copy/pasteable examples for ad-hoc servers by repeating the HTTP URL (with quoting) so the commands shown under `Examples:` actually work before you persist the definition.
### Code generation
- Staged the actual dependency directories (`commander`, `mcporter`) directly into the Bun bundler workspace so `npx mcporter generate-cli "npx -y chrome-devtools-mcp" --compile` succeeds even when npm hoists dependencies outside the package (fixes the regression some users still saw with 0.3.5).
## [0.3.5] - 2025-11-08
### Code generation
- Ensure the Bun bundler resolves `commander`/`mcporter` even when `npx mcporter generate-cli … --compile` runs inside an empty temp directory by symlinking mcporters own `node_modules` into the staging workspace before invoking `bun build`. This keeps the “one weird trick” workflow working post-0.3.4 without requiring extra installs.
## [0.3.4] - 2025-11-08
### CLI & runtime
- Added a global `--oauth-timeout <ms>` flag (and the matching `MCPORTER_OAUTH_TIMEOUT_MS` override) so long-running OAuth handshakes can be shortened during debugging; the runtime now logs a clear warning and tears down the flow once the limit is reached, ensuring `mcporter list/call/auth` always exit.
### Docs
- Documented the new OAuth timeout flag/env var across the README and tmux/hang-debug guides so release checklists and manual repro steps call out the faster escape hatch.
## [0.3.3] - 2025-11-07
### Code generation
- When a server definition omits `description`, `mcporter generate-cli` now asks the MCP server for its own `instructions`/`serverInfo.title` during tool discovery and embeds that value, so generated CLIs introduce themselves with the real server description instead of the generic “Standalone CLI…” fallback.
- Embedded tool listings inside generated CLIs now show each commands flag signature (no `usage:` prefix) separated by blank lines, and per-command `--help` output inherits the same colorized usage/option styling as the main `mcporter` binary for readability on rich TTYs.
- Added a `--bundler rolldown|bun` flag to `mcporter generate-cli`, defaulting to Rolldown but allowing Buns bundler (when paired with `--runtime bun`) for teams that want to stay entirely inside the Bun toolchain. The generator now records the chosen bundler in artifact metadata and enforces the Bun-only constraint so reproduction via `--from` stays deterministic.
@ -296,50 +359,58 @@
## [0.3.2] - 2025-11-07
### CLI
- Embedded the CLI version so Homebrew/Bun builds respond to `mcporter --version` even when `package.json` is unavailable.
- Revamped `mcporter --help` to mirror the richer list/call formatting (name + summary rows, grouped sections, quick-start examples, and ANSI colors when TTYs are detected).
- Fixed `mcporter list` so it no longer errors when `config/mcporter.json` is absent—fresh installs now run without creating config files, and a regression test guards the optional-config flow.
- Generated standalone CLIs now print the full help menu (same grouped layout as the main CLI) when invoked without arguments, matching the behavior of `mcporter` itself.
### Code generation
- Generated binaries now default to the current working directory (using the inferred server name) when `--compile` is provided without a path, and automatically append a numeric suffix when the target already exists.
- Standalone CLIs inherit the improved help layout (color-aware title, grouped command summaries, embedded tool listings, and quick-start snippets) so generated artifacts read the same way as the main CLI.
- Swapped the bundler from esbuild to Rolldown for both JS and Bun targets, removing the fragile per-architecture esbuild binaries while keeping aliasing for local dependencies and honoring `--minify` via Rolldowns native minifier.
- Improved `generate-cli` so inline stdio commands (e.g., `"npx chrome-devtools-mcp"`) parse correctly even when invoked from empty directories.
### Code generation
- `readPackageMetadata()` now tolerates missing `package.json` files; when invoked from a directory without a manifest it falls back to mcporters own version string, so `generate-cli` works even when you call it via `npx` in an empty folder.
## [0.3.1] - 2025-11-07
### CLI & runtime
- Short-circuited global `--help` / `--version` handling so these flags no longer fall through command inference and always print immediately, regardless of which command the user typed first.
- Added regression coverage for the new shortcuts and kept the existing `runCli` helper exported so tests (and downstream tools) can exercise argument parsing without forking the entire process.
### Code generation & metadata
- Fixed `mcporter generate-cli --bundle/--compile` in empty directories by aliasing `commander`/`mcporter` imports to the CLIs own installation so esbuild always resolves dependencies. Verified with a new fixture that bundles from temp dirs without `node_modules` (fixes #1).
- Added an end-to-end integration test that runs `node dist/cli.js generate-cli` twice—once for bundling and once for `--compile`—as well as a GitHub Actions step that installs Bun so CI exercises the compiled binary path on every PR.
## [0.3.0] - 2025-11-06
### CLI & runtime
- Added configurable log levels (`--log-level` / `MCPORTER_LOG_LEVEL`) that default to `warn`, promoting noisy transport fallbacks to warnings so critical issues still surface.
- Forced the CLI to exit cleanly after shutdown (opt out with `MCPORTER_NO_FORCE_EXIT`) and patched `StdioClientTransport` so stdio MCP servers no longer leave Node handles hanging; stderr from stdio servers is buffered and replayed via `MCPORTER_STDIO_LOGS=1` or whenever a server exits with a non-zero status.
### Discovery, calling, and ad-hoc workflows
- Rebuilt `mcporter list`: spinner updates stream live, summaries print only after discovery completes, and single-server views now render TypeScript-style doc blocks, inline examples, inferred return hints, and compact `// optional (N): …` summaries. The CLI guarantees at least five parameters before truncating, introduced a single `--all-parameters` switch (replacing the `--required-only` / `--include-optional` pair), and shares its formatter with `mcporter generate-cli` so signatures are consistent everywhere.
- Verb inference and parser upgrades let bare server names dispatch to `list`, dotted invocations jump straight to `call`, colon-delimited flags (`key:value` / `key: value`) sit alongside `key=value`, and the JavaScript-like call syntax now supports unlabeled positional arguments plus typo correction heuristics when tool names are close but not exact.
- Ad-hoc workflows are significantly safer: `--http-url` / `--stdio` definitions (with `--env`, `--cwd`, `--name`, `--persist`) work across `list`, `call`, and `auth`, mcporter reuses existing config entries when a URL matches (preserving OAuth tokens / redirect URIs), and `mcporter auth <url>` piggybacks on the same resolver to persist entries or retry when a server flips modes mid-flight.
- Hardened OAuth detection automatically promotes ad-hoc HTTP servers that return 401/403 to `auth: "oauth"`, broadens the unauthorized heuristic for Supabase/Vercel/GitHub-style responses, and performs a one-time retry whenever a server switches into OAuth mode while you are connecting.
### Code generation & metadata
- Generated CLIs now embed their metadata (generator version, resolved server definition, invocation flags) behind a hidden `__mcporter_inspect` command. `mcporter inspect-cli` / `mcporter generate-cli --from <artifact>` read directly from the artifact, while legacy `.metadata.json` sidecars remain as a fallback for older binaries.
- Shared the TypeScript signature formatter between `mcporter list` and `mcporter generate-cli`, ensuring command summaries, CLI hints, and generator help stay pixel-perfect and are backed by new snapshot/unit tests.
- Introduced `mcporter emit-ts`, a codegen command that emits `.d.ts` tool interfaces or ready-to-run client wrappers (`--mode types|client`, `--include-optional`) using the same doc/comment data that powers the CLI, so agents/tests can consume MCP servers with strong TypeScript types.
- `mcporter generate-cli` now accepts inline stdio commands via `--command "npx -y package@latest"` or by quoting the command as the first positional argument, automatically splits the command/args, infers a friendly name from scripts or package scopes, and documents the chrome-devtools one-liner in the README; additional unit tests cover HTTP, stdio, scoped package, and positional shorthand flows.
### Documentation & references
- Added `docs/tool-calling.md`, `docs/call-syntax.md`, and `docs/call-heuristic.md` to capture every invocation style (flags, function expressions, inferred verbs) plus the typo-correction rules.
- Expanded the ad-hoc/OAuth story across `README.md`, `docs/adhoc.md`, `docs/local.md`, `docs/known-issues.md`, and `docs/supabase-auth-issue.md`, detailing when servers auto-promote to OAuth, how retries behave, and how to persist generated definitions safely.
- Updated the README, CLI reference, and generator docs to cover the new `--all-parameters` flag, list formatter, metadata embedding, the `mcporter emit-ts` workflow, and refreshed branding so the CLI and docs consistently introduce the project as **MCPorter**.
@ -365,22 +436,28 @@
## [0.1.0]
- Initial release.
## [0.6.2] - 2025-11-18
### Platform resilience (Windows/WSL)
- Added `fs-helpers` that treat chmod/copy failures on NTFS/DrvFs as best-effort so CLI generation keeps working on WSL mounts.
- Documented Windows/WSL workflows: install/test from ext4 copies, remount guidance for /mnt/c, and syncing tips.
### CLI/runtime
- Global flag parsing moved into `cli-factory` for consistent log-level/oauth-timeout handling across commands.
- `daemon` host/client hardened and covered with new tests; idle eviction and restart paths verified.
- Imports now include platform-aware defaults for Cursor/Claude/Windsurf/VS Code/OpenCode configs with path dedupe.
### StdIO MCP coverage
- Added stdio e2e tests using in-repo filesystem & memory MCP fixtures to ensure list/call works via execPath.
### Content extraction
- `createCallResult` now reads nested `raw.content`/`raw.structuredContent` so tools that wrap responses render text/markdown/json correctly; new unit tests cover text joining, markdown, and JSON.
### Docs
- New `docs/windows.md` with WSL/NTFS tips; added to docs index.

View File

@ -3,10 +3,7 @@
"chrome-devtools": {
"description": "Chrome DevTools protocol bridge for driving local tabs during debugging or automation.",
"command": "npx",
"args": [
"-y",
"chrome-devtools-mcp@latest"
],
"args": ["-y", "chrome-devtools-mcp@latest"],
"env": {
"npm_config_loglevel": "error"
}
@ -14,10 +11,7 @@
"mobile-mcp": {
"description": "Mobile Next MCP server for automating iOS/Android simulators and devices.",
"command": "npx",
"args": [
"-y",
"@mobilenext/mobile-mcp@latest"
],
"args": ["-y", "@mobilenext/mobile-mcp@latest"],
"env": {
"npm_config_loglevel": "error"
}
@ -47,10 +41,7 @@
"obsidian": {
"description": "Local Obsidian vault access via obsidian-mcp-server.",
"command": "npx",
"args": [
"-y",
"obsidian-mcp-server@latest"
],
"args": ["-y", "obsidian-mcp-server@latest"],
"env": {
"OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}",
"OBSIDIAN_BASE_URL": "${OBSIDIAN_BASE_URL:-https://127.0.0.1:27124}",
@ -84,10 +75,7 @@
"signoz": {
"description": "SigNoz Query MCP server (logs, traces, metrics).",
"command": "npx",
"args": [
"-y",
"signoz-mcp-server@latest"
],
"args": ["-y", "signoz-mcp-server@latest"],
"env": {
"SIGNOZ_URL": "${SIGNOZ_URL:-http://localhost:3301}",
"SIGNOZ_TOKEN": "${SIGNOZ_TOKEN:-}",
@ -102,13 +90,7 @@
"iterm": {
"description": "iTerm2 terminal bridge via local iterm-mcp",
"command": "pnpm",
"args": [
"--dir",
"/Users/steipete/Projects/iterm-mcp",
"exec",
"node",
"build/index.js"
],
"args": ["--dir", "/Users/steipete/Projects/iterm-mcp", "exec", "node", "build/index.js"],
"env": {
"npm_config_loglevel": "error"
}
@ -116,19 +98,11 @@
"XcodeBuildMCP": {
"description": "XcodeBuild MCP server for building, testing, and inspecting Xcode projects and simulators.",
"command": "npx",
"args": [
"-y",
"xcodebuildmcp@latest"
],
"args": ["-y", "xcodebuildmcp@latest"],
"env": {
"npm_config_loglevel": "error"
}
}
},
"imports": [
"cursor",
"claude-code",
"claude-desktop",
"codex"
]
"imports": ["cursor", "claude-code", "claude-desktop", "codex"]
}

View File

@ -16,6 +16,7 @@ Two new flag sets let you describe a server on the command line:
- `mcporter call --stdio "bun run ./server.ts" --name local-tools`
You can also pass a bare URL as the selector (`mcporter list https://mcp.linear.app/mcp`) or embed the URL in a `call` expression (`mcporter call 'https://mcp.example.com/tools.generate({ topic: "release" })'`).
- Add `--json` to `mcporter list …` when you need a machine-readable summary of status counts and per-server failures, use `--output json`/`--output raw` with `mcporter call` to receive structured `{ server, tool, issue }` envelopes whenever a transport error occurs, and run `mcporter auth … --json` to capture the same envelope if OAuth or transport setup fails.
### Example: HTTP ad-hoc workflow

View File

@ -6,19 +6,22 @@ read_when:
# Call Command Auto-Correction
`mcporter call` aims to help when a tool name is *almost* correct without hiding real mistakes.
`mcporter call` aims to help when a tool name is _almost_ correct without hiding real mistakes.
## Confident Matches → Auto-Correct
- We normalise tool names (strip punctuation, lowercase) and compute a Levenshtein distance.
- If the distance is ≤ `max(2, floor(length × 0.3))`, or the names only differ by case/punctuation, we retry automatically.
- A dim informational line explains the correction: `[mcporter] Auto-corrected tool call to linear.list_issues (input: linear.listIssues).`
## Low-Confidence Matches → Suggest
- When the best candidate falls outside the threshold we keep the original failure.
- We still print a hint so the user learns the canonical name: `[mcporter] Did you mean linear.list_issue_statuses?`
- No second call is attempted in this case.
## Edge Cases
- We only inspect the tool catalog if the server explicitly replied with “Tool … not found”. Other MCP errors surface untouched.
- If listing tools itself fails (auth, offline, etc.) we skip both auto-correct and hints.
- Behaviour is covered by `tests/cli-call.test.ts`.

View File

@ -8,11 +8,11 @@ read_when:
`mcporter call` now understands two complementary styles:
| Style | Example | Notes |
|-------|---------|-------|
| Flag-based (compatible) | `mcporter call linear.create_comment --issue-id LNR-123 --body "Hi"` | Use `key=value`, `key:value`, or `key: value` pairs—ideal for shell scripts. |
| Function-call (expressive) | `mcporter call 'linear.create_comment(issueId: "LNR-123", body: "Hi")'` | Mirrors the pseudo-TypeScript signature shown by `mcporter list`; unlabeled values map to schema order. |
| Structured output | `mcporter call 'linear.create_comment(...)' --output json` | Successful calls emit JSON bodies; failures emit `{ server, tool, issue }` envelopes so automation can react to auth/offline/http errors. |
| Style | Example | Notes |
| -------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Flag-based (compatible) | `mcporter call linear.create_comment --issue-id LNR-123 --body "Hi"` | Use `key=value`, `key:value`, or `key: value` pairs—ideal for shell scripts. |
| Function-call (expressive) | `mcporter call 'linear.create_comment(issueId: "LNR-123", body: "Hi")'` | Mirrors the pseudo-TypeScript signature shown by `mcporter list`; unlabeled values map to schema order. |
| Structured output | `mcporter call 'linear.create_comment(...)' --output json` | Successful calls emit JSON bodies; failures emit `{ server, tool, issue }` envelopes so automation can react to auth/offline/http errors. |
Both forms share the same validation pipeline, so required parameters, enums, and formats behave identically.

View File

@ -9,9 +9,11 @@ read_when:
Default behavior: generating `<server>.ts` in the working directory if no output path is provided. Bundling is opt-in via `--bundle` and produces a single JS file with shebang; otherwise we emit TypeScript targeting Node.js. Rolldown handles bundling by default unless the runtime resolves to Bun—in that case Buns native bundler is selected automatically (still requires `--runtime bun` or Bun auto-detection); `--bundler` lets you override either choice.
## Goal
Create an `mcporter generate-cli` command that produces a standalone CLI for a single MCP server. The generated CLI should feel like a Unix tool: subcommands map to MCP tools, arguments translate to schema fields, and output can be piped/redirected easily.
## High-Level Requirements
- **Input**: Identify the target server either by shorthand name or by providing an explicit MCP server definition.
- **Output**: Emit a TypeScript file (ESM) targeting Node.js by default (`<server>.ts` unless `--output` overrides). Bundling to a standalone JS file happens only when `--bundle` is passed.
- **Runtime Selection**: Prefer Bun when it is available (`bun --version` succeeds); otherwise fall back to Node.js. Callers can force either runtime via `--runtime bun|node`.
@ -21,6 +23,7 @@ Create an `mcporter generate-cli` command that produces a standalone CLI for a s
- **Documentation**: Update README (or similar) to show how to generate and use the CLI.
## Steps
1. **Command Scaffolding**
- Add `generate-cli` subcommand to the existing CLI.
- Parse flags: `--server`, `--name`, `--command`, optional `--description`, plus `--output`, `--runtime=node|bun`, `--bundle`, `--bundler=rolldown|bun`, `--minify`, `--compile`, `--include-tools`, `--exclude-tools`, etc. Runtime auto-detects Bun when available, and the bundler inherits that choice unless overridden.
@ -53,6 +56,7 @@ Create an `mcporter generate-cli` command that produces a standalone CLI for a s
- Provide an example generated CLI under `examples/generated/<server>.ts` (if we keep an examples directory).
## Notes
- Generated CLI depends on the latest `commander` for argument parsing.
- Default timeout for tool calls is 30 seconds, overridable via `--timeout`.
- Runtime flag remains (`--runtime bun`) to tailor shebang/usage instructions, but Node.js is the default.
@ -94,8 +98,6 @@ npx mcporter generate-cli --command "npx -y chrome-devtools-mcp@latest"
`npx mcporter generate-cli linear --exclude-tools debug_tool,admin_reset`.
```
## Artifact Metadata & Regeneration
- Every generated artifact embeds its metadata (generator version, resolved server definition, invocation flags). A hidden `__mcporter_inspect` subcommand prints the payload without contacting the MCP server, so binaries remain self-describing even after being copied to another machine.
@ -103,14 +105,14 @@ npx mcporter generate-cli --command "npx -y chrome-devtools-mcp@latest"
- `mcporter generate-cli --from <artifact>` replays the stored invocation against the latest mcporter build. `--server`, `--runtime`, `--timeout`, `--minify/--no-minify`, `--bundle`, `--compile`, `--output`, and `--dry-run` let you override specific pieces of the stored metadata when necessary.
- Because the metadata lives inside the artifact, any template, bundle, or compiled binary can be refreshed after a generator upgrade without juggling sidecar files.
## Status
- ✅ `generate-cli` subcommand implemented with schema-aware proxy generation.
- ✅ Inline JSON / file / shorthand server resolution wired up.
- ✅ Bundling via Rolldown by default (or Bun automatically when the runtime is Bun, with `--bundler` available for overrides) plus optional minification and Bun bytecode compilation.
- ✅ Integration tests cover bundling, minification, compiled binaries, and metadata/regeneration flows against the mock MCP server.
Next steps:
1. Add optional shell completion scaffolding if demand arises.
2. Explore templated TypeScript definitions for generated CLIs to improve editor tooling.

View File

@ -10,6 +10,7 @@ A quick reference for the primary `mcporter` subcommands. Each command inherits
`--config <file>` and `--root <dir>` to override where servers are loaded from.
## `mcporter list [server]`
- Without arguments, lists every configured server (with live discovery + brief
status).
- With a server name, prints TypeScript-style signatures for each tool, doc
@ -22,6 +23,7 @@ A quick reference for the primary `mcporter` subcommands. Each command inherits
- `--timeout <ms>` per-server timeout when enumerating all servers.
## `mcporter call <server.tool>`
- Invokes a tool once and prints the response; supports positional arguments via
pseudo-TS syntax and `--arg` flags.
- Useful flags:
@ -35,6 +37,7 @@ A quick reference for the primary `mcporter` subcommands. Each command inherits
- `--tail-log` stream tail output when the tool returns log handles.
## `mcporter generate-cli`
- Produces a standalone CLI for a single MCP server (optionally bundling or
compiling with Bun).
- Key flags:
@ -58,6 +61,7 @@ A quick reference for the primary `mcporter` subcommands. Each command inherits
treats the URL as an ad-hoc server definition.
## `mcporter emit-ts <server>`
- Emits TypeScript definitions (and optionally a ready-to-use client) describing
a servers tools. This reuses the same formatter as `mcporter list` so doc
comments, signatures, and examples stay in sync.

View File

@ -5,6 +5,7 @@ read_when:
---
# CLI Help Menu Snapshot
```
mcporter config
Usage: mcporter config [options] <command>
@ -35,9 +36,11 @@ See https://github.com/sweetistics/mcporter/blob/main/docs/config.md for config
# Configuration Guide
## Overview
mcporter keeps three configuration buckets in sync: repository-scoped JSON (`config/mcporter.json`), imported editor configs (Cursor, Claude, Codex, Windsurf, OpenCode, VS Code), and ad-hoc definitions supplied on the CLI. This guide explains how those sources merge, how to mutate them with `mcporter config ...`, and the safety rails around OAuth, env interpolation, and persistence.
## Quick Start
1. Create `config/mcporter.json` at the repo root:
```jsonc
{
@ -46,10 +49,10 @@ mcporter keeps three configuration buckets in sync: repository-scoped JSON (`con
"linear": {
"description": "Linear issues",
"baseUrl": "https://mcp.linear.app/mcp",
"headers": { "Authorization": "Bearer ${LINEAR_API_KEY}" }
}
"headers": { "Authorization": "Bearer ${LINEAR_API_KEY}" },
},
},
"imports": ["cursor", "claude-code", "claude-desktop", "codex", "windsurf", "opencode", "vscode"]
"imports": ["cursor", "claude-code", "claude-desktop", "codex", "windsurf", "opencode", "vscode"],
}
```
The `$schema` property enables IDE autocomplete and validation. Use the raw GitHub URL for the latest schema, or copy `mcporter.schema.json` locally.
@ -66,41 +69,47 @@ mcporter now merges home and project config files by default so global servers s
3. Otherwise, mcporter loads both of these layers (when present):
- `~/.mcporter/mcporter.json` or `~/.mcporter/mcporter.jsonc`
- `<root>/config/mcporter.json`
Entries from the project file override entries with the same name from the home file. Each layer still pulls in its own imports before merging.
Entries from the project file override entries with the same name from the home file. Each layer still pulls in its own imports before merging.
All `mcporter config …` mutations still write back to a single file: the explicit path when provided; otherwise the project config path (`<root>/config/mcporter.json`). To edit the home file explicitly, run commands like `mcporter config --config ~/.mcporter/mcporter.json add <name> …` or set `MCPORTER_CONFIG` in your shell profile.
## Discovery & Precedence
mcporter builds a merged view of all known servers before executing any command. The sources load in this order:
| Priority | Source | Notes |
| --- | --- | --- |
| 1 | Explicit `--http-url`, `--stdio`, or bare URL passed to commands | Highest priority, never cached unless `--persist` is supplied. Requires `--allow-http` for plain HTTP URLs. |
| 2 | `config/mcporter.json` (or the file passed via `--config`) | Default path is `<root>/config/mcporter.json`; missing file returns an empty config so commands continue to work. |
| 3 | Imports listed in `"imports"` | When you omit `imports`, mcporter loads `['cursor','claude-code','claude-desktop','codex','windsurf','opencode','vscode']`. When you specify a non-empty array, mcporter appends any omitted defaults after your list so shared presets remain available. |
| Priority | Source | Notes |
| -------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Explicit `--http-url`, `--stdio`, or bare URL passed to commands | Highest priority, never cached unless `--persist` is supplied. Requires `--allow-http` for plain HTTP URLs. |
| 2 | `config/mcporter.json` (or the file passed via `--config`) | Default path is `<root>/config/mcporter.json`; missing file returns an empty config so commands continue to work. |
| 3 | Imports listed in `"imports"` | When you omit `imports`, mcporter loads `['cursor','claude-code','claude-desktop','codex','windsurf','opencode','vscode']`. When you specify a non-empty array, mcporter appends any omitted defaults after your list so shared presets remain available. |
Rules:
- Later sources never override earlier ones. Local config always wins over imports; ad-hoc descriptors override both for the duration of a command.
- Each merged server tracks its origin (local path vs. import path), so `mcporter config get <name>` can show you the path before you edit or remove the local copy with `mcporter config remove <name>`.
- Imports remain read-only until you explicitly copy an entry via `mcporter config import <kind> --copy` or run `mcporter config add --copy-from claude-code:linear` (feature planned alongside the CLI work).
## CLI Workflows
`mcporter config` is the entry point for reading and writing configuration files. Use the existing ad-hoc flags on `mcporter list|call|auth` when you want ephemeral definitions; once youre ready to persist them, switch back to `mcporter config add`.
Use `--scope home|project` with `mcporter config add` to pick the write target explicitly. `project` is always the default (creating `config/mcporter.json` if needed); `home` writes to `~/.mcporter/mcporter.json` even when a project config is present. `--persist <path>` still takes precedence when you need a custom file.
### `mcporter config list [filter]`
- Shows **local** entries by default. Pass `--source import` to list imported editor configs, or `--json` for machine output.
- Always appends a summary of other config files (paths, counts, sample names) so you know where imported entries live.
- `filter` accepts a name, glob fragment, or `source:cursor` selector.
- Adds informational notes when we auto-correct names (same machinery as `mcporter list`).
### `mcporter config get <name>`
- Prints the resolved definition for a single server, including the on-disk path, inherited headers/env, and transport details.
- Near-miss names are auto-corrected with the same heuristics as `mcporter list`/`call`, and youll see suggestions whenever ambiguity remains.
- Supports ad-hoc descriptors so you can inspect a URL before persisting it.
### `mcporter config add <name> [target]`
- Persists a server into the writable config file. Accepts both positional shortcuts (`mcporter config add sentry https://mcp.sentry.dev/mcp`) and flag-driven definitions:
- `--transport http|sse|stdio`
- `--url` or `--command`/`--stdio`
@ -109,9 +118,11 @@ Use `--scope home|project` with `mcporter config add` to pick the write target e
- `--dry-run` shows the JSON diff without writing, while `--persist <path>` overrides the destination file.
### `mcporter config remove <name>`
- Removes the local definition. Names sourced exclusively from imports remain untouched until you copy them locally.
### `mcporter config import <kind>`
- Displays (and optionally copies) entries from editor-specific configs:
- `cursor`: `.cursor/mcp.json` in the repo, falling back to `~/.config/Cursor/User/mcp.json` (or `%APPDATA%/Cursor/User` on Windows).
- `claude-code`: `<root>/.claude/settings.local.json`, `<root>/.claude/settings.json`, `<root>/.claude/mcp.json`, then `~/.claude/settings.json`, `~/.claude/mcp.json`, `~/.claude.json`. `settings.local.json` is meant for untracked per-developer overrides, while `settings.json` is the shared project config.
@ -123,14 +134,17 @@ Use `--scope home|project` with `mcporter config add` to pick the write target e
- `--copy` writes selected entries into your local config; `--filter <glob>` narrows the import list; `--path <file>` lets you point at bespoke locations.
### `mcporter config login <name|url>` / `logout`
- Mirrors `mcporter auth`. `login` completes OAuth (or token provisioning) for either a named server or an ad-hoc URL. When a hosted MCP returns 401/403, mcporter automatically promotes that target to OAuth and re-runs the flow, matching the behavior documented in `docs/adhoc.md`.
- `--browser none` suppresses automatic browser launch (useful for copying the URL into a remote browser).
- `logout` wipes token caches under `~/.mcporter/<name>/` (or the custom `tokenCacheDir`). Pass `--all` to clear everything.
### `mcporter config doctor`
- Early validator that checks for simple issues (e.g., OAuth entries missing cache paths). Future iterations will add fixes for Accept headers, duplicate imports, and more.
## Ad-hoc & Persistence
- `--http-url` and `--stdio` flags live on `mcporter list|call|auth`, keeping `mcporter config` focused on persistent config files.
- Names default to slugified hostnames or executable/script combos. Supply `--name` to improve reuse; mcporter uses that slug for OAuth caches even before persistence.
- `--allow-http` is mandatory for cleartext endpoints so we never downgrade transport silently.
@ -138,6 +152,7 @@ Use `--scope home|project` with `mcporter config add` to pick the write target e
- `--env KEY=VAL` entries merge with existing `env` dictionaries if you later persist the same server; nothing is lost when you alternate between CLI flags and JSON edits.
## JSON Schema for IDE Support
mcporter provides a JSON Schema for config file validation and autocompletion. Add the `$schema` property to your config file:
```jsonc
@ -148,6 +163,7 @@ mcporter provides a JSON Schema for config file validation and autocompletion. A
```
For local development, you can reference the schema from the repo root:
```jsonc
{
"$schema": "../mcporter.schema.json",
@ -158,48 +174,53 @@ For local development, you can reference the schema from the repo root:
The schema is auto-generated from the Zod validation schemas using `pnpm generate:schema`.
## Schema Reference
Top-level structure:
| Key | Type | Description |
| --- | --- | --- |
| `mcpServers` | object | Map of server names → definitions. Required even if empty. |
| `imports` | string[] | Optional list of import kinds. Empty array disables imports entirely; omitting the key falls back to the default list. |
| Key | Type | Description |
| ------------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `mcpServers` | object | Map of server names → definitions. Required even if empty. |
| `imports` | string[] | Optional list of import kinds. Empty array disables imports entirely; omitting the key falls back to the default list. |
Server definition fields (subset of what `RawEntrySchema` accepts):
| Field | Description |
| --- | --- |
| `description` | Free-form summary printed by `mcporter list`/`config list`. |
| `baseUrl` / `url` / `serverUrl` | HTTPS or HTTP endpoint. `http://` requires `--allow-http` in ad-hoc mode but works in config if you explicitly set it. |
| `command` / `args` | Stdio executable definition (string or array). Arrays are preferred because they avoid shell quoting issues. |
| `env` | Key/value pairs applied when launching stdio commands. Supports `${VAR}` interpolation and `${VAR:-fallback}` defaults. Existing process env values win over fallbacks. |
| `headers` | Request headers for HTTP/SSE transports. Values can reference `$env:VAR` or `${VAR}` placeholders, which must be set at runtime or mcporter aborts with a helpful error.
| `auth` | Currently only `oauth` is recognized. Any other string is ignored (treated as undefined) to avoid stale state from other clients. |
| `tokenCacheDir` | Directory for OAuth tokens; still honored, but mcporter now keeps a centralized vault in `~/.mcporter/credentials.json` (legacy per-server caches are auto-migrated). Supports `~` expansion. |
| `clientName` | Optional identifier some servers use for telemetry/audience segmentation. |
| `oauthRedirectUrl` | Override the default localhost callback. Useful when tunneling OAuth through Codespaces or remote dev boxes. |
| `oauthScope` | Optional explicit OAuth scope string. If omitted, mcporter lets the MCP SDK derive scope from server/auth metadata. Use this as an escape hatch for providers that require explicit scopes but dont publish `scopes_supported`. |
| `oauthCommand.args` | For STDIO servers that ship a custom auth subcommand (e.g., Gmail MCP). mcporter will spawn the stdio command with these args when you run `mcporter auth <name>`, so you dont need to call `npx ... auth` manually. |
| Field | Description |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `description` | Free-form summary printed by `mcporter list`/`config list`. |
| `baseUrl` / `url` / `serverUrl` | HTTPS or HTTP endpoint. `http://` requires `--allow-http` in ad-hoc mode but works in config if you explicitly set it. |
| `command` / `args` | Stdio executable definition (string or array). Arrays are preferred because they avoid shell quoting issues. |
| `env` | Key/value pairs applied when launching stdio commands. Supports `${VAR}` interpolation and `${VAR:-fallback}` defaults. Existing process env values win over fallbacks. |
| `headers` | Request headers for HTTP/SSE transports. Values can reference `$env:VAR` or `${VAR}` placeholders, which must be set at runtime or mcporter aborts with a helpful error. |
| `auth` | Currently only `oauth` is recognized. Any other string is ignored (treated as undefined) to avoid stale state from other clients. |
| `tokenCacheDir` | Directory for OAuth tokens; still honored, but mcporter now keeps a centralized vault in `~/.mcporter/credentials.json` (legacy per-server caches are auto-migrated). Supports `~` expansion. |
| `clientName` | Optional identifier some servers use for telemetry/audience segmentation. |
| `oauthRedirectUrl` | Override the default localhost callback. Useful when tunneling OAuth through Codespaces or remote dev boxes. |
| `oauthScope` | Optional explicit OAuth scope string. If omitted, mcporter lets the MCP SDK derive scope from server/auth metadata. Use this as an escape hatch for providers that require explicit scopes but dont publish `scopes_supported`. |
| `oauthCommand.args` | For STDIO servers that ship a custom auth subcommand (e.g., Gmail MCP). mcporter will spawn the stdio command with these args when you run `mcporter auth <name>`, so you dont need to call `npx ... auth` manually. |
mcporter normalizes headers to include `Accept: application/json, text/event-stream` automatically, matching the runtimes streaming expectations.
## Imports & Conflict Resolution
- `pathsForImport(kind, rootDir)` determines every candidate path. mcporter searches the repo first, then user-level directories, and stops at the first file that parses.
- Entries pulled from imports are treated as read-only snapshots. The merge process keeps the first definition for each name; later sources with the same name are skipped until you override locally.
- To copy an imported entry, either run `mcporter config import <kind> --copy --filter name` or use `mcporter config add name --copy-from kind:name`. The copy operation writes through the same JSON normalization stack, so the resulting file matches our schema even if the source format was TOML (Codex) or legacy JSON shapes (`servers` vs `mcpServers`).
## Project vs. Machine Layers
- Keep `config/mcporter.json` under version control. Encourage contributors to add sensitive data via env vars (`${LINEAR_API_KEY}`) rather than inline secrets.
- Machine-specific additions can live in `~/.mcporter/local.json`; point `mcporter config --config ~/.mcporter/local.json add ...` there when you prefer not to touch the repo. Since the runtime only watches one config at a time, CI jobs should always pass `--config config/mcporter.json` (or run from the repo root) for deterministic behavior.
- OAuth tokens, cached server metadata, and generated CLIs should remain outside the repo (`~/.mcporter/<name>/`, `dist/`).
## Validation & Troubleshooting
- `mcporter list --http-url ...` refuses to auto-run OAuth to keep listing commands quick; use `mcporter config login ...` or `mcporter auth ...` to finish credential setup.
- When env placeholders are missing, commands fail fast with the exact variable name. Add the variable or wrap it in `${VAR:-fallback}` to provide defaults.
- Use `mcporter config get <name> --show-source` (planned flag) to confirm whether a server came from an import. If a teammates Cursor config keeps overriding your local entry, reorder the `imports` array to move Cursor later or set it to `[]` to disable imports entirely.
- `docs/adhoc.md` covers deeper debugging, including tmux workflows and OAuth promotion logs.
## Outstanding Coverage Items
- Describe how `--persist` writes through the same import merge pipeline (especially once `mcporter config add --copy-from` ships) so users know exactly which file changes.
- Call out that `--allow-http` remains required for cleartext URLs even in config mutations, and reiterate that `--env KEY=VAL` merges with on-disk env blocks rather than replacing them entirely.
- Clarify and illustrate the automatic OAuth promotion path for ad-hoc HTTP entries in both this doc and future `mcporter config login` help output.

View File

@ -19,14 +19,14 @@ mcporter emit-ts <server> --out linear-client.ts \
```
- `--mode types` (default) emits a `.d.ts` interface (`LinearTools`) with
docblocks + promisified signatures. Missing output schemas fall back to
`CallResult`.
docblocks + promisified signatures. Missing output schemas fall back to
`CallResult`.
- `--mode client` emits both the interface (auto-derived `.d.ts`) **and** an
executable `.ts` helper that wraps `createServerProxy`. Each method returns a
`CallResult`, and the factory exposes a `close()` helper for runtimes the client
creates.
executable `.ts` helper that wraps `createServerProxy`. Each method returns a
`CallResult`, and the factory exposes a `close()` helper for runtimes the client
creates.
- `--include-optional` mirrors `mcporter list --all-parameters`, ensuring every
parameter is shown even when optional.
parameter is shown even when optional.
Outputs overwrite existing files automatically so you can regenerate artifacts
whenever the server schema changes.
@ -81,13 +81,13 @@ returned objects `close()` becomes a no-op.
## Flags
| Flag | Description |
| --- | --- |
| `--out <path>` | Required. `.d.ts` target for `types`, `.ts` target for `client`. |
| `--mode types|client` | Output kind (defaults to `types`). |
| Flag | Description |
| -------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------- |
| `--out <path>` | Required. `.d.ts` target for `types`, `.ts` target for `client`. |
| `--mode types | client` | Output kind (defaults to `types`). |
| `--types-out <path>` | Optional override for the `.d.ts` file when `--mode client`. Default: derive from `--out`. |
| `--include-optional` | Include every parameter (not just the minimum 5 + required). |
| `--json` | Emit a JSON summary describing the emitted file(s) instead of plain-text logs. |
| `--include-optional` | Include every parameter (not just the minimum 5 + required). |
| `--json` | Emit a JSON summary describing the emitted file(s) instead of plain-text logs. |
## Testing

View File

@ -21,7 +21,7 @@ culprit is a child MCP server process that keeps the stdio transport alive.
child remains, mcporter will now unref and force-kill it, but the debug list
tells you exactly what was keeping the event loop alive.
4. **Capture the pane output** run `tmux capture-pane -p -t <session> -S
-200` to save the diagnostic log for later review.
-200` to save the diagnostic log for later review.
5. **Retry with `--timeout`** if the tool itself hangs, use
`--timeout <ms>` or `MCPORTER_CALL_TIMEOUT` to fail fast while still
gathering diagnostics.
@ -65,7 +65,7 @@ child process, which mcporter will now terminate during shutdown.
- Killing residual children is best-effort; if you see repeated `kill-failed`
messages, manually terminate the PID listed in the log.
- Always keep tmux sessions tidy after debugging: `tmux kill-session -t
<session>`.
<session>`.
- The CLI now forces `process.exit(0)` after cleanup by default so Node never
lingers on leaked handles. Export `MCPORTER_NO_FORCE_EXIT=1` if youre
debugging and need the process to stay alive.

View File

@ -28,15 +28,15 @@ Set `"imports": []` when you want to disable auto-merging entirely, or supply a
## Import Support Matrix
| Kind | Typical owner | Format | Project paths | User paths | Notes |
| --- | --- | --- | --- | --- | --- |
| `cursor` | Cursor IDE | JSON (`mcpServers`) | `.cursor/mcp.json` | macOS/Linux: `${XDG_CONFIG_HOME:-~/.config}/Cursor/User/mcp.json`<br>Windows: `%APPDATA%/Cursor/User/mcp.json` | Mirrors Cursors “MCP Servers” panel. Per-workspace files override the global file when both exist. |
| `claude-code` | Claude Code (browser) | JSON (`mcpServers`) | `.claude/settings.local.json`, `.claude/settings.json`, `.claude/mcp.json` | `~/.claude/settings.json`, `~/.claude/mcp.json`, `~/.claude.json` | `settings.local.json` (ignored by git) overrides `settings.json`, which is the shared project config; both beat the legacy `mcp.json`. |
| `claude-desktop` | Claude Desktop | JSON (`mcpServers`) | — | macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`<br>Windows: `%APPDATA%/Claude/claude_desktop_config.json`<br>Linux: `~/.config/Claude/claude_desktop_config.json` | Desktop Claude stores all servers per-machine, so theres no project-relative file. |
| `codex` | Sweetistics Codex | TOML (`[mcp_servers.*]`) | `.codex/config.toml` | `~/.codex/config.toml` | Only `config.toml` is recognized; the deprecated `mcp.toml` filename is ignored. |
| `windsurf` | Codeium Windsurf | JSON (`mcpServers`) | — | Windows: `%APPDATA%/Codeium/windsurf/mcp_config.json`<br>macOS/Linux: `~/.codeium/windsurf/mcp_config.json` | Global-only config managed by Codeium. |
| `opencode` | OpenCode | JSON/JSONC (`mcp`, `mcpServers`, or root map) | `opencode.json`, `opencode.jsonc` | `OPENCODE_CONFIG` override<br>`OPENCODE_CONFIG_DIR/opencode.json(c)`<br>macOS/Linux: `${XDG_CONFIG_HOME:-~/.config}/opencode/opencode.json(c)`<br>Windows: `%APPDATA%/opencode/opencode.json(c)` | Accepts comment-friendly `.jsonc` files and honors OpenCodes precedence env vars. |
| `vscode` | VS Code MCP extension | JSON (`mcpServers` or `servers`) | — | macOS: `~/Library/Application Support/Code(/Code - Insiders)/User/mcp.json`<br>Windows: `%APPDATA%/Code(/Code - Insiders)/User/mcp.json`<br>Linux: `~/.config/Code(/Code - Insiders)/User/mcp.json` | We probe both Stable and Insiders directories; the first readable file wins. |
| Kind | Typical owner | Format | Project paths | User paths | Notes |
| ---------------- | --------------------- | --------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `cursor` | Cursor IDE | JSON (`mcpServers`) | `.cursor/mcp.json` | macOS/Linux: `${XDG_CONFIG_HOME:-~/.config}/Cursor/User/mcp.json`<br>Windows: `%APPDATA%/Cursor/User/mcp.json` | Mirrors Cursors “MCP Servers” panel. Per-workspace files override the global file when both exist. |
| `claude-code` | Claude Code (browser) | JSON (`mcpServers`) | `.claude/settings.local.json`, `.claude/settings.json`, `.claude/mcp.json` | `~/.claude/settings.json`, `~/.claude/mcp.json`, `~/.claude.json` | `settings.local.json` (ignored by git) overrides `settings.json`, which is the shared project config; both beat the legacy `mcp.json`. |
| `claude-desktop` | Claude Desktop | JSON (`mcpServers`) | — | macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`<br>Windows: `%APPDATA%/Claude/claude_desktop_config.json`<br>Linux: `~/.config/Claude/claude_desktop_config.json` | Desktop Claude stores all servers per-machine, so theres no project-relative file. |
| `codex` | Sweetistics Codex | TOML (`[mcp_servers.*]`) | `.codex/config.toml` | `~/.codex/config.toml` | Only `config.toml` is recognized; the deprecated `mcp.toml` filename is ignored. |
| `windsurf` | Codeium Windsurf | JSON (`mcpServers`) | — | Windows: `%APPDATA%/Codeium/windsurf/mcp_config.json`<br>macOS/Linux: `~/.codeium/windsurf/mcp_config.json` | Global-only config managed by Codeium. |
| `opencode` | OpenCode | JSON/JSONC (`mcp`, `mcpServers`, or root map) | `opencode.json`, `opencode.jsonc` | `OPENCODE_CONFIG` override<br>`OPENCODE_CONFIG_DIR/opencode.json(c)`<br>macOS/Linux: `${XDG_CONFIG_HOME:-~/.config}/opencode/opencode.json(c)`<br>Windows: `%APPDATA%/opencode/opencode.json(c)` | Accepts comment-friendly `.jsonc` files and honors OpenCodes precedence env vars. |
| `vscode` | VS Code MCP extension | JSON (`mcpServers` or `servers`) | — | macOS: `~/Library/Application Support/Code(/Code - Insiders)/User/mcp.json`<br>Windows: `%APPDATA%/Code(/Code - Insiders)/User/mcp.json`<br>Linux: `~/.config/Code(/Code - Insiders)/User/mcp.json` | We probe both Stable and Insiders directories; the first readable file wins. |
> Tip: mcporter resolves `~` and `$XDG_CONFIG_HOME` inside these paths automatically, so you can rely on the same `imports` list across platforms.
>

View File

@ -9,6 +9,7 @@ read_when:
This file tracks limitations that users regularly run into. Most of these require upstream cooperation or larger refactors—feel free to reference this when triaging bugs.
## Hosted OAuth servers (Supabase, GitHub MCP, etc.)
- Supabases hosted MCP server rejects the standard `mcp:tools` scope and only accepts Supabase-specific scopes (`projects:read`, `database:write`, ...). Because they do not expose OAuth discovery metadata or scope negotiation, mcporter cannot auto-register or complete the flow. Workarounds:
- Use Supabases supported clients (Cursor, Windsurf).
- Self-host their MCP server and configure PAT headers / custom OAuth.
@ -16,16 +17,19 @@ This file tracks limitations that users regularly run into. Most of these requir
- GitHubs MCP endpoint (`https://api.githubcopilot.com/mcp/`) returns “does not support dynamic client registration” when mcporter attempts to connect. Copilots backend expects pre-registered client credentials. Until GitHub publishes a dynamic-registration API (or client secrets), mcporter cannot interact with their hosted server.
## Output schemas missing/buggy on many servers
- The MCP spec allows servers to omit `outputSchema`. In practice, many hosted MCPs return empty or inconsistent schemas, so features that rely on return types (TypeScript signatures, generated CLIs, `createServerProxy` return helpers) may degrade to `unknown`.
- Workarounds: inspect the servers README / manual docs for output details, or wrap the tool via `createServerProxy` and handle the raw envelope manually.
- Potential improvement: allow user-provided schema overrides (e.g., `mcporter config patch`, CLI flag to load schema JSON) so we can fill gaps on a per-tool basis.
## MCP SDK 1.22.0 inline-stdio regression
- Upgrading `@modelcontextprotocol/sdk` to 1.22.0 causes `mcporter generate-cli --compile` (and direct runtime `listTools`) to fail against inline STDIO servers with `MCP error -32603: Cannot read properties of undefined (reading 'typeName')`.
- Repro: `pnpm mcporter generate-cli "node mock-stdio.mjs" --compile /tmp/inline-cli --runtime bun` using the inline stdio harness in `tests/cli-generate-cli.integration.test.ts`.
- Status: reproduced locally; pinned the SDK to `~1.21.2` until upstream ships a fix.
## Next Steps
- Implement true scope negotiation (read discovery metadata, allow `--oauth-scope`).
- Keep lobbying providers for spec-compliant OAuth behavior.
- Consider adding schema override hooks or auto-caching schema snapshots per tool.

View File

@ -9,10 +9,12 @@ read_when:
These tests hit real hosted MCP servers and require outbound HTTP. They are **off by default** to keep CI and local runs deterministic.
## When to run
- Before releases when you want end-to-end validation against hosted servers.
- When debugging regressions that only repro against real servers (e.g., DeepWiki).
## How to run
```bash
MCP_LIVE_TESTS=1 pnpm test:live
```
@ -20,6 +22,7 @@ MCP_LIVE_TESTS=1 pnpm test:live
This runs the Vitest suite under `tests/live`, in-band, with longer timeouts.
## Current coverage
- **DeepWiki**:
- Streamable HTTP success path: `https://mcp.deepwiki.com/mcp`
- Deprecated SSE endpoint classification: `https://mcp.deepwiki.com/sse`
@ -28,6 +31,7 @@ This runs the Vitest suite under `tests/live`, in-band, with longer timeouts.
- assert the legacy SSE endpoint currently returns a structured HTTP `410` issue envelope
## Notes
- Tests are skipped entirely unless `MCP_LIVE_TESTS=1` is set.
- Ensure network egress is allowed. No secrets are required for the current DeepWiki checks.
- As of 2026-03-29, DeepWiki's hosted `/sse` endpoint responds with HTTP `410`, so the live suite treats that as a compatibility/error-classification smoke rather than a success-path transport check.

View File

@ -40,6 +40,7 @@ cat /tmp/list-SERVER.log
```
Verify:
- Header shows the right name/transport and the new metadata line (`tools · duration · transport`).
- Timeouts produce the footer block: `Tools: <timed out after ...>` and `Reason: ...`.
@ -53,6 +54,7 @@ cat /tmp/call-SERVER.log
```
Checks:
- Successful calls print the payload; failures reuse the shared hinting (`SSE error ...`, auto-correct messages, etc.).
- For HTTP selectors (`https://.../mcp.tool` or `https://.../mcp.tool(args)`), ensure no OAuth prompt appears and the request hits the configured server.
@ -68,6 +70,7 @@ cat /tmp/auth-SERVER.log
```
Expectations:
- If a token cache exists, log should mention the cleared directory.
- Failed auths emit the unified message (`Failed to authorize 'SERVER': ...`).

View File

@ -33,11 +33,11 @@ npm install mcporter
## 4. Programmatic Usage
```ts
import { createRuntime } from "mcporter";
import { createRuntime } from 'mcporter';
const runtime = await createRuntime({ configPath: "./config/mcporter.json" });
const tools = await runtime.listTools("chrome-devtools");
await runtime.callTool("chrome-devtools", "take_screenshot", { args: { url: "https://x.com" } });
const runtime = await createRuntime({ configPath: './config/mcporter.json' });
const tools = await runtime.listTools('chrome-devtools');
await runtime.callTool('chrome-devtools', 'take_screenshot', { args: { url: 'https://x.com' } });
await runtime.close();
```
@ -46,12 +46,12 @@ Prefer `createRuntime` for long-lived agents so connections and OAuth tokens can
## 5. Single Call Helper
```ts
import { callOnce } from "mcporter";
import { callOnce } from 'mcporter';
await callOnce({
server: "firecrawl",
toolName: "crawl",
args: { url: "https://anthropic.com" },
server: 'firecrawl',
toolName: 'crawl',
args: { url: 'https://anthropic.com' },
});
```
@ -65,12 +65,12 @@ Use `callOnce` for fire-and-forget invocations.
## 7. Troubleshooting
| Symptom | Fix |
| --- | --- |
| Browser did not open | Copy the printed OAuth URL manually into a browser. |
| Authorization hangs | Ensure the callback URL can bind to `127.0.0.1`; firewalls may block it. |
| Tokens are stale | Delete `~/.mcporter/<server>/tokens.json` and retry. |
| Stdio command fails | Pass `--root` to point at the repo root so relative paths resolve. |
| Symptom | Fix |
| -------------------- | ------------------------------------------------------------------------ |
| Browser did not open | Copy the printed OAuth URL manually into a browser. |
| Authorization hangs | Ensure the callback URL can bind to `127.0.0.1`; firewalls may block it. |
| Tokens are stale | Delete `~/.mcporter/<server>/tokens.json` and retry. |
| Stdio command fails | Pass `--root` to point at the repo root so relative paths resolve. |
---

View File

@ -9,7 +9,8 @@ read_when:
This doc tracks remaining reuse/refactor work now that the original plan is done.
Each section lists the goal, why it matters, and the concrete steps/tests needed.
## 1. Shared Tool Schema Cache *(Completed)*
## 1. Shared Tool Schema Cache _(Completed)_
- **Problem**: `generate-cli` and `emit-ts` both fetch & serialize tool schemas
independently (and `mcporter list` re-parses them too).
- **What we did**:
@ -18,7 +19,8 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
3. Added `tests/tool-cache.test.ts` + updated emit-ts tests to ensure the helper is covered.
- **Next**: Consider integrating the cache into `generate-cli` if we ever reuse runtime instances there.
## 2. Unified Flag Parsing for Generator-style Commands *(Completed)*
## 2. Unified Flag Parsing for Generator-style Commands _(Completed)_
- **Problem**: `generate-cli`, the (now legacy) `regenerate-cli` wrapper, and `emit-ts` each
reimplemented `--runtime`, `--timeout`, and `--include-optional` handling.
- **What we did**:
@ -29,7 +31,8 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
3. Added `tests/generator-flag-parser.test.ts` to cover runtime/timeout and
optional flags.
## 3. Test Fixture Reuse *(Completed)*
## 3. Test Fixture Reuse _(Completed)_
- **Problem**: Emit-ts/tool-cache/unit tests each defined their own tool/definition
fixtures, leading to divergence.
- **What we did**:
@ -39,7 +42,8 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
3. Ensured the fixture covers required+optional parameters so both suites hit
the same edge cases.
## 4. CallResult Helper Extraction *(Completed)*
## 4. CallResult Helper Extraction _(Completed)_
- **Problem**: `call-command.ts` and the emit-ts client template both wrapped
results with `createCallResult`, but there was no shared helper.
- **What we did**:
@ -49,7 +53,8 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
they stay in sync.
3. Adjusted emit-ts tests to assert the helper is referenced.
## 5. CLI Docs Consolidation *(Completed)*
## 5. CLI Docs Consolidation _(Completed)_
- **Problem**: CLI usage guidance was scattered across README, `docs/spec.md`,
and various feature docs.
- **What we did**:
@ -60,7 +65,8 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
- **Next**: Once the other doc changes land, update README/spec to link to the
reference and drop redundant sections.
## 6. Runtime Module Split *(Completed)*
## 6. Runtime Module Split _(Completed)_
- **Problem**: `src/runtime.ts` had grown bulky (600+ lines) mixing transport setup, OAuth flow control, and small helpers, making tests and reuse harder.
- **What we did**:
1. Extracted transport construction/retry logic to `src/runtime/transport.ts`.
@ -72,5 +78,6 @@ Each section lists the goal, why it matters, and the concrete steps/tests needed
- **Next**: Keep new helpers in sync as runtime evolves; prefer adding surface to these modules over growing `runtime.ts` again.
---
Tracking the above here keeps future agents aligned. Update this checklist as
items ship (mark sections “Completed” when done, or delete the doc once empty).

View File

@ -7,11 +7,13 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
> Inspired in part by Anthropics 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:call` ergonomics 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 todays single-call flow.
@ -23,6 +25,7 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
- Documentation: README, usage examples, migration guide for replacing `pnpm mcp:*`.
## Architecture Notes
- Load MCP definitions from JSON (support relative paths + HTTPS).
- Reuse `@modelcontextprotocol/sdk` transports; invoke stdio servers directly (e.g., call `npx` with 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.
@ -35,6 +38,7 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
- Document Cursor-compatible `config/mcporter.json` structure; 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.json` for reuse across processes, and tolerate failures by falling back to raw `callTool`.
- Allow direct method-style invocations such as `context7.getLibraryDocs("react")` by:
- Mapping camelCase properties to kebab-case tool names.
@ -47,6 +51,7 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
- 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-cli` should accept inline JSON, file paths, inline stdio commands (either via `--command` or 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 `.cjs` files or Bun-ready `.js` binaries with executable shebangs.
@ -54,24 +59,28 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
- 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.json` mirrors Cursor/Claude schema: `mcpServers` map with entries containing `baseUrl` or `command`+`args`, optional `headers`, `env`, `description`, `auth`, `tokenCacheDir`, and convenience `bearerToken`/`bearerTokenEnv` fields.
- Optional `imports` array (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 `configPath` override 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
1. **Scaffold Package**
- Init pnpm workspace config, tsconfig, lint/test scaffolding, build script.
2. **Core Runtime**
- Port config parsing + env/header logic.
- Implement connection cache, tool invocation, resource helpers.
3. **CLI Surface**
- Implement `list` (with optional schema) and `call` commands.
- Render tool metadata as pseudo-TypeScript declarations: blue `function` signatures, grey doc comments using `@param` lines, 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 theyre optional) before summarising the remainder.
- Ensure output parity with existing helper.
- `call` has to parse both `server.tool` tokens and HTTP selectors like `https://host/path.tool(args)`; in the HTTP case we need to peel off the `.tool` suffix, infer/auto-register the ad-hoc server (respecting `--allow-http`), and hydrate arguments from parentheses or trailing `key=value` pairs.
- Add `generate-cli` for standalone/bundled CLIs with embedded schema caching.
- Ensure `generate-cli`, `inspect-cli`, and `emit-ts` share the same server-resolution logic as `list/call`, including HTTP URL matching and scheme-less selectors with `.tool` suffixes.
4. **Testing & Fixtures**
- Mock representative MCP servers (stdio + HTTP + OAuth) for integration tests.
- Snapshot output for `list` vs. `call`.
@ -80,6 +89,7 @@ summary: 'Plan for the mcporter package replacing the Sweetistics pnpm MCP helpe
- 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?

View File

@ -5,6 +5,7 @@ summary: 'Multi-agent system directives and coordination rules. Master reference
# Claude Subagent Quickstart
## CLI Basics
- Never invoke subagents through `./runner`—launch them inside tmux directly so the session can persist and bypass the runner timeouts. Example:
```bash
@ -13,6 +14,7 @@ summary: 'Multi-agent system directives and coordination rules. Master reference
```
Once inside the session, run `/model` to confirm the active alias (`haiku` maps to Claude 3.5 Haiku) and switch models if needed.
- Need to queue instructions without attaching? Use `bun scripts/agent-send.ts --session <name> -- "your command"` to inject text into a running agent session (single Enter is sent by default).
- Run Claude through the repo wrapper when you just need help (`./runner claude --help`), but for actual delegation launch Claude inside tmux so the work keeps running after you disconnect.
- Two modes:
@ -23,16 +25,19 @@ summary: 'Multi-agent system directives and coordination rules. Master reference
- Ralphs supervisor loop launches Claude the same way (`claude --dangerously-skip-permissions "<prompt>"`) to keep the tmux automation flowing.
## One-Shot Prompts
- The CLI accepts the prompt as a trailing argument in one-shot mode. Multi-line prompts can be piped: `echo "..." | ./runner claude --print`.
- Add `--output-format json` when you need structured fields (e.g., summary + bullets) for post-processing.
- Keep prompts explicit about reading full files: “Read docs/example.md in full and produce a 23 sentence summary covering all sections.”
## Bulk Markdown Conversion
- Produce the markdown inventory first (`pnpm run docs:list`) and feed batches of filenames to your Claude session.
- For each batch, issue a single instruction like “Rewrite these files with YAML front matter summaries, keep all other content verbatim.” Haiku can loop over multi-file edits when you provide the explicit list.
- After Claude reports success, diff each file locally (`./runner git diff docs/<file>.md`) before moving to the next batch.
## Ralph Integration Notes
- Ralph (see `scripts/ralph.ts`) spins up tmux sessions, auto-wakes the worker, and calls Claude as the supervisor via `claude --dangerously-skip-permissions`.
- Supervisor responses must end with either `CONTINUE`, `SEND: <message>`, or `RESTART`; Ralph parses these tokens to decide the next action.
- To start Ralph manually: `bun scripts/ralph.ts start --goal "…" [--markdown path]`. Progress is tracked in `.ralph/progress.md` by default.

View File

@ -7,6 +7,7 @@ read_when:
# OAuth Notes & Hosted MCP Compatibility
## MCP Spec Expectations
- The June182025 MCP “Authorization” spec (and the linked OAuth flow document) requires OAuth2.1 dynamic client registration plus RFC7235 `WWW-Authenticate` challenges for scope negotiation.
- Servers SHOULD expose discovery metadata via `/.well-known/oauth-authorization-server` and `/.well-known/oauth-protected-resource`. Those documents list supported scopes and additional OAuth endpoints.
- Clients are expected to start with a baseline scope (the spec uses `mcp:tools`) and then re-authenticate with any server-supplied scope hints.
@ -14,6 +15,7 @@ read_when:
We currently hard-code `mcp:tools` because it is the only scope guaranteed to exist in the MCP reference implementation. We need richer negotiation to support providers that enforce product-specific scopes.
## Hosted Supabase MCP (~Oct2025)
Supabases hosted MCP server (`https://mcp.supabase.com/mcp`) validates the requested scopes against their management API permissions (`organizations:read`, `projects:read`, `database:write`, `storage:read`, etc.). When mcporter asks for `mcp:tools`, their authorization server rejects the request with HTTP400 and a body similar to:
```
@ -21,11 +23,13 @@ Supabases hosted MCP server (`https://mcp.supabase.com/mcp`) validates the re
```
Key takeaways from Supabases docs:
1. Hosted installs rely on dynamic client registration and are currently integrated with Cursor/Windsurf (which embed the Supabase scope list).
2. Manual authentication is offered for self-hosted/CI workflows (PAT headers or custom OAuth app), but their hosted server still expects Supabase-specific scopes.
3. There is no public metadata endpoint describing those scopes, so third-party MCP clients cannot opt in automatically.
## mcporters Current Behavior
- We auto-promote ad-hoc HTTP servers to OAuth and retry once when we see 401/403 errors.
- We surface any server-supplied OAuth error payload so its obvious whether the problem is scope-related, a missing token, etc.
- After the second failure we stop retrying to avoid infinite loops.
@ -33,6 +37,7 @@ Key takeaways from Supabases docs:
This works for providers that use standard MCP scopes (e.g., the MCP example server, Vercels MCP), but it fails for Supabase because they reject `mcp:tools` outright.
## Roadmap / Proposed Improvements
1. **Scope discovery & negotiation**
- Fetch `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server` when a server advertises OAuth. If `scopes_supported` is present, intersect it with user overrides and use that list instead of `mcp:tools`.
- Parse `WWW-Authenticate` challenges on 401/403 responses and restart the authorization flow with the scopes the server demands.
@ -46,6 +51,7 @@ This works for providers that use standard MCP scopes (e.g., the MCP example ser
- File upstream issues (e.g., Supabase) requesting support for standard MCP scopes or publication of `scopes_supported` metadata, so we can integrate without custom code.
## Workarounds Today
- Use a supported GUI client (Cursor, Claude Desktop, Windsurf) for Supabases hosted MCP—they already ship the necessary scopes.
- Self-host Supabase MCP and configure PAT headers or your own OAuth client; you can then relax scope validation to include `mcp:tools`.
- For other providers, consult their docs for discovery metadata. If they list scopes, set them via a future `--oauth-scope` flag once we implement it (tracked in #TODO).

View File

@ -13,11 +13,14 @@ Use `tmux` to verify whether a CLI command actually exits or is stalled on open
tmux new-session -ds mcporter-check "pnpm exec tsx src/cli.ts list"
```
2. Wait a few seconds, then ask tmux if the session is still running:
```bash
tmux has-session -t mcporter-check
```
- Exit status **1** (`can't find session`) means the process exited normally.
- Exit status **0** means the command is still running (or hung) inside the session.
3. Capture the output without attaching:
```bash
tmux capture-pane -pt mcporter-check | tail -n 40

View File

@ -69,6 +69,7 @@ mcporter call --http-url https://mcp.example.com/mcp fetch_docs repoName=value
---
**Tips**
- Use `mcporter list <server>` to see parameter names, return types, and example invocations.
- Optional fields hide by default; add `--all-parameters` when listing a server to reveal everything.
- `mcporter auth <server|url>` accepts the same ad-hoc flags, so you can authenticate immediately after a 401 without editing config.

View File

@ -5,21 +5,21 @@ summary: What to do when pnpm/test flows fail on NTFS-backed worktrees.
## Installing dependencies
* `pnpm install` fails on `/mnt/c` because NTFS/DrvFs blocks `futime`. Clone/sync the repo to `$HOME` (ext4 inside WSL) and run `./runner pnpm install` there instead. Example: `rsync -a --delete --exclude node_modules /mnt/c/Projects/mcporter/ ~/mcporter-wsl/`.
* Keep `$HOME/.bun/bin` and `$HOME/.local/share/pnpm` on your PATH before invoking `./runner`. Without Bun and pnpm the runner prints the guardrail error and exits.
* If you *must* work from `/mnt/c`, remount with `metadata` support (`sudo mount -t drvfs C: /mnt/c -o metadata,uid=$(id -u),gid=$(id -g),umask=22,fmask=111`). Otherwise installs, chmods, and copyfile calls will continue to fail.
- `pnpm install` fails on `/mnt/c` because NTFS/DrvFs blocks `futime`. Clone/sync the repo to `$HOME` (ext4 inside WSL) and run `./runner pnpm install` there instead. Example: `rsync -a --delete --exclude node_modules /mnt/c/Projects/mcporter/ ~/mcporter-wsl/`.
- Keep `$HOME/.bun/bin` and `$HOME/.local/share/pnpm` on your PATH before invoking `./runner`. Without Bun and pnpm the runner prints the guardrail error and exits.
- If you _must_ work from `/mnt/c`, remount with `metadata` support (`sudo mount -t drvfs C: /mnt/c -o metadata,uid=$(id -u),gid=$(id -g),umask=22,fmask=111`). Otherwise installs, chmods, and copyfile calls will continue to fail.
## Running tests
* Use the ext4 copy (`~/mcporter-wsl`) for `pnpm lint`, `pnpm typecheck`, and the Vitest suites. All tests pass there (71 files / 280 tests, 1 file and 2 tests skipped).
* Whole-repo `pnpm test` on `/mnt/c` repeatedly times out because Vitest cannot start workers when the node_modules tree belongs to root or sits on NTFS. Copy the repo to ext4 or fix ownership before retrying.
* When working cross-filesystem, remember to sync the edited source files back to the canonical `/mnt/c/Projects/mcporter` tree (e.g., `rsync -a ~/mcporter-wsl/src/cli/generate/{template,artifacts,fs-helpers}.ts /mnt/c/Projects/mcporter/src/cli/generate/`).
* The stdio integration suite now vendors two tiny fixtures under `tests/fixtures/stdio-*.mjs` that spin up filesystem/memory MCP servers via `node`. The tests shell out to `process.execPath`, so make sure your PATH resolves `node` correctly (fnm/nvs setups sometimes expose only `node.exe` on Windows). If you need to debug them manually, run `./runner pnpm exec vitest run tests/stdio-servers.integration.test.ts` so the guardrails apply.
- Use the ext4 copy (`~/mcporter-wsl`) for `pnpm lint`, `pnpm typecheck`, and the Vitest suites. All tests pass there (71 files / 280 tests, 1 file and 2 tests skipped).
- Whole-repo `pnpm test` on `/mnt/c` repeatedly times out because Vitest cannot start workers when the node_modules tree belongs to root or sits on NTFS. Copy the repo to ext4 or fix ownership before retrying.
- When working cross-filesystem, remember to sync the edited source files back to the canonical `/mnt/c/Projects/mcporter` tree (e.g., `rsync -a ~/mcporter-wsl/src/cli/generate/{template,artifacts,fs-helpers}.ts /mnt/c/Projects/mcporter/src/cli/generate/`).
- The stdio integration suite now vendors two tiny fixtures under `tests/fixtures/stdio-*.mjs` that spin up filesystem/memory MCP servers via `node`. The tests shell out to `process.execPath`, so make sure your PATH resolves `node` correctly (fnm/nvs setups sometimes expose only `node.exe` on Windows). If you need to debug them manually, run `./runner pnpm exec vitest run tests/stdio-servers.integration.test.ts` so the guardrails apply.
## Windows-specific fixes in the repo
* CLI generation now uses `src/cli/generate/fs-helpers.ts`: `markExecutable` ignores `EPERM/EINVAL/ENOSYS/EACCES` so NTFS builds no longer fail when setting executable bits.
* `safeCopyFile` falls back to a manual read/write when DrvFs blocks `copyFile`, keeping Bun bundling stable on Windows.
* These helpers only affect Windows/WSL behavior—Linux/macOS paths still perform real `chmod`/`copyFile`.
* Regenerated CLIs (for example `node dist/cli.js generate-cli context7 --config config/mcporter.json --bundle /mnt/c/Temp/context7-cli.js --runtime node`) now complete successfully even when the bundle lives on `/mnt/c`, and the resulting executable runs with `node /mnt/c/Temp/context7-cli.js --help`.
* When running `mcporter generate-cli` with `--command ./relative-script.ts`, the CLI no longer tries to normalize the path into an HTTP URL—relative/bare commands are always treated as STDIO transports now, matching the PowerShell/WSL behavior you expect.
- CLI generation now uses `src/cli/generate/fs-helpers.ts`: `markExecutable` ignores `EPERM/EINVAL/ENOSYS/EACCES` so NTFS builds no longer fail when setting executable bits.
- `safeCopyFile` falls back to a manual read/write when DrvFs blocks `copyFile`, keeping Bun bundling stable on Windows.
- These helpers only affect Windows/WSL behavior—Linux/macOS paths still perform real `chmod`/`copyFile`.
- Regenerated CLIs (for example `node dist/cli.js generate-cli context7 --config config/mcporter.json --bundle /mnt/c/Temp/context7-cli.js --runtime node`) now complete successfully even when the bundle lives on `/mnt/c`, and the resulting executable runs with `node /mnt/c/Temp/context7-cli.js --help`.
- When running `mcporter generate-cli` with `--command ./relative-script.ts`, the CLI no longer tries to normalize the path into an HTTP URL—relative/bare commands are always treated as STDIO transports now, matching the PowerShell/WSL behavior you expect.

View File

@ -127,9 +127,7 @@
"description": "Arguments for the OAuth command"
}
},
"required": [
"args"
],
"required": ["args"],
"additionalProperties": false
},
"oauth_command": {
@ -144,9 +142,7 @@
"description": "Arguments for the OAuth command"
}
},
"required": [
"args"
],
"required": ["args"],
"additionalProperties": false
},
"bearerToken": {
@ -200,9 +196,7 @@
"maximum": 9007199254740991
}
},
"required": [
"mode"
],
"required": ["mode"],
"additionalProperties": false
}
],
@ -237,15 +231,7 @@
"type": "array",
"items": {
"type": "string",
"enum": [
"cursor",
"claude-code",
"claude-desktop",
"codex",
"windsurf",
"opencode",
"vscode"
],
"enum": ["cursor", "claude-code", "claude-desktop", "codex", "windsurf", "opencode", "vscode"],
"description": "Supported editor/client configurations to import MCP servers from"
}
},
@ -254,9 +240,7 @@
"description": "JSON Schema URL for IDE validation and autocomplete"
}
},
"required": [
"mcpServers"
],
"required": ["mcpServers"],
"additionalProperties": false,
"description": "mcporter configuration file schema",
"$id": "https://raw.githubusercontent.com/steipete/mcporter/main/mcporter.schema.json"

View File

@ -4,7 +4,7 @@
"opencode-user-only": {
"description": "User-level OpenCode server",
"command": "opencode-user-cli",
"args": ["--json"]
}
}
"args": ["--json"],
},
},
}

View File

@ -5,7 +5,7 @@
"description": "Project-level OpenCode server",
"type": "stdio",
"command": "opencode-cli",
"args": ["serve"]
}
}
"args": ["serve"],
},
},
}