{"id":"ec4737a0-d053-430b-aaa3-a7bb23a1f3bb","slug":"appcrane-mcp","kind":"mcp","name":"appcrane-mcp","summary":"Standalone MCP connector for AppCrane: exposes its 62 deploy and ops tools to any MCP client, proxied to your own self-hosted AppCrane.","owner":"gitayg","repoUrl":"https://github.com/gitayg/appcrane-mcp","license":"MIT","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-07-04T00:20:24.000Z","addedAt":"2026-10-14T05:37:06.181Z","logoUrl":"https://avatars.githubusercontent.com/u/109329461?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra","memory-knowledge"],"tags":["ai-agents","claude","deployment","devops","self-hosted","appcrane","heroku-alternative","paas"],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-17T15:54:47.573Z","sample":false,"url":"https://conduits.dev/tools/appcrane-mcp","language":"JavaScript","transports":["stdio"],"install":{"npm":"appcrane-mcp"},"requirements":{"env":[{"name":"APPCRANE_URL","secret":false,"required":false,"description":"Base URL of your own AppCrane instance, e.g. https://crane.example.com. Without it the connector still starts and answers tools/list from the bundled catalog, but cannot execute tools."},{"name":"APPCRANE_KEY","secret":true,"required":false,"description":"Your AppCrane API key, sent to the instance as the X-API-Key header. Required to execute tools."},{"name":"APPCRANE_GITHUB_TOKEN","secret":true,"required":false,"description":"Optional GitHub personal access token, sent as X-Github-Token, to unlock the github_* passthrough tools."}],"upstreamMayCharge":false},"tools":null,"readme":"# appcrane-mcp\n\nThe standalone MCP connector for **[AppCrane](https://glick.run/appcrane.html)** — the self-hosted deployment platform for AI-built, agent-deployed apps.\n\nAppCrane exposes an MCP server at `<instance>/api/mcp` that requires an `X-API-Key`. This package is a thin **stdio** MCP server that:\n\n1. Serves the full `appcrane_*` tool catalog for **`tools/list` introspection with zero configuration** — it ships a bundled `catalog.json`, so registries and sandboxes (e.g. Glama) can start it in a container and introspect it offline.\n2. **Proxies real `tools/call`** to your own AppCrane instance once `APPCRANE_URL` and `APPCRANE_KEY` are set.\n\nIt runs anywhere Node 20+ is available, via `npx appcrane-mcp`.\n\n> **Licensing:** this connector is **MIT**. The AppCrane platform it talks to is a separate\n> project and is **AGPL-3.0**. Installing this package does not pull the platform in — the\n> connector is a client that talks to an AppCrane instance you host yourself.\n\n## How you connect\n\nThere is no hosted service and no AppCrane account. The flow is entirely your own:\n\n1. You self-host AppCrane (AGPL) somewhere you control.\n2. You issue an API key from that instance.\n3. Your agent runs this connector locally over **stdio** (`npx -y appcrane-mcp`).\n4. The connector forwards each `tools/call` to `${APPCRANE_URL}/api/mcp` with your\n   `X-API-Key`. Your key stays in your own MCP client config; it is never sent anywhere\n   except the instance URL you set.\n\n## Install / run\n\n```bash\nnpx appcrane-mcp\n```\n\nWith no environment variables it still starts and answers `tools/list` from the bundled catalog (57 tools). To actually invoke tools against your instance, set:\n\n| Env var | Required | Description |\n| --- | --- | --- |\n| `APPCRANE_URL` | for calls | Your instance base URL, e.g. `https://crane.example.com` |\n| `APPCRANE_KEY` | for calls | Your AppCrane API key (sent as `X-API-Key`) |\n| `APPCRANE_GITHUB_TOKEN` | optional | A GitHub PAT (sent as `X-Github-Token`) to unlock the `github_*` passthrough tools |\n\n## MCP client configuration\n\nThis is a **stdio** command server (not an HTTP endpoint). Add it to your MCP client config like this:\n\n```json\n{\n  \"mcpServers\": {\n    \"appcrane\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"appcrane-mcp\"],\n      \"env\": {\n        \"APPCRANE_URL\": \"https://crane.example.com\",\n        \"APPCRANE_KEY\": \"your_api_key\",\n        \"APPCRANE_GITHUB_TOKEN\": \"ghp_optional_for_github_passthrough\"\n      }\n    }\n  }\n}\n```\n\nClaude Code CLI:\n\n```bash\nclaude mcp add appcrane \\\n  --env APPCRANE_URL=https://crane.example.com \\\n  --env APPCRANE_KEY=your_api_key \\\n  -- npx -y appcrane-mcp\n```\n\n## How it works\n\n- **`tools/list`**\n  - If `APPCRANE_URL` + `APPCRANE_KEY` are set → connects to `${APPCRANE_URL}/api/mcp` (StreamableHTTP, header `X-API-Key`, plus `X-Github-Token` when the GitHub token is set), fetches the **live, auth-filtered** tool list, and returns it. If the instance is unreachable it falls back to the bundled catalog.\n  - If not configured → returns the **bundled static catalog** (`catalog.json`). This path needs no env vars, which is what a registry's introspection sandbox hits.\n- **`tools/call`** → requires `APPCRANE_URL` + `APPCRANE_KEY`; forwards the call to the backend and returns its result. Without configuration it returns a clear \"not configured\" error.\n\n## Docker\n\n```bash\ndocker build -t appcrane-mcp .\n\n# Introspection only (no config) — starts and serves tools/list:\ndocker run -i --rm appcrane-mcp\n\n# Full use:\ndocker run -i --rm \\\n  -e APPCRANE_URL=https://crane.example.com \\\n  -e APPCRANE_KEY=your_api_key \\\n  appcrane-mcp\n```\n\n## Development\n\n```bash\nnpm install\nnpm run build          # tsc -> dist/\nnpm run gen:catalog    # regenerate catalog.json from the AppCrane platform source\nnpm run check:catalog  # fail if catalog.json has drifted from that source\nnode scripts/test-list.mjs   # smoke test: spawn over stdio, assert tools/list\n```\n\nBoth catalog scripts import the platform's own `getToolCatalog()` from a sibling\n`deployhub` checkout; set `APPCRANE_SRC` to point at its `server/services/mcpTools.js`\nif yours lives elsewhere.\n\n### Releasing\n\nBump `version` in `package.json`, commit, then push a matching tag:\n\n```bash\ngit tag v1.5.3 && git push origin v1.5.3\n```\n\n`.github/workflows/publish.yml` publishes it to npm with **npm Trusted Publishing**: no npm\ntoken and no one-time password, and npm attaches provenance (the commit it was built from).\nThe workflow refuses a tag that does not match `package.json`, and checks the catalog against\nthe platform's current `main` before publishing, so a stale `catalog.json` cannot ship. (It\nhas rotted silently before: 22 tools behind the platform, 35 advertised against 57 real.)\nRun `npm run check:catalog` locally first to find out before CI does.\n\nThe same tag then lists the version in the official [MCP Registry](https://registry.modelcontextprotocol.io)\nas `io.github.gitayg/appcrane`, also by OIDC. Bump `version` and `packages[0].version` in\n`server.json` together with `package.json`: the workflow refuses a tag that does not match all three.\n(The listing sat at 1.0.0 while npm moved on, until this was automated.)\n\nThe bundled `catalog.json` is generated from the real tool definitions in the AppCrane platform (`deployhub/server/services/mcpTools.js`) and reflects the AWS-aligned tool vocabulary (`appcrane_set_secret`, `appcrane_get_secret`, `appcrane_cp`, and the `stage` parameter). It is committed so the package ships self-contained.\n\n## About AppCrane\n\nAppCrane is a self-hosted home for AI-built and AI-deployed apps. This connector is MIT-licensed to maximize adoption; the platform itself is AGPL.\n\n- This connector (MIT): https://github.com/gitayg/appcrane-mcp\n- Platform (AGPL-3.0): https://github.com/gitayg/appCrane\n- Product page: https://glick.run/appcrane.html\n"}