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?
| Field | Type | Default | Description |
|---|---|---|---|
| Registered tools | Ballast → you | HTTP / MCP | Your endpoint appears as a custom:<name> node inside workflows. |
| Webhook triggers | event → Ballast | HTTP POST | An external system starts a run; the request body is the input. |
| MCP | both ways | MCP | Workflows call MCP servers, and MCP clients drive Ballast. |
| SDKs | Ballast ↔ you | Python / TS | Decorate a function and serve+register it in one step; or script the API. |
| Framework adapters | Ballast → you | LangGraph / CrewAI | Expose 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.
$ 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.
$ 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_calltool (or a registered tool withkind: "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.
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.