Connect

Connecting your agents

Ballast doesn't compete with where your agents are built — it's where they become reliable and governed. Five surfaces connect existing agents and systems to the platform, each landing at the same place: your code running inside a checkpointed, audited workflow.

Whatever your agent is today — an HTTP service, an MCP server, a Python function, a LangGraph app, a CrewAI crew — one of the surfaces below wraps it with retries, timeouts, human gates, cost attribution, and an audit trail, without rewriting the agent itself. The one question that picks a surface is the direction data flows: does Ballast call out to your code, does an external event call in, or does another agent drive Ballast?

FieldTypeDescription
Registered toolsBallast → youYour endpoint appears as a custom:<name> node inside workflows.
Webhook triggersevent → BallastAn external system starts a run; the request body is the input.
MCPboth waysWorkflows call MCP servers, and MCP clients drive Ballast.
SDKsBallast ↔ youDecorate a function and serve+register it in one step; or script the API.
Framework adaptersBallast → youExpose a compiled graph or crew as a registered tool.

1. Registered custom tools — your agent in the palette

Register any HTTP endpoint or MCP tool once as a named tool with a JSON input schema, auth headers, and its own timeout and retry defaults. It appears in the builder palette, and workflow nodes call it as custom:<name>. Arguments are validated against the schema before the call; for an HTTP tool a non-2xx response fails the node and the engine's retry/backoff machinery applies. This is the default choice when your agent already speaks HTTP or MCP.

Register an agent endpoint
$ curl -X POST http://localhost:8000/api/tools \
    -H "X-API-Key: aos_..." -H "content-type: application/json" \
    -d '{
      "name": "score-lead",
      "label": "Score lead",
      "description": "Scores an inbound lead 0-100.",
      "kind": "http",
      "endpoint_url": "https://my-agent.example.com/score",
      "input_schema": {
        "type": "object",
        "properties": { "company": { "type": "string" } },
        "required": ["company"]
      }
    }'

Full field reference, argument validation rules, and the one-shot /test endpoint are on the tool reference page.

2. Inbound webhook triggers — external systems start runs

Every workflow can expose one signed webhook URL. Any system that can send an HTTP POST — Zendesk, Stripe, GitHub, a CI job, your own backend — starts a governed run, with the request body as the run input. The secret embedded in the URL is the only credential, so no API key needs to leave your workspace. Reach for this when the trigger is an event rather than a call you make yourself.

Enable, then trigger
$ curl -X POST http://localhost:8000/api/workflows/{id}/webhook -H "X-API-Key: aos_..."
{ "enabled": true, "url": "http://localhost:8000/api/hooks/{id}/{secret}" }

$ curl -X POST "http://localhost:8000/api/hooks/{id}/{secret}" \
    -H "content-type: application/json" -d '{"ticket": "I was double charged"}'
{ "run_id": "af772b3602ef", "status": "pending" }

Enabling, rotating, the constant-time secret check, and secret-handling guidance are on the webhook triggers page.

3. MCP — both directions

  • Workflows call MCP servers — the built-in mcp_call tool (or a registered tool with kind: "mcp") invokes any tool on any MCP server over streamable HTTP, so MCP-speaking agents and toolsets plug in with zero adapter code
  • Agents operate Ballast — the platform is itself an MCP server at POST /api/mcp: Claude, Cursor, or any MCP client can list workflows, start runs, inspect runs, and resolve approval gates, each call enforcing the capability of its REST equivalent

Setup for both directions and a Claude Code connection example are on the MCP page.

4. SDKs — Python and TypeScript

The SDKs collapse "stand up an endpoint" and "register it" into one step. In Python, decorate a plain function with @tool, call serve(), and it is exposed over HTTP andregistered as a workspace tool — schema inferred from the signature. Use the SDKs when your agent is code you own and you'd rather not hand-write the registration payload, or when you want a typed client for scripting the API.

connect_agent.py
from agentos_sdk import AgentOS, tool, serve

@tool(description="Score a sales lead 0-100.")
def score_lead(company: str, employees: int = 0) -> dict:
    return {"score": min(100, employees // 10)}

client = AgentOS("http://localhost:8000", api_key="aos_...")
serve(client, [score_lead], port=8801)
# tool custom:score-lead -> http://localhost:8801/tools/score-lead

Quickstarts for both languages are on the SDKs page.

5. Framework adapters — LangGraph and CrewAI

register_langgraph and register_crewai wrap a compiled LangGraph app (anything with .invoke(state)) or a CrewAI crew (anything with .kickoff(inputs=...)) using the same serve-and-register mechanics as the SDK. They ship with the Python SDK, so their deep-dive lives on the SDKs page.

Honest framing

The adapters do not translate framework graphs into Ballast graphs. Your agent keeps running in your process, with its own framework — Ballast calls it over HTTP as a registered tool and provides the durability, approval, and audit layer around every invocation. If you want Ballast to orchestrate individual steps (checkpoint each one, gate between them), model those steps as nodes; if you just want your existing agent governed as a unit, an adapter is the fastest path.

Which surface should I use?

Start from what you already have and which way data needs to flow:

  • Your agent is an HTTP service → registered tool (tools)
  • External events should start workflows → webhooks (webhooks)
  • Your agent or its tools already speak MCP → MCP (outbound) (MCP)
  • Your agent is a Python function or a LangGraph/CrewAI app → SDK / adapters (SDKs)
  • Another agent or IDE should drive Ballast itself → the MCP server (MCP)

Surfaces compose

These are not mutually exclusive. A common shape: a webhook from Stripe starts a run, a registered tool (or MCP call) invokes your scoring agent mid-graph, a human gate pauses for review, and a teammate resolves it from an IDE through the MCP server — one run, three surfaces, fully audited end to end.