feat: refactor node spec and add mcp tools (#244)

* refactor: carve out extraction panel

* refactor: create spec versions for node types

* refactor: create a GenericNode and remove custom nodes

* feat: add python and typescript sdk

* add dograh sdk

* fix: fetch draft workflow definition over published one

* fix: fix routes of SDKs to use code gen

* chore: remove doclink dependency to reduce image size

* chore: format files

* chore: bump pipecat

* feat: let mcp fetch archived workflows on demand

* chore: fix tests

* feat: add sdk documentation

* chore: change banner and add badge
This commit is contained in:
Abhishek 2026-04-21 07:56:16 +05:30 committed by GitHub
parent 0a61ef295f
commit 00a1a22b74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
162 changed files with 14355 additions and 3554 deletions

View file

@ -0,0 +1,111 @@
---
title: "Build an agent"
description: "Assemble a Dograh voice agent programmatically with the SDK and save it as a draft"
---
The SDK mirrors the node-and-edge model of the [Voice Agent Builder](/voice-agent/introduction). You create a `Workflow`, add nodes (`startCall`, `agentNode`, `endCall`, …) with `add()`, connect them with `edge()`, and persist the result via `save_workflow`.
## Prerequisites
- A Dograh [API key](/configurations/api-keys) exported as `DOGRAH_API_KEY`
- An existing agent ID to save drafts against (create one in the Dograh UI or via [`POST /api/v1/workflow/create`](/api-reference/agents/create-from-template))
## Build and save
The example below builds a three-node loan-qualification agent and saves it as a **new draft version** on an existing agent. Your published agent keeps serving calls until you explicitly publish the draft.
<CodeGroup>
```python Python
from dograh_sdk import DograhClient, Workflow
with DograhClient(api_key="YOUR_API_KEY") as client:
wf = Workflow(client=client, name="loan_qualification")
greeting = wf.add(
type="startCall",
name="greeting",
prompt="You are Sarah from Acme Loans. Greet the caller warmly.",
)
qualify = wf.add(
type="agentNode",
name="qualify",
prompt="Ask about loan amount, purpose, and monthly income.",
)
done = wf.add(
type="endCall",
name="done",
prompt="Thank them and end the call politely.",
)
wf.edge(greeting, qualify, label="interested", condition="Caller wants to continue.")
wf.edge(qualify, done, label="done", condition="All qualification questions answered.")
client.save_workflow(workflow_id=123, workflow=wf)
```
```typescript TypeScript
import { DograhClient, Workflow } from "@dograh/sdk";
const client = new DograhClient({ apiKey: "YOUR_API_KEY" });
const wf = new Workflow({ client, name: "loan_qualification" });
const greeting = await wf.add({
type: "startCall",
name: "greeting",
prompt: "You are Sarah from Acme Loans. Greet the caller warmly.",
});
const qualify = await wf.add({
type: "agentNode",
name: "qualify",
prompt: "Ask about loan amount, purpose, and monthly income.",
});
const done = await wf.add({
type: "endCall",
name: "done",
prompt: "Thank them and end the call politely.",
});
wf.edge(greeting, qualify, { label: "interested", condition: "Caller wants to continue." });
wf.edge(qualify, done, { label: "done", condition: "All qualification questions answered." });
await client.saveWorkflow(123, wf);
```
</CodeGroup>
## Edit an existing agent
Load an agent into an editable `Workflow`, mutate it, then save:
<CodeGroup>
```python Python
wf = client.load_workflow(workflow_id=123)
wf.name = "loan_qualification_v2"
client.save_workflow(workflow_id=123, workflow=wf)
```
```typescript TypeScript
const wf = await client.loadWorkflow(123);
wf.name = "loan_qualification_v2";
await client.saveWorkflow(123, wf);
```
</CodeGroup>
## Discover node types
Each node's `type` string and required fields come from the backend's node-spec catalog. Fetch it at runtime to validate what you can build:
<CodeGroup>
```python Python
types = client.list_node_types()
for spec in types.node_types:
print(spec.name, [p.name for p in spec.properties])
```
```typescript TypeScript
const types = await client.listNodeTypes();
for (const spec of types.node_types) {
console.log(spec.name, spec.properties.map(p => p.name));
}
```
</CodeGroup>
<Note>
For a full description of each node type and its fields, see the [Nodes](/voice-agent/start-call) section of the Voice Agent Builder docs.
</Note>

View file

@ -0,0 +1,75 @@
---
title: "Introduction"
description: "Build and operate Dograh voice AI agents programmatically from Python or TypeScript"
---
Dograh ships official SDKs for **Python** and **TypeScript** that wrap the Dograh REST API and the workflow builder. Use them to create or edit agents, place outbound calls, and inspect runs from your own code.
- **Python** — [`dograh-sdk`](https://pypi.org/project/dograh-sdk/) on PyPI
- **TypeScript** — [`@dograh/sdk`](https://www.npmjs.com/package/@dograh/sdk) on npm
Both packages are generated from the same backend OpenAPI spec, so the method surface is equivalent — only the naming convention differs (`snake_case` in Python, `camelCase` in TypeScript).
## Install
<CodeGroup>
```bash Python
pip install dograh-sdk
```
```bash TypeScript
npm install @dograh/sdk
```
</CodeGroup>
## Authenticate
Generate an API key at [`/api-keys`](https://app.dograh.com/api-keys) (or `http://localhost:3010/api-keys` for self-hosted). See [API Keys](/configurations/api-keys) for details.
Both SDKs read the API key from the `DOGRAH_API_KEY` environment variable by default, and the base URL from `DOGRAH_API_URL` (defaults to `http://localhost:8000`). You can also pass them explicitly.
<CodeGroup>
```python Python
from dograh_sdk import DograhClient
client = DograhClient(
base_url="https://app.dograh.com",
api_key="YOUR_API_KEY",
)
```
```typescript TypeScript
import { DograhClient } from "@dograh/sdk";
const client = new DograhClient({
baseUrl: "https://app.dograh.com",
apiKey: "YOUR_API_KEY",
});
```
</CodeGroup>
<Note>
For self-hosted deployments, swap `baseUrl` for your backend URL (e.g. `http://localhost:8000`).
</Note>
## Quick tour
List the agents in your workspace:
<CodeGroup>
```python Python
workflows = client.list_workflows()
for wf in workflows:
print(wf.id, wf.name)
```
```typescript TypeScript
const workflows = await client.listWorkflows();
for (const wf of workflows) {
console.log(wf.id, wf.name);
}
```
</CodeGroup>
## Next steps
- [Build an agent](/sdks/build-an-agent) — assemble nodes and edges, save as a draft
- [Place an outbound call](/sdks/outbound-calls) — trigger a call from an agent to a phone number
- [MCP Server](/integrations/mcp) — let Claude and other coding agents drive the SDK for you

View file

@ -0,0 +1,49 @@
---
title: "Place an outbound call"
description: "Trigger a Dograh voice agent to call a phone number from the SDK"
---
Use the SDK to place a test outbound call from a specific agent to a phone number. This is the same endpoint used by the **Test Call** button in the Dograh UI.
## Prerequisites
- A Dograh [API key](/configurations/api-keys) exported as `DOGRAH_API_KEY`
- A published agent (you need the agent ID)
- A configured telephony provider — see [Telephony](/integrations/telephony/overview) for Twilio, Vonage, and other setups
## Place the call
<CodeGroup>
```python Python
from dograh_sdk import DograhClient
from dograh_sdk._generated_models import InitiateCallRequest
with DograhClient(api_key="YOUR_API_KEY") as client:
client.test_phone_call(
body=InitiateCallRequest(
workflow_id=123,
phone_number="+14155551234",
)
)
```
```typescript TypeScript
import { DograhClient } from "@dograh/sdk";
const client = new DograhClient({ apiKey: "YOUR_API_KEY" });
await client.testPhoneCall({
body: {
workflow_id: 123,
phone_number: "+14155551234",
},
});
```
</CodeGroup>
## Inspect the run
Every call creates a **run** you can inspect afterwards. See [Calls & runs](/core-concepts/calls-and-runs) for what's tracked, or use the [Runs API](/api-reference/agents/runs/list) to list and fetch runs programmatically.
## Bulk campaigns
For placing many calls at once (say, from a CSV), use [Campaigns](/core-concepts/campaigns) rather than looping over `test_phone_call` — campaigns handle pacing, retries, and progress tracking.