npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

coding-tools-conductor

v0.1.2

Published

A TypeScript orchestration layer for coding-tools-mcp.

Readme

Coding Tools Conductor

Coding Tools Conductor (ctc) is an orchestration layer that sits above coding-tools-mcp. It exposes a single MCP server to your model and talks to the lower Python MCP server as an MCP client, adding the things a coding agent needs around raw file and git operations: workspace lifecycle, isolated git worktrees, human review checkpoints, handoff state, remote access, and aggregation of other MCP servers.

Run ctc for an interactive terminal UI, or ctc start for a headless MCP server that any model client can connect to over stdio.

Contents

Installation

Requires Node.js 22+. Install the CLI globally:

npm install -g coding-tools-conductor   # provides the `ctc` command

Or run it once without installing:

npx coding-tools-conductor --help

run-ctc is a name alias for the same package and the same ctc command — install one or the other, not both. The project is in beta; add @beta to pull the newest pre-release (npm install -g coding-tools-conductor@beta).

You do not need to install the lower coding-tools-mcp server yourself. If it is not already on your PATH, ctc runs it with uvx coding-tools-mcp (uv fetches the published PyPI package on first use), or you can point ctc at a Docker image or a remote HTTP endpoint instead — see Backends.

Quick start

ctc                     # open the TUI and start a session for the current repo
ctc /path/to/repo       # same, for another repo

Launching ctc opens an interactive terminal UI and starts a live session on the target repository. Point your model client at the MCP endpoint it prints, edit the repo through the model, and use /diff to review changes before you keep them. Quitting closes the session and stops the backend.

For a headless server with no UI (for example, embedding ctc in another host):

ctc start /path/to/repo

How it works

Conductor is a thin, opinionated layer with a strict division of responsibilities:

  1. Single atomic filesystem, process, and git operations belong to coding-tools-mcp. Conductor forwards these instead of rebuilding them.
  2. Cross-tool state — policy, workspace lifecycle, human review checkpoints, and handoff flows — belongs to Conductor.
  3. Conductor reaches the lower layer only through MCP. It does not import the Python project or run shell/git directly. The sole exception is the workspace/ module, where managed git worktree creation and cleanup must run in the source repository before the lower server is pointed at the worktree.

A CI lint enforces boundary 3 by keeping execa out of every module except src/workspace/ and the setup wizard.

Primary backend tools are re-exposed to the model without prefixes (subject to profile allow/deny policy). Conductor adds its own workspace, review, and baton tools on top, and any additional MCP servers are re-exposed with a <server>__ prefix. Every proxied tool call emits a JSONL audit event under ~/.ctc/logs/.

The terminal UI

Launching ctc is the session: the TUI opens a workspace session for the repo (direct mode by default) and quitting closes it — the workspace record is stamped closed and the backend stops, the way Claude Code or Codex CLI treat a run. A separate observe mode, ctc tui <session-id>, renders an external ctc start session read-only and answers its permission prompts without hosting a session of its own.

Transcript. Activity renders as an append-only transcript that flows into terminal scrollback, in the style of Claude Code: each tool call is a line with a dimmed result (or a red error), review checkpoints render as inline diff cards, and notices appear as / / · notes. Updates are event-driven — the TUI watches the active session's log with a dirty-checked snapshot store rather than repainting on a timer.

Commands. Typing / opens a navigable menu of every command, grouped by area (Sessions, Review, Configure, Interface). It fuzzy-matches as you type (/dr finds doctor), highlights matched characters, and wraps at the ends — arrows to choose, Tab to complete, Enter to run. See the TUI command reference for the full list.

Composer. The input supports the usual readline editing keys: Ctrl+A/E to jump to line start/end, Ctrl+W/U/K to delete by word or to the line edges, and Ctrl+←/→ or Alt+←/→ to move by word.

Panels. Bounded panels open over the live region for /diff, /baton, /approvals, /config, /inspect (also Ctrl+O), /doctor, and /help; ↑/↓ scroll by line, ←/→ (or PgUp/PgDn) page while the composer is empty, and Esc closes. /clear resets the transcript, and Ctrl+C must be pressed twice to quit so a stray interrupt cannot tear down the live session.

Approvals. If the model calls the lower request_permissions tool while the TUI is attached, Conductor pauses the request and shows an approval prompt with selectable options (y/n, 1/2, arrows + Enter; left/right walk the queue when several requests are pending; Esc denies). Without an attached TUI, the request falls back to the lower backend's existing permission flow.

Backends

