{"id":49215789,"url":"https://github.com/walkindude/cli-bridge","last_synced_at":"2026-04-24T00:01:13.464Z","repository":{"id":353439968,"uuid":"1195644080","full_name":"walkindude/cli-bridge","owner":"walkindude","description":"Turn any CLI into an MCP tool that agents actually use.","archived":false,"fork":false,"pushed_at":"2026-04-23T23:06:36.000Z","size":210,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-23T23:33:06.172Z","etag":null,"topics":["agentic","ai-agents","anthropic","claude","claude-code","cli","developer-tools","mcp","mcp-server","model-context-protocol","plugin","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/walkindude.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-29T23:00:48.000Z","updated_at":"2026-04-23T23:06:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/walkindude/cli-bridge","commit_stats":null,"previous_names":["walkindude/cli-bridge"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/walkindude/cli-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walkindude%2Fcli-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walkindude%2Fcli-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walkindude%2Fcli-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walkindude%2Fcli-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/walkindude","download_url":"https://codeload.github.com/walkindude/cli-bridge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walkindude%2Fcli-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32203362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T20:19:26.138Z","status":"ssl_error","status_checked_at":"2026-04-23T20:19:23.520Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic","ai-agents","anthropic","claude","claude-code","cli","developer-tools","mcp","mcp-server","model-context-protocol","plugin","typescript"],"created_at":"2026-04-24T00:00:55.780Z","updated_at":"2026-04-24T00:01:13.458Z","avatar_url":"https://github.com/walkindude.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cli-bridge\n\n[![npm version](https://img.shields.io/npm/v/cli-bridge.svg)](https://www.npmjs.com/package/cli-bridge)\n[![CI](https://github.com/walkindude/cli-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/walkindude/cli-bridge/actions/workflows/ci.yml)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5+-3178C6?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![MCP](https://img.shields.io/badge/MCP-compatible-8A2BE2)](https://modelcontextprotocol.io)\n\nTurn any CLI into an MCP tool that agents actually use.\n\n## The problem\n\nYou built a CLI that does something useful. Maybe it queries a database, lints code, or manages infrastructure. You tell the agent about it in CLAUDE.md or your system prompt. It works for a while, then the agent quietly goes back to `grep` and `Bash`.\n\nThis happens because text instructions sit in the context window, and context is a lossy channel. When the conversation gets long or the task gets complex, the agent forgets your tool exists. It falls back to what it knows: shell commands.\n\nMCP tools don't have this problem. They live outside the context window, in the tool registry. The agent sees them every time it decides which tool to call, regardless of how long the conversation is or how much pressure the context is under.\n\n## What cli-bridge does\n\ncli-bridge lets you describe your CLI's interface in a JSON spec file. On startup, it reads the spec and registers each subcommand as a real MCP tool. The agent sees `tool_foo` and `tool_bar` in its tool list, not buried in a CLAUDE.md paragraph it might skip.\n\nWhen the agent calls one of these tools, cli-bridge runs your binary via `execFile` (no shell), parses the output according to the spec, and returns structured content. Your CLI stays a CLI. It just also happens to be an MCP tool now.\n\nThis works with Claude Code, Codex, and anything else that speaks MCP.\n\n## Install\n\n### From the marketplace (Claude Code)\n\n```\n/plugin marketplace add walkindude/cli-bridge\n/plugin install cli-bridge@cli-bridge\n```\n\n### From npm (or any compatible package manager)\n\n```bash\nnpm install -g cli-bridge\n# or\npnpm add -g cli-bridge\n# or\nyarn global add cli-bridge\n# or\nbun add -g cli-bridge\n```\n\n### With mise\n\n```bash\nmise use -g npm:cli-bridge@latest\n```\n\n### With Nix (flakes)\n\n```bash\nnix profile install github:walkindude/cli-bridge\n# or for a one-off:\nnix run github:walkindude/cli-bridge\n# or drop into a dev shell with node + pnpm:\nnix develop github:walkindude/cli-bridge\n```\n\n### Configure the MCP client\n\nThen add to your project's `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"cli-bridge\": {\n      \"type\": \"stdio\",\n      \"command\": \"cli-bridge\"\n    }\n  }\n}\n```\n\n### For Codex\n\nAdd to `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.cli-bridge]\ncommand = \"cli-bridge\"\n```\n\n### From source\n\n```bash\ngit clone https://github.com/walkindude/cli-bridge\ncd cli-bridge\npnpm install \u0026\u0026 pnpm run build\nnpm link\n```\n\n## Register a tool\n\n```\n/cli-bridge:register \u003cbinary\u003e\n```\n\nTwo paths, tried in order:\n\n**Canonical path (preferred).** If the tool exposes a `\u003cbinary\u003e cli-bridge-manifest` subcommand, the skill uses its output verbatim. The tool owns its own spec — zero drift, always in lockstep with the installed binary. This is the convention for CLI authors who want first-class cli-bridge support: [gosymdb](https://github.com/walkindude/gosymdb) is the reference implementation.\n\n**Heuristic fallback.** If the tool doesn't expose a manifest, the skill scrapes `--help` output to synthesize a spec. Lower quality — you'll probably want to hand-tune the triggers.\n\nSpecs land at `~/.config/cli-bridge/specs/\u003ctool\u003e/\u003cversion\u003e.json`. See [Spec Format](#spec-format) below.\n\n## How it works\n\n1. On startup, the MCP server discovers specs from three locations (highest priority first):\n   - `.cli-bridge/specs/` in the current project (team-shared)\n   - `~/.config/cli-bridge/specs/` (user-local, `XDG_CONFIG_HOME` respected)\n   - `specs/` in the plugin directory (bundled, empty by default)\n\n2. For each spec, it resolves the binary via `which`, detects the installed version, and picks the best-matching spec file.\n\n3. Each command in the spec becomes an MCP tool named `{tool}_{command}` (e.g. `tool_foo`, `tool_bar`).\n\n4. When Claude calls a tool, cli-bridge runs the binary via `execFile` (no shell), parses stdout according to the spec's output format, and returns structured MCP content.\n\n## Spec format\n\nSpecs live at `~/.config/cli-bridge/specs/\u003ctool\u003e/\u003cversion\u003e.json`.\n\n```json\n{\n  \"name\": \"jq\",\n  \"specVersion\": \"1\",\n  \"binary\": \"jq\",\n  \"binaryVersion\": \"1.7.1\",\n  \"description\": \"Command-line JSON processor\",\n  \"versionDetection\": {\n    \"command\": \"--version\",\n    \"pattern\": \"jq-(\\\\d+\\\\.\\\\d+[.\\\\d+]*)\"\n  },\n  \"triggers\": {\n    \"positive\": [\"BEFORE processing or filtering JSON data\"],\n    \"negative\": [\"Do NOT use for non-JSON formats\"]\n  },\n  \"commands\": [\n    {\n      \"name\": \"run\",\n      \"description\": \"Apply a jq filter to JSON input\",\n      \"usage\": \"jq \u003cfilter\u003e [file]\",\n      \"args\": [\n        { \"name\": \"filter\", \"description\": \"jq filter expression\", \"required\": true, \"type\": \"string\" }\n      ],\n      \"flags\": [\n        { \"name\": \"raw-output\", \"short\": \"r\", \"description\": \"Output raw strings\", \"required\": false, \"type\": \"boolean\" }\n      ],\n      \"output\": { \"format\": \"json\" }\n    }\n  ]\n}\n```\n\nKey fields:\n\n| Field | Purpose |\n|-------|---------|\n| `triggers.positive` | When the model SHOULD consider this tool |\n| `triggers.negative` | When the model should NOT use this tool |\n| `output.format` | How to parse stdout: `json`, `jsonl`, `text`, `csv`, `tsv` |\n| `versionDetection` | How to detect the installed binary version on startup |\n| `globalFlags` | Flags available on every command |\n\nTeams can share specs by checking them into `.cli-bridge/specs/` in their repo. Project-level specs take priority over user-level specs.\n\n## Security model\n\ncli-bridge executes real binaries on your machine. A spec is effectively a shortcut to running a CLI command. Loading a spec grants the same permissions as running the binary directly.\n\n**Spec sources and trust:**\n\n| Source | Trust level | Who controls it |\n|--------|------------|-----------------|\n| `.cli-bridge/specs/` in repo | Same as cloning the repo | Repo maintainers |\n| `~/.config/cli-bridge/specs/` | User-controlled | You |\n| `specs/` in plugin dir | Bundled with cli-bridge | cli-bridge maintainers |\n\nProject-local specs (`.cli-bridge/specs/`) load automatically when you open a project, the same trust model as `Makefile`, `.vscode/tasks.json`, or `package.json` scripts. **Review specs from untrusted repos before use.**\n\n**Execution safety:**\n- All commands run via `execFile` (no shell), no metacharacter expansion\n- Output is capped at 10 MB per invocation\n- Timeouts enforced (default 30s, max 5 min)\n- Trigger phrases are length-limited to prevent prompt injection via tool descriptions\n\n## Development\n\n```bash\npnpm run build          # compile + bundle\npnpm test               # vitest\npnpm run test:coverage  # coverage report\npnpm run lint           # eslint\npnpm run typecheck      # tsc --noEmit\npnpm run format         # prettier --write\npnpm run format:check   # prettier --check\n```\n\n## Architecture\n\n| Module | Purpose |\n|--------|---------|\n| `src/server.ts` | MCP stdio server. Loads specs, registers tools, handles calls |\n| `src/registry.ts` | Spec discovery, version resolution, MCP tool generation |\n| `src/executor.ts` | Runs CLI via `execFile`. No shell. Timeout enforcement |\n| `src/schema.ts` | `CliToolSpec` types + JSON Schema + `validateSpec()` |\n| `src/parser.ts` | Parses stdout (json/text/csv/tsv/jsonl) into MCP content |\n| `src/resolver.ts` | Binary resolution (`which`), version detection, semver matching |\n| `src/paths.ts` | Spec directory resolution with XDG support |\n| `src/types.ts` | `Result\u003cT,E\u003e`, error types |\n\n## Versioning\n\nReleases are cut via git tags (`v0.1.0`, `v0.2.0`, etc.). Pushing a tag triggers a GitHub Release with auto-generated release notes.\n\nPlugin updates: bump the `version` field in `.claude-plugin/plugin.json` and `package.json`. Users on the marketplace will pick up the new version on next session start (if auto-update is enabled) or via `/plugin update`.\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalkindude%2Fcli-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwalkindude%2Fcli-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalkindude%2Fcli-bridge/lists"}