feat: create tools using MCP

This commit is contained in:
Abhishek Kumar 2026-05-31 16:50:44 +05:30
parent 5c29b6ed94
commit fcb7004c7a
17 changed files with 1989 additions and 572 deletions

View file

@ -12,6 +12,7 @@ from __future__ import annotations
from typing import Any
from dograh_sdk._generated_models import (
CreateToolRequest,
CreateWorkflowRequest,
CredentialResponse,
DocumentListResponseSchema,
@ -29,6 +30,11 @@ from dograh_sdk._generated_models import (
class _GeneratedClient:
# `DograhClient.__init__` installs `self._request` (see client.py).
def create_tool(self, *, body: CreateToolRequest) -> ToolResponse:
"""Create a reusable tool for the authenticated organization."""
data = self._request("POST", "/tools/", json=body.model_dump(mode="json", exclude_none=True))
return ToolResponse.model_validate(data)
def create_workflow(self, *, body: CreateWorkflowRequest) -> WorkflowResponse:
"""Create a new workflow from a workflow definition."""
data = self._request("POST", "/workflow/create/definition", json=body.model_dump(mode="json", exclude_none=True))

View file

@ -1,13 +1,28 @@
# generated by datamodel-codegen:
# filename: dograh-openapi-aBVTJk.json
# timestamp: 2026-05-27T10:06:12+00:00
# filename: dograh-openapi-EZT8BU.json
# timestamp: 2026-05-31T10:54:36+00:00
from __future__ import annotations
from enum import Enum
from typing import Annotated, Any
from typing import Annotated, Any, Literal
from pydantic import AwareDatetime, BaseModel, ConfigDict, Field
from pydantic import AwareDatetime, BaseModel, ConfigDict, Field, RootModel
class CalculatorToolDefinition(BaseModel):
"""
Tool definition for Calculator tools.
"""
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
"""
Schema version.
"""
type: Annotated[Literal['calculator'], Field(title='Type')]
"""
Tool type.
"""
class CallDispositionCodes(BaseModel):
@ -16,6 +31,34 @@ class CallDispositionCodes(BaseModel):
)
class Category(Enum):
"""
Tool category. Must match definition.type.
"""
http_api = 'http_api'
end_call = 'end_call'
transfer_call = 'transfer_call'
calculator = 'calculator'
native = 'native'
integration = 'integration'
mcp = 'mcp'
class Icon(RootModel[str]):
root: Annotated[str, Field(max_length=50, title='Icon')] = 'globe'
"""
Lucide icon identifier.
"""
class IconColor(RootModel[str]):
root: Annotated[str, Field(max_length=7, title='Icon Color')] = '#3B82F6'
"""
Hex color for the tool icon.
"""
class CreateWorkflowRequest(BaseModel):
name: Annotated[str, Field(title='Name')]
workflow_definition: Annotated[dict[str, Any], Field(title='Workflow Definition')]
@ -90,6 +133,64 @@ class DocumentResponseSchema(BaseModel):
is_active: Annotated[bool, Field(title='Is Active')]
class MessageType(Enum):
"""
Type of goodbye message.
"""
none = 'none'
custom = 'custom'
audio = 'audio'
class EndCallConfig(BaseModel):
"""
Configuration for End Call tools.
"""
messageType: Annotated[MessageType | None, Field(title='Messagetype')] = 'none'
"""
Type of goodbye message.
"""
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
"""
Custom message to play before ending the call.
"""
audioRecordingId: Annotated[str | None, Field(title='Audiorecordingid')] = None
"""
Recording ID for audio goodbye message.
"""
endCallReason: Annotated[bool | None, Field(title='Endcallreason')] = False
"""
When enabled, the model must provide a reason for ending the call. The reason is set as call disposition and added to call tags.
"""
endCallReasonDescription: Annotated[
str | None, Field(title='Endcallreasondescription')
] = None
"""
Description shown to the model for the reason parameter. Used only when endCallReason is enabled.
"""
class EndCallToolDefinition(BaseModel):
"""
Tool definition for End Call tools.
"""
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
"""
Schema version.
"""
type: Annotated[Literal['end_call'], Field(title='Type')]
"""
Tool type.
"""
config: EndCallConfig
"""
End Call configuration.
"""
class GraphConstraints(BaseModel):
"""
Per-node-type graph rules. WorkflowGraph enforces these at validation.
@ -104,6 +205,34 @@ class GraphConstraints(BaseModel):
max_outgoing: Annotated[int | None, Field(title='Max Outgoing')] = None
class Method(Enum):
"""
HTTP method to use for the request.
"""
GET = 'GET'
POST = 'POST'
PUT = 'PUT'
PATCH = 'PATCH'
DELETE = 'DELETE'
class TimeoutMs(RootModel[int]):
root: Annotated[int, Field(ge=1, title='Timeout Ms')] = 5000
"""
Request timeout in milliseconds.
"""
class CustomMessageType(Enum):
"""
Type of custom message.
"""
text = 'text'
audio = 'audio'
class InitiateCallRequest(BaseModel):
workflow_id: Annotated[int, Field(title='Workflow Id')]
workflow_run_id: Annotated[int | None, Field(title='Workflow Run Id')] = None
@ -116,6 +245,66 @@ class InitiateCallRequest(BaseModel):
)
class McpToolConfig(BaseModel):
"""
Configuration for a customer MCP server tool definition.
"""
transport: Annotated[Literal['streamable_http'], Field(title='Transport')] = (
'streamable_http'
)
"""
MCP transport protocol.
"""
url: Annotated[str, Field(title='Url')]
"""
MCP server URL. Must use http:// or https://.
"""
credential_uuid: Annotated[str | None, Field(title='Credential Uuid')] = None
"""
Reference to an external credential for MCP server auth.
"""
tools_filter: Annotated[list[str] | None, Field(title='Tools Filter')] = None
"""
Allowlist of MCP tool names to expose. Empty exposes all tools.
"""
timeout_secs: Annotated[int | None, Field(ge=0, title='Timeout Secs')] = 30
"""
Connection timeout in seconds.
"""
sse_read_timeout_secs: Annotated[
int | None, Field(ge=0, title='Sse Read Timeout Secs')
] = 300
"""
SSE read timeout in seconds.
"""
discovered_tools: Annotated[
list[dict[str, Any]] | None, Field(title='Discovered Tools')
] = None
"""
Server-managed cache of the MCP server's tool catalog [{name, description}]. Populated best-effort by the backend.
"""
class McpToolDefinition(BaseModel):
"""
Persisted MCP tool definition.
"""
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
"""
Schema version.
"""
type: Annotated[Literal['mcp'], Field(title='Type')]
"""
Tool type.
"""
config: McpToolConfig
"""
MCP server configuration.
"""
class NodeCategory(Enum):
"""
Drives grouping in the AddNodePanel UI.
@ -140,6 +329,39 @@ class NodeExample(BaseModel):
data: Annotated[dict[str, Any], Field(title='Data')]
class Type(Enum):
"""
JSON type for the resolved value.
"""
string = 'string'
number = 'number'
boolean = 'boolean'
class PresetToolParameter(BaseModel):
"""
A parameter injected by Dograh at runtime.
"""
name: Annotated[str, Field(title='Name')]
"""
Parameter name used as a key in the request body.
"""
type: Annotated[Type, Field(title='Type')]
"""
JSON type for the resolved value.
"""
value_template: Annotated[str, Field(title='Value Template')]
"""
Fixed value or template, e.g. {{initial_context.phone_number}}.
"""
required: Annotated[bool | None, Field(title='Required')] = True
"""
Whether the parameter must resolve to a non-empty value.
"""
class PropertyOption(BaseModel):
"""
An option in an `options` or `multi_options` dropdown.
@ -197,9 +419,42 @@ class RecordingResponseSchema(BaseModel):
is_active: Annotated[bool, Field(title='Is Active')]
class Type1(Enum):
"""
JSON type for the parameter value.
"""
string = 'string'
number = 'number'
boolean = 'boolean'
class ToolParameter(BaseModel):
"""
A parameter that the tool accepts from the model at call time.
"""
name: Annotated[str, Field(title='Name')]
"""
Parameter name used as a key in the tool request body.
"""
type: Annotated[Type1, Field(title='Type')]
"""
JSON type for the parameter value.
"""
description: Annotated[str, Field(title='Description')]
"""
Description shown to the model for this parameter.
"""
required: Annotated[bool | None, Field(title='Required')] = True
"""
Whether this parameter is required when the tool is called.
"""
class ToolResponse(BaseModel):
"""
Response schema for a tool.
Response schema for a reusable tool.
"""
id: Annotated[int, Field(title='Id')]
@ -216,6 +471,62 @@ class ToolResponse(BaseModel):
created_by: CreatedByResponse | None = None
class MessageType1(Enum):
"""
Type of message to play before transfer.
"""
none = 'none'
custom = 'custom'
audio = 'audio'
class TransferCallConfig(BaseModel):
"""
Configuration for Transfer Call tools.
"""
destination: Annotated[str, Field(title='Destination')]
"""
Phone number or SIP endpoint to transfer the call to, e.g. +1234567890 or PJSIP/1234.
"""
messageType: Annotated[MessageType1 | None, Field(title='Messagetype')] = 'none'
"""
Type of message to play before transfer.
"""
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
"""
Custom message to play before transferring.
"""
audioRecordingId: Annotated[str | None, Field(title='Audiorecordingid')] = None
"""
Recording ID for audio message before transfer.
"""
timeout: Annotated[int | None, Field(ge=5, le=120, title='Timeout')] = 30
"""
Maximum seconds to wait for the destination to answer.
"""
class TransferCallToolDefinition(BaseModel):
"""
Tool definition for Transfer Call tools.
"""
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
"""
Schema version.
"""
type: Annotated[Literal['transfer_call'], Field(title='Type')]
"""
Tool type.
"""
config: TransferCallConfig
"""
Transfer Call configuration.
"""
class UpdateWorkflowRequest(BaseModel):
name: Annotated[str | None, Field(title='Name')] = None
workflow_definition: Annotated[
@ -286,6 +597,80 @@ class HTTPValidationError(BaseModel):
detail: Annotated[list[ValidationError] | None, Field(title='Detail')] = None
class HttpApiConfig(BaseModel):
"""
Configuration for HTTP API tools.
"""
method: Annotated[Method, Field(title='Method')]
"""
HTTP method to use for the request.
"""
url: Annotated[str, Field(title='Url')]
"""
Target HTTP or HTTPS URL.
"""
headers: Annotated[dict[str, str] | None, Field(title='Headers')] = None
"""
Static headers to include with every request.
"""
credential_uuid: Annotated[str | None, Field(title='Credential Uuid')] = None
"""
Reference to an external credential for request authentication.
"""
parameters: Annotated[list[ToolParameter] | None, Field(title='Parameters')] = None
"""
Parameters the model must provide when calling this tool.
"""
preset_parameters: Annotated[
list[PresetToolParameter] | None, Field(title='Preset Parameters')
] = None
"""
Parameters injected by Dograh from fixed values or workflow context templates.
"""
timeout_ms: Annotated[
TimeoutMs | None, Field(title='Timeout Ms', validate_default=True)
] = 5000
"""
Request timeout in milliseconds.
"""
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
"""
Custom message to play after tool execution.
"""
customMessageType: Annotated[
CustomMessageType | None, Field(title='Custommessagetype')
] = None
"""
Type of custom message.
"""
customMessageRecordingId: Annotated[
str | None, Field(title='Custommessagerecordingid')
] = None
"""
Recording ID for an audio custom message.
"""
class HttpApiToolDefinition(BaseModel):
"""
Tool definition for HTTP API tools.
"""
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
"""
Schema version.
"""
type: Annotated[Literal['http_api'], Field(title='Type')]
"""
Tool type.
"""
config: HttpApiConfig
"""
HTTP API configuration.
"""
class PropertySpec(BaseModel):
"""
Single field on a node.
@ -338,6 +723,46 @@ class RecordingListResponseSchema(BaseModel):
total: Annotated[int, Field(title='Total')]
class CreateToolRequest(BaseModel):
"""
Request schema for creating a reusable tool.
"""
name: Annotated[str, Field(max_length=255, title='Name')]
"""
Display name for the tool.
"""
description: Annotated[str | None, Field(title='Description')] = None
"""
Description shown to the agent when deciding whether to call it.
"""
category: Annotated[Category | None, Field(title='Category')] = 'http_api'
"""
Tool category. Must match definition.type.
"""
icon: Annotated[Icon | None, Field(title='Icon', validate_default=True)] = 'globe'
"""
Lucide icon identifier.
"""
icon_color: Annotated[
IconColor | None, Field(title='Icon Color', validate_default=True)
] = '#3B82F6'
"""
Hex color for the tool icon.
"""
definition: Annotated[
HttpApiToolDefinition
| EndCallToolDefinition
| TransferCallToolDefinition
| CalculatorToolDefinition
| McpToolDefinition,
Field(discriminator='type', title='Definition'),
]
"""
Typed tool definition.
"""
class NodeSpec(BaseModel):
"""
Single source of truth for a node type.

View file

@ -65,7 +65,8 @@ class StartCall(TypedNode):
greeting: Optional[str] = None
"""
Text spoken via TTS at the start of the call. Supports
{{template_variables}}. Leave empty to skip the greeting.
{{template_variables}}. Leave empty to skip the greeting. Not supported
with realtime (speech-to-speech) models.
"""
greeting_recording_id: Optional[str] = None