{"_id":"@callmcp/driver-dograh","name":"@callmcp/driver-dograh","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@callmcp/driver-dograh","version":"0.1.0","description":"CallMCP driver for Dograh (github.com/dograh-hq/dograh) — a self-hostable, BYO-carrier voice-AI platform. Wraps Dograh's own REST API directly (not Dograh's MCP server) so a local, fully air-gapped Dograh instance can be driven through the CallMCP tool co","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"dependencies":{"@callmcp/driver-interface":"0.1.0"},"devDependencies":{"@types/node":"^20.14.0","typescript":"^5.6.3","vitest":"^2.1.4"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","dev":"tsc -p tsconfig.json --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc -p tsconfig.json --noEmit"},"_id":"@callmcp/driver-dograh@0.1.0","_integrity":"sha512-vLKdtidBXQS90LOwawuDfjgQWf8Ux9x1eZG/RLNV3WSTNUOC/Jy3WHhOYxVKK5GryIKxjRQTiX7T9htgVPEP7A==","_resolved":"C:\\Users\\cgall\\AppData\\Local\\Temp\\498f40ef8751b13fe0da2df0e4693189\\callmcp-driver-dograh-0.1.0.tgz","_from":"file:callmcp-driver-dograh-0.1.0.tgz","_nodeVersion":"20.18.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-vLKdtidBXQS90LOwawuDfjgQWf8Ux9x1eZG/RLNV3WSTNUOC/Jy3WHhOYxVKK5GryIKxjRQTiX7T9htgVPEP7A==","shasum":"7affb6cfca1213bbdda7814e0716a26ffc35f730","tarball":"https://registry.npmjs.org/@callmcp/driver-dograh/-/driver-dograh-0.1.0.tgz","fileCount":20,"unpackedSize":90192,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDRvY/PNDdqe866USQQB7r+29FFfK/6zJeOcvElxKDZ/wIgPfvfDO8+mofDCe2kHbbJv1y//W8Hi5R/Z5/rFTRd6ho="}]},"_npmUser":{"name":"kaicmo","email":"connor@kaicalls.com"},"directories":{},"maintainers":[{"name":"kaicmo","email":"connor@kaicalls.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/driver-dograh_0.1.0_1783643284445_0.015868899422176286"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-10T00:28:04.256Z","0.1.0":"2026-07-10T00:28:04.600Z","modified":"2026-07-10T00:28:04.853Z"},"maintainers":[{"name":"kaicmo","email":"connor@kaicalls.com"}],"description":"CallMCP driver for Dograh (github.com/dograh-hq/dograh) — a self-hostable, BYO-carrier voice-AI platform. Wraps Dograh's own REST API directly (not Dograh's MCP server) so a local, fully air-gapped Dograh instance can be driven through the CallMCP tool co","license":"MIT","readme":"# @callmcp/driver-dograh\n\nCallMCP driver for [Dograh](https://github.com/dograh-hq/dograh) — a\nself-hostable, BYO-carrier voice-AI platform. This is the driver you want\nwhen the goal is **zero cloud telephony accounts**: run Dograh on your own\nmachine (or your own server), point this driver at it, and place an\napproved call without ever creating a Twilio, Vapi, or Retell account.\n\nThis package wraps Dograh's own REST API directly. It does **not** wrap or\nre-export Dograh's own MCP server (`docs.dograh.com/integrations/mcp`) —\nDograh ships that itself, and treating it as a dependency here would put\nthis driver at the mercy of a direct competitor's roadmap. See\n`workspace/research/r4-local-stacks.md` §10 in the CallMCP research corpus\nfor the full reasoning.\n\nThe normative reference for the tool contract this driver implements is\n[`SPEC.md`](../../SPEC.md) at the repo root. If this README and `SPEC.md`\never disagree about a universal field's meaning, `SPEC.md` wins.\n\n## What this driver can and can't do\n\nDograh's real capability, honestly stated (SPEC §7 \"degradation appendix\"\nphilosophy — no smoothing over gaps):\n\n| Tool | Supported? | Why |\n|---|---|---|\n| `make_call` | Yes | `POST /telephony/initiate-call`, scoped to a `workflow_id` |\n| `get_call_status` | Yes | Polls `GET /{workflow_id}/runs/{run_id}` |\n| `get_transcript` | Yes (baseline, **not realtime**) | Same poll endpoint returns `transcript_url`; this driver fetches it |\n| `get_recording` | Yes | Read from the run's `artifacts[]` (matched by `artifact_type`) |\n| `configure_number` | Yes | `PUT /api/v1/workflow/{workflow_id}` — **attaches** a number you already own |\n| `list_numbers` | Yes | Derived from each known workflow's telephony config |\n| `list_calls` | Yes | Aggregated from `GET /{workflow_id}/runs` across known workflows |\n| `end_call` | **No** | Dograh has no external hangup endpoint at all |\n| `send_sms` | **No** | Dograh has no SMS capability at all |\n| `search_numbers` | **No** | Dograh is strictly BYO-carrier — no number marketplace to search |\n| `buy_number` | **No** | No purchase endpoint exists anywhere in Dograh's API |\n\n`end_call`/`buy_number`/`search_numbers`/`send_sms` are real, permanent gaps\nin Dograh itself — not \"not implemented yet\" on this driver's side. They're\nimplemented here as methods that throw `UNSUPPORTED_CAPABILITY` (SPEC §5.1)\nrather than left `undefined`, so a stale `tools/list` cache still fails\nloudly and correctly; the manifest (`supports_*: false`) is what keeps them\nout of `tools/list` in the first place. Full detail, with upstream tracking\nlinks, lives in `callmcp.manifest.json`'s `known_degradations` and in the\ndoc comments at the top of `src/client.ts` and `src/driver.ts`.\n\n**A note on what's verified vs. inferred.** `POST /telephony/initiate-call`\nand `GET /{workflow_id}/runs/{run_id}` (returning `transcript_url`) were\nconfirmed by reading dograh-hq/dograh's actual route source. The\nnumber-attachment surface (`PUT /api/v1/workflow/{workflow_id}` and its\nGET/collection counterparts) is a reasonable, but **not independently\nsource-verified**, REST convention this driver assumes. If your Dograh\ninstance's real routes differ, check `{DOGRAH_BASE_URL}/docs` (FastAPI's\nauto-generated OpenAPI UI) and adjust `src/client.ts` — see the provenance\ncomment at the top of that file for exactly which routes fall into which\nbucket.\n\n## Configuration\n\n| Env var | Required | Meaning |\n|---|---|---|\n| `DOGRAH_BASE_URL` | Yes | Base URL of your Dograh instance, e.g. `http://localhost:8081` |\n| `DOGRAH_API_KEY` | No | Bearer token, if your instance requires auth. Dograh's default docker-compose quickstart runs with no auth. |\n| `DOGRAH_DEFAULT_WORKFLOW_ID` | Recommended | `workflow_id` used when a call doesn't specify one explicitly (see below) |\n| `DOGRAH_WORKFLOW_IDS` | Optional | Comma-separated `workflow_id` list this driver aggregates across for `list_numbers`/`list_calls`. Falls back to `[DOGRAH_DEFAULT_WORKFLOW_ID]`, then to Dograh's workflow-listing endpoint, if unset. |\n\nEvery CallMCP call is scoped to a Dograh **workflow** — there's no\nbackend-agnostic \"just call this number\" primitive in Dograh, calls are\nalways \"run this workflow against this number.\" This driver resolves the\nworkflow to use, in priority order:\n\n1. `agent_config_ref` on the tool call (`make_call`'s/`configure_number`'s\n   opaque agent-config reference — this *is* the Dograh `workflow_id`)\n2. `options.dograh.workflow_id` (driver-specific passthrough, SPEC §1.0)\n3. `DOGRAH_DEFAULT_WORKFLOW_ID`\n\nIf none of those resolve, `make_call`/`configure_number` fail with a\n`DRIVER_ERROR` explaining exactly what's missing — this driver never\nsilently guesses a workflow.\n\n## Local quickstart: zero cloud telephony accounts\n\nTwo paths, depending on how air-gapped you want to go.\n\n### Path A — Twilio-under-Dograh (fastest to a real call)\n\nYou still need *a* carrier account to actually dial the PSTN — Dograh\ndoesn't eliminate the need for SIP trunking, it eliminates the need for a\n**voice-AI platform account** (no Vapi, no Retell, no per-minute platform\nmarkup). This path uses Twilio purely as the SIP/PSTN leg underneath a\nDograh instance that runs entirely on your own machine.\n\n```bash\n# 1. Bring up Dograh locally\ncurl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml\n./start_docker.sh\n# Dograh is now on http://localhost:3010 (UI) / http://localhost:8081 (API) by default —\n# confirm the actual API port against your compose file/instance.\n\n# 2. In the Dograh UI: create a workflow, wire in your Twilio account SID/\n#    auth token as the telephony provider, and note the workflow's ID.\n\n# 3. Point this driver at your local instance\nexport DOGRAH_BASE_URL=\"http://localhost:8081\"\nexport DOGRAH_DEFAULT_WORKFLOW_ID=\"wf_your_workflow_id\"\n# export DOGRAH_API_KEY=\"...\"   # only if your instance requires it\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"callmcp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@callmcp/server\"],\n      \"env\": {\n        \"CALLMCP_DEFAULT_DRIVER\": \"dograh\",\n        \"DOGRAH_BASE_URL\": \"http://localhost:8081\",\n        \"DOGRAH_DEFAULT_WORKFLOW_ID\": \"wf_your_workflow_id\"\n      }\n    }\n  }\n}\n```\n\nWith that config, `make_call({ to: \"+1...\" })` places a real outbound call:\nDograh's workflow logic + LLM run entirely on your machine, and only the\nSIP/PSTN leg touches Twilio's infrastructure. No calls, recordings, or\ntranscripts ever leave your boundary except the raw audio Twilio has to\ncarry to reach the PSTN.\n\n### Path B — Asterisk/ARI, fully air-gapped (zero commercial telephony vendor)\n\nDograh's Asterisk ARI integration (`/telephony/ws/ari`) is a direct path to\nself-hosted SIP/PSTN with **no commercial telephony vendor at all** — the\ngenuinely air-gapped option, useful for testing against a local SIP\ntrunk/PBX or a VoIP gateway you already control, with \"no calls, recordings,\ntranscripts, or model inference ever leave your boundary\" (Dograh's own\nframing).\n\n```bash\n# 1. Stand up a local Asterisk instance with ARI enabled (outside the scope\n#    of this README — see asterisk.org's ARI documentation). At minimum you\n#    need ARI credentials and a SIP trunk/extension Asterisk can dial out\n#    through, e.g. a local VoIP gateway or a SIP trunk provider that doesn't\n#    require a \"voice-AI platform\" account (this is a pure SIP trunk, not a\n#    Vapi/Retell-style integration).\n\n# 2. Bring up Dograh locally (same as Path A, step 1)\ncurl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml\n./start_docker.sh\n\n# 3. In the Dograh UI: create a workflow, select Asterisk/ARI as the\n#    telephony provider, and point it at your local Asterisk instance's ARI\n#    endpoint + credentials. Note the workflow's ID.\n\n# 4. Point this driver at your local instance, same as Path A\nexport DOGRAH_BASE_URL=\"http://localhost:8081\"\nexport DOGRAH_DEFAULT_WORKFLOW_ID=\"wf_your_ari_workflow_id\"\n```\n\nSame `claude-desktop` config as Path A — the driver doesn't know or care\nwhether the workflow underneath is Twilio- or Asterisk-backed, that's\nentirely a Dograh-side configuration choice. This is the path to prove out\n\"local voice-AI driver, approved call, zero cloud telephony accounts\" in\nthe strictest sense: if your Asterisk box's trunk is itself a local\nsoftphone-to-softphone loop or an on-prem PBX, nothing in this call ever\nleaves hardware you control.\n\nSee [`examples/claude-desktop-local-dograh.json`](../../examples/claude-desktop-local-dograh.json)\nat the repo root for a ready-to-copy MCP client config.\n\n## Using it programmatically\n\n```ts\nimport { DograhDriver } from \"@callmcp/driver-dograh\";\n\nconst driver = new DograhDriver(); // reads DOGRAH_BASE_URL / DOGRAH_API_KEY / DOGRAH_DEFAULT_WORKFLOW_ID from env\n\nconst call = await driver.makeCall({\n  to: \"+14155551234\",\n  agent_config_ref: \"wf_your_workflow_id\", // overrides DOGRAH_DEFAULT_WORKFLOW_ID for this call\n  approval_id: \"a_...\", // supplied by the server core's approval gate, SPEC §3\n});\n\nconst status = await driver.getCallStatus({ call_id: call.call_id });\nconst transcript = await driver.getTranscript({ call_id: call.call_id });\n```\n\n`call_id` here is a driver-internal composite (`\"<workflow_id>::<run_id>\"`)\n— treat it as opaque. Dograh scopes a run's lifecycle to its parent\nworkflow (`GET /{workflow_id}/runs/{run_id}`), and CallMCP's `call_id` is a\nsingle opaque string, so this driver encodes both into one value rather\nthan requiring a server-side call registry.\n\n## Development\n\n```bash\npnpm install\npnpm --filter @callmcp/driver-dograh run typecheck\npnpm --filter @callmcp/driver-dograh run build\npnpm --filter @callmcp/driver-dograh run test\n```\n\n`test/driver.test.ts` mocks HTTP entirely (no live Dograh instance\nrequired) and also runs `@callmcp/driver-interface`'s `runConformanceSuite`\nagainst this driver + its manifest, so a manifest/implementation drift\n(claiming a capability the code doesn't back, or vice versa) fails CI\nrather than surfacing as a runtime surprise for a client.\n","readmeFilename":"README.md","_rev":"1-b140ea7bf4cfbc02e3b5cae84e9a7bcc"}