ctc start connects to the lower MCP server in one of three modes, selected with --backend or during ctc setup:

| Mode | What it does | | --- | --- | | stdio (default) | Spawns coding-tools-mcp --stdio --workspace <path>, or a profile/CLI-supplied command. When no command is configured, resolution mirrors how esbuild finds its platform binary: a coding-tools-mcp on PATH wins, otherwise ctc falls back to uvx coding-tools-mcp. If both are missing, startup fails with install guidance instead of a bare spawn ... ENOENT. | | docker | Runs the published sandbox image (ghcr.io/xytom/coding-tools-mcp-sandbox:latest, override with CTC_BACKEND_DOCKER_IMAGE or ctc setup) with the workspace bind-mounted at /workspace, via docker run --rm -i --init. The image is pulled on first start. | | http | Connects to a Streamable HTTP MCP endpoint with an optional bearer token read from an environment variable. |

ctc start /path/to/repo --backend stdio
ctc start /path/to/repo --backend docker
ctc start /path/to/repo --backend-command-json '["uvx","coding-tools-mcp","--stdio","--workspace","/path/to/repo"]'
ctc start /path/to/repo --backend http --backend-url http://127.0.0.1:8765/mcp --backend-token-env CTC_TOKEN

--backend-command accepts a bare command name only; flags after it are parsed as ctc's own options, so use --backend-command-json for commands that need arguments.

First starts that download (uvx) or pull (docker) can exceed the 5-minute control-plane budget on slow networks; raise it with CTC_BACKEND_CONTROL_TIMEOUT_MS.

Workspaces and review

Workspace mode defaults to direct — the model edits the repo in place. Worktree isolation is an explicit opt-in (/new --worktree), which opens a detached git worktree so the model's changes stay off your working tree until you merge them.

Three model-facing tools drive this:

  • open_workspace opens either a direct workspace or an isolated detached git worktree, then points the lower MCP server at that path with set_default_cwd.
  • close_workspace closes the active workspace and removes managed worktrees when they are clean, or when force is explicitly passed.
  • show_changes creates a temporary-index git snapshot, diffs it against refs/ctc/review/<session>/baseline, last-shown, or HEAD, and advances last-shown after each review checkpoint.

Only worktree mode requires a git repository. A direct workspace opens in any directory: when the path is not a repository (or has no commits yet), open_workspace still succeeds and reports review.available: false with the reason, and the TUI notes that review checkpoints are off. show_changes re-checks on each call, so git init plus a first commit turns checkpoints on mid-session without reopening the workspace.

Human-side workspace commands:

ctc ws list
ctc ws clean --yes
ctc ws clean --force --yes
ctc ws merge <session-id>

Inside the TUI, /clean [--force|--yes] mirrors ctc ws clean with an in-terminal confirmation prompt. Cleaning also prunes closed session records — their ~/.ctc JSON, log, and approval files are deleted so state stays bounded; the TUI's active session is always exempt.

Managed worktrees are created inside the repository at .ctc/worktrees/<session-id> so the workspace-confined lower server can reach them with workspace-relative paths (it denies absolute paths). The directory is added to .git/info/exclude automatically, so it never shows up in source-repo status, diffs, or merges.

Worktree creation and cleanup are the only direct git operations in the core runtime. Review checkpoints run git through the lower exec_command tool so the layering boundary stays intact.

Project context and skills

open_workspace returns a context guide alongside workspace metadata:

  • Repository-root AGENTS.md, CLAUDE.md, and .cursorrules files are listed with byte counts; root-level files are inlined up to a fixed safety limit.
  • Nested instruction files are listed by path so the model knows where deeper rules exist before editing there.
  • Workspace skills are discovered from .ctc/skills/<name>/SKILL.md, with .claude/skills/ read as a compatibility fallback.

The model-facing load_skill tool returns the full SKILL.md content for a skill listed by open_workspace.context.skills.

Baton handoff

The baton is local handoff state written inside the active workspace's .baton/ directory. Model-facing tools write there and nowhere else:

  • baton_write_plan(content) writes .baton/plan.md.
  • baton_read_plan() reads .baton/plan.md.
  • baton_update_status(phase, step?, state, note?) writes .baton/status.json with an updatedAt timestamp.
  • baton_write_report(content) writes .baton/report.md.

The directory also holds an artifacts/ folder for future diff or log attachments. Add .baton/ to your workspace gitignore when using it.

Inspect the baton from the CLI (ctc baton show /path/to/repo) or the TUI (/baton).

Remote access

/tunnel start exposes the MCP server over a free try.cloudflare.com tunnel so remote connectors (ChatGPT, Claude, and other MCP clients) can reach it. A tunnel requires the live session — one is started automatically, and /new restores it after a /close.

If cloudflared is already installed the tunnel starts immediately. Otherwise the TUI opens a picker of the ways this host can run one:

  • Use wrangler (no install) — runs wrangler tunnel quick-start <url>, using a wrangler on PATH or npx wrangler (the first npx run downloads wrangler and can take a minute). Nothing is installed permanently.
  • Install cloudflaredbrew install cloudflared on macOS when Homebrew is present, otherwise the official release binary is downloaded to ~/.ctc/bin/cloudflared. The managed binary is preferred on later runs, so this is a one-time step.

Both providers surface the same *.trycloudflare.com URL. Hosts with neither cloudflared nor npx say so plainly instead of hanging.

Endpoints and transports

Model clients connect to the stable /mcp endpoint (locally http://127.0.0.1:<port>/mcp, through a tunnel https://<tunnel-host>/mcp). The port is persisted in the workspace profile, so a client configured once keeps working across ctc restarts. /mcp serves the live session; /mcp/<session-id> pins a specific id (a /new replacement mints a new one). Each client that POSTs an initialize request gets its own MCP session (routed by the Mcp-Session-Id header), so any number of clients can connect, reconnect, and terminate independently.

Conductor speaks both remote MCP transports, so connectors that only implement the legacy 2024-11-05 HTTP+SSE transport connect too: a GET /sse — or a GET /mcp with an SSE Accept and no Mcp-Session-Id — opens the old handshake (endpoint event, messages POSTed to /messages?sessionId=..., keepalive pings so free tunnels do not idle the stream out). Common URL mistakes stay routable: the bare tunnel origin / aliases /mcp, and a plain browser/curl GET on /, /mcp, or /.well-known/mcp.json returns a small server card describing the endpoints and auth mode (the card and /.well-known stay readable without credentials; everything else is gated). When no session is live, MCP endpoints answer 503 rather than 404, so clients report a temporarily unavailable server instead of a wrong URL.

Tunnel authentication

The tunnel gate supports three authentication methods, chosen in ctc setup (or /config tunnel-auth <method>) and reported in the server card's auth field:

| Method | How clients authenticate | | --- | --- | | bearer (default) | Clients send Authorization: Bearer <token>. Best where you paste a token or custom header by hand. Existing profiles keep working unchanged. | | url-token | The token rides in the query string, e.g. …/mcp?token=<token>, for clients that cannot set a custom Authorization header. The parameter name defaults to token (--tunnel-token-param). Note it can appear in proxy/access logs. | | oauth | The MCP-standard OAuth 2.1 + PKCE flow, built on the MCP SDK's authorization server. Conductor advertises /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource, supports dynamic client registration, and gates a browser consent page with a single owner password. Use this for connectors that auto-discover OAuth (e.g. ChatGPT and Claude). |

Bearer tokens and the OAuth owner password are generated fresh each /tunnel start and printed once, or sourced from an env:<NAME> reference (--tunnel-token-env, --tunnel-owner-password-env) for a stable secret across restarts. Secrets are never written into the profile — only the method and env references are.

Extra MCP servers

Conductor can aggregate additional third-party MCP servers (GitHub MCP, Playwright MCP, remote Streamable HTTP servers, …) behind the same model-facing endpoint. The primary coding-tools-mcp backend stays authoritative: its tools remain unprefixed, open_workspace, review checkpoints, baton files, and request_permissions bind to it exclusively, and a primary connection failure still fails startup. Extra servers are tools-only — each tool is exposed as <server>__<tool> (github__create_issue, playwright__browser_click) and calls route back to the owning server.

Configuration merges two places:

  • the workspace profile (~/.ctc/profiles/<repo-hash>.json) under an mcpServers record — personal, implicitly trusted;
  • a shareable <repo>/.ctc/mcp.json committed with the repository.
{
  "mcpServers": {
    "github":     { "command": "docker", "args": ["run", "-i", "--rm", "ghcr.io/github/github-mcp-server"],
                    "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "env:GITHUB_TOKEN" } },
    "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] },
    "remote":     { "url": "https://example.com/mcp", "headers": { "Authorization": "env:REMOTE_AUTH" } }
  }
}

Entries are stdio (command, args, env) or Streamable HTTP (url, headers), plus optional disabled and per-server allow/deny tool policies (unprefixed names). Server names must match [A-Za-z0-9_-]+ so prefixed tool names stay MCP-safe. env and headers values support env:<NAME> references, resolved at connect time — recommended over literals so .ctc/mcp.json never carries secrets. Extra stdio servers spawn with a minimal default environment plus the configured env only. On a name collision the profile entry replaces the workspace entry wholesale (personal over shared), and exposed tool names resolve conductor > primary > extras, with shadowed names reported per server.

Trust boundary. Workspace-declared servers are untrusted: a cloned repository could ship a malicious stdio command, so they start disabled (untrusted) until approved with /mcp trust <name> (records a fingerprint of the entry; if the repo later edits it, trust resets) or per-session with ctc start --trust-workspace-mcp. Profile-declared servers are trusted as your own configuration.

Failure semantics. Extra servers never block startup. A broken command or unreachable URL becomes a per-server error status with background reconnect (250 ms → 5 s backoff, 8 s connect timeout) while the session keeps serving. Conductor advertises tools.listChanged and broadcasts notifications/tools/list_changed when an extra server connects, drops, or is toggled, so clients pick up tool changes mid-session. Config files are read once at session start; edit them and open a new session, or use /mcp reconnect for connection-level retries.

In the TUI, /mcp opens a live status panel and /mcp enable|disable|reconnect|trust <name> manages servers (only trust writes the profile). ctc doctor adds one mcp:<name> check per configured server. Note for mixed versions: older ctc builds rewrite profiles through a stricter schema and drop the new mcpServers/trustedWorkspaceMcp fields on their next profile write.

ChatGPT Apps adapter

The ChatGPT Apps adapter is optional and isolated under src/adapters/chatgpt/. Core behavior does not depend on it, and it is disabled unless the workspace profile contains { "adapters": ["chatgpt"] } (or you pass --adapter chatgpt during setup).

When enabled, Conductor advertises MCP widget resources and adds ChatGPT Apps metadata to three high-value tools: open_workspace (a workspace/context guide card), show_changes (a review diff card), and baton_update_status (a baton progress card). It uses standard MCP Apps metadata (_meta.ui.resourceUri) plus ChatGPT compatibility aliases such as _meta["openai/outputTemplate"]. It is a host-specific presentation layer; model-facing tool names and core results stay unchanged.

Command reference

CLI commands

| Command | Description | | --- | --- | | ctc [path] | Open the TUI and start a session for the repo (defaults to the current directory). | | ctc start [path] | Start a headless conductor MCP session over stdio. | | ctc tui [session-id] | Observe an external ctc start session read-only and answer its permission prompts. | | ctc setup [path] | Configure a workspace profile (backend, default mode, tunnel, adapters, tool policy). | | ctc doctor [path] | Check the saved profile, backend, worktree storage, and git version. | | ctc ws list | List recorded ctc workspaces. | | ctc ws clean [--force] [--yes] | Clean recorded worktrees and prune closed session records. | | ctc ws merge <session-id> | Apply a worktree session's patch back to the source repository. | | ctc baton show [path] | Render .baton/plan.md, status.json, and report.md. | | ctc stats [--days N] [--json] | Show local telemetry: latency, reliability, usage, and merge metrics. | | ctc telemetry <status\|on\|off\|local\|reset\|endpoint\|sentry\|flush> | Inspect or change telemetry collection and upload. | | ctc --version | Print the ctc version. |

Run ctc <command> --help for the full option list of any command.

TUI commands

Type / in the TUI to open the command menu.

| Group | Command | Description | | --- | --- | --- | | Sessions | /new [path] [--worktree\|--direct] [--resume <wt>] | Replace the session: switch repo or isolation mode. | | Sessions | /close [--force] | Close the session; /new reopens one. | | Sessions | /merge | Merge worktree changes back into the source repo. | | Sessions | /clean [--force\|--yes] | Remove idle worktrees and prune closed session records. | | Review | /diff | Show the latest review checkpoint for this session. | | Review | /baton | Show the session baton plan, status, and report. | | Review | /approvals | List pending approvals for this session. | | Review | /stats [days] | Show local telemetry: latency, reliability, and merge stats. | | Configure | /mcp [status\|enable\|disable\|reconnect\|trust <name>] | Show and manage extra MCP servers for the session. | | Configure | /tunnel [start [bearer\|url-token\|oauth]\|stop\|status] | Manage the public MCP tunnel. | | Configure | /config [backend\|mode\|permission\|tunnel\|tunnel-auth\|reset] … | View or update the repo profile (reset deletes it). | | Configure | /doctor | Run profile, git, worktree, and backend checks. | | Interface | /help (/?) | Show TUI commands and key bindings. | | Interface | /inspect | Open the event inspector — raw JSON for recent events (Ctrl+O). | | Interface | /details | Reopen the latest error or long output, scrollable. | | Interface | /clear | Clear the transcript and start a fresh screen. | | Interface | /quit (/q) | Exit the TUI. |

Model-facing tools

Beyond the proxied backend tools (re-exposed unprefixed) and aggregated servers (<server>__<tool>), Conductor adds these tools of its own:

| Tool | Purpose | | --- | --- | | open_workspace | Open a direct workspace or an isolated worktree and return a project context guide. | | close_workspace | Close the active workspace; remove a managed worktree when clean (or with force). | | show_changes | Produce a review checkpoint diff against the session baseline / last-shown / HEAD. | | load_skill | Return the full SKILL.md content for a workspace skill. | | baton_write_plan / baton_read_plan | Write / read .baton/plan.md. | | baton_update_status | Write .baton/status.json with a timestamp. | | baton_write_report | Write .baton/report.md. |

Configuration

Profiles are stored as JSON under ~/.ctc/profiles/<repo-hash>.json and hold the backend mode, default workspace mode, tunnel settings, tool policy, adapter flags, and extra mcpServers. Create or edit one with ctc setup:

ctc setup /path/to/repo
ctc setup /path/to/repo --yes --skip-smoke --default-mode worktree
ctc doctor /path/to/repo
ctc doctor /path/to/repo --skip-backend

Secrets are never written into a profile: HTTP bearer tokens, tunnel tokens, and MCP server credentials are stored as env:<NAME> references (such as env:CTC_TOKEN) and resolved from the environment at connect time.

Runtime environment and shutdown

Backend PATH. Conductor resolves the user's login-shell PATH once per process (bash/zsh via $SHELL -ilc; fish and csh get their own probe; 5 s timeout, cached, CTC_RESOLVING_LOGIN_SHELL=1 set during the probe) and spawns the primary stdio backend with process.env plus that merged PATH. This keeps nvm/pyenv/asdf-selected toolchains working when the MCP host that launched ctc came from a GUI with a minimal PATH — the same approach VS Code uses. Existing custom PATH entries stay in front; login-shell entries are appended. Extra stdio MCP servers get the same widening. Set CTC_NO_LOGIN_SHELL_PATH=1 to disable the probe.

Request budgets. Control-plane calls (initialize, tools/list) time out after 5 minutes — generous enough to absorb a first-start Docker pull or PyPI download — and tool calls after 10 minutes. A timeout marks the backend disconnected and starts the reconnect loop instead of hanging the session. Override with CTC_BACKEND_CONTROL_TIMEOUT_MS / CTC_BACKEND_TOOL_TIMEOUT_MS.

Shutdown. ctc start exits when its host hangs up (stdin EOF, SIGINT, or SIGTERM) and tears the spawned lower backend down with it — stdin EOF first (clean MCP stdio shutdown; lets a docker run --rm -i backend stop and auto-remove), then SIGTERM, then SIGKILL after a 3 s grace. Quitting the TUI closes the hosted workspace and stops the runtime the same way, so no background coding-tools-mcp process outlives ctc.

Telemetry

ctc reports anonymous usage telemetry to its developers: per-tool latency histograms and success rates, session/approval/merge counters, and crash fingerprints (crashes go to Sentry). Events are structural metadata only — never file contents, paths, command text, or tool arguments. Release builds carry built-in destinations (unset in this repo, so a source build reports nothing); ctc telemetry off or DO_NOT_TRACK=1 opts out of all reporting.

Locally the model is upload-first: events are buffered under ~/.ctc/telemetry/ only until uploaded, then deleted (3-day cap while offline). ctc telemetry local on opts into a 30-day local copy so ctc stats [--days N] [--json] (or /stats in the TUI) can report offline. ctc telemetry status shows the destination and mode. See docs/telemetry.md for details and the wire schema.

Development

This is a closed-source beta published as a minified bundle. Build and test locally with the standard scripts:

npm install
npm run build      # bundle to dist/ with tsup
npm test           # vitest
npm run lint       # eslint
npm run typecheck  # tsc --noEmit

Release and packaging notes — including the sourcemap leak guard and the npm trusted-publishing flow — live in PUBLISHING.md.

Licensed under the terms in LICENSE.