connections/
Connections declare external capabilities and credential requirements. Raw secrets and refresh tokens stay outside the agent folder, model context, and sandbox filesystem.
// connections/github.ts
import { adapter, defineConnection } from "@assemblyline-agents/core";
export default defineConnection({
description: "GitHub capability contract.",
provider: "github",
binding: adapter("env"),
scopes: ["repo:read"],
capabilities: ["issues:read", "pull_requests:read"],
subject: "user",
required: false
});
Live Tool Connections
Use a protocol helper when a connection should expose tools through the deferred discovery path:
defineMcpClientConnection()defineOpenAPIConnection()defineHttpApiConnection()defineSandboxCliConnection()
Connection tools appear through tool_search, tool_describe, and tool_call.
Concrete remote schemas are not injected into every prompt.
The abstraction is the external capability and account, not its wire protocol.
MCP, OpenAPI, HTTP, and sandbox CLI are transports beneath the same connection
selection, access, approval, tracing, and subagent-scoping model. A sandbox CLI
connection runs its reviewed command inside the active agent sandbox so it can
see /files and /workspace; it does not launch the CLI on the gateway host.
Every live connection must declare tool-level access. Unclassified tools are not discoverable, and write matches take precedence over read matches:
export default defineMcpClientConnection({
url: "https://mcp.example.com",
description: "Example service.",
access: {
read: { tools: ["list_items", "get_item"] },
write: {
tools: ["create_item", "update_item", "delete_item"],
approval: "always"
}
}
});
Install A Provider Plugin
Connection plugins generate this policy rather than hiding it:
assembly-line add notion agent
assembly-line add slack agent --role connection
The generated provider helper uses the package's reviewed read/write tool-name
patterns and starts with read: true, write: false. To enable mutations, edit
the file explicitly:
import { defineNotionConnection } from "@assemblyline-agents/notion";
export default defineNotionConnection({
access: {
read: true,
write: { approval: "always" }
}
});
Assembly Line does not create the Notion integration or OAuth application. The
deployment owner supplies the token, a custom auth definition, or an endpoint
override. This same boundary applies to all official connection plugins.
Plugin Transports
Every official connection plugin follows one of four transports. The plugin catalog lists each plugin's endpoint and credential env vars; each package README documents provider-specific setup.
| Transport | What runs where | Exemplars |
|---|---|---|
| Hosted MCP (Streamable HTTP) | The provider's (or a developer-operated) MCP server; credential from a <PROVIDER>_MCP_TOKEN-style env var, custom header, or OAuth flow | Notion (above), Linear, Browser Use, Arcads, Mirror, Provenance |
| Direct OpenAPI | The provider's HTTP API called from the runtime using a bundled or referenced OpenAPI spec | SoundCloud |
| Stdio MCP | A packaged bridge or separately installed binary launched by the Assembly Line runtime host — trusted configuration, never model-chosen | FFmpeg, Remotion, Orgo, Peekaboo |
| Sandbox CLI | A provider CLI executed inside the active run sandbox with reviewed, individually quoted arguments | Higgsfield |
One exemplar for each remaining transport:
// connections/soundcloud.ts — direct OpenAPI with OAuth 2.1 PKCE.
// Register a SoundCloud app; set SOUNDCLOUD_CLIENT_ID and SOUNDCLOUD_CLIENT_SECRET.
import { defineSoundCloudConnection } from "@assemblyline-agents/soundcloud";
export default defineSoundCloudConnection({
access: { read: true, write: false }
});
// connections/ffmpeg.ts — stdio bridge; install ffmpeg/ffprobe on the runtime host.
// All media paths stay inside workspaceRoot; the model never supplies flags or shell.
import { defineFfmpegConnection } from "@assemblyline-agents/ffmpeg";
export default defineFfmpegConnection({
workspaceRoot: "/workspace/media",
access: {
read: true,
write: { approval: "always" }
}
});
// connections/higgsfield.ts — sandbox CLI transport.
// Install the official CLI in the sandbox image; run `higgsfield auth login`
// interactively inside each persistent, user-scoped sandbox.
import { defineHiggsfieldConnection } from "@assemblyline-agents/higgsfield";
export default defineHiggsfieldConnection({
access: {
read: true,
write: { approval: "always" }
}
});
Stdio and sandbox-CLI definitions are trusted application configuration: process command, arguments, working directory, and environment come from the checked-in connection source, never from the model. Local binaries and project dependencies must be provisioned on each runtime host where a stdio connection executes.
Subagents receive only their declared connection set. Give a dedicated worker
its connections in subagents/<name>/agent.ts:
import { defineSubagent } from "@assemblyline-agents/core";
export default defineSubagent({
description: "Analyze sources, cut social video, and render approved outputs.",
connections: ["arcads", "higgsfield", "ffmpeg", "remotion"]
});
Missing Credentials At Runtime
When a tool call reaches a live connection that has no usable credential, the
runtime raises ConnectionAuthorizationRequiredError and parks the run
instead of failing it:
- The run's status becomes
waiting_for_connectionand anauthorization.requiredevent records the connection name, reason, and the authorization challenge (including a session id for OAuth flows). Runs also park up front — with aconnection.requiredevent — when arequiredconnection is missing before the model turn starts. - For OAuth and interactive authorization, completing the provider flow at
GET/POST /assembly-line/connections/callback(runtime.completeConnectionAuthorizationCallbackfor embedders) stores the grant and resumes the parked tool call. The resume is idempotency- claimed, so a replayed or double-fired callback never executes the gated tool twice. - Env-token connections are configuration, not authorization: a missing
<PROVIDER>_MCP_TOKEN-style variable surfaces as an explicitMissing <VAR>error naming the variable to set. - In
tool_searchresults, a connection needing authorization is reported withneedsAuthorization: truerather than silently omitted.
During the rename compatibility window, both /assembly-line/connections/callback
and the legacy /openeve/connections/callback are served. Callback-URL
construction still emits the legacy path until the Mirror-side registration
cutover, after which it flips to the new path.
Authorizing Before The First Run
Operator surfaces can start (or probe) authorization without parking a run:
GET /assembly-line/connections/authorize?connection=<name> on the node host
(runtime.beginConnectionAuthorization() for embedders). The route is
authenticated (agent-control class) and returns JSON — the dashboard opens the
returned consent URL itself and the provider redirects to the public callback:
{ "status": "authorize", "url": "…" }— send the user's browser here. A pending session's challenge is reused, so repeated calls never mint duplicate sessions and the same call doubles as a poll while consent is in flight.{ "status": "connected" }— a usable grant already exists.{ "status": "unavailable", "reason": "…" }(409) — the connection has no auth definition, an env-token variable is missing (Missing <VAR>), or a user-subject connection was called without an identity.
Connections with subject: "user" key their grant by (userId, channel);
pass the same userId/channel query params a run would carry so the minted
grant is the one that run resolves. Grants live in the runtime's own store —
authorize once per environment.
MCP Transports
defineMcpClientConnection() is the backwards-compatible Streamable HTTP
form; transport: "http" is optional. defineMcpStdioConnection() declares a
static process with transport: "stdio", command, optional args, cwd, and
explicit environment overrides. defineMcpRelayConnection() declares a
static, HTTPS device relay with transport: "relay", url, credentialEnv,
and an optional bounded timeout. Assembly Line uses the MCP TypeScript SDK for HTTP
and stdio, routes HTTP/relay traffic through the host request policy, and
launches stdio commands directly without a shell. Each registry keeps one lazy
client/process per connection and closes it during runtime shutdown.
Process- and device-backed MCP definitions are trusted application configuration. Dynamic connections remain ordinary URL-backed HTTP MCP only and cannot supply commands, arguments, working directories, process environments, relay credentials, or a paired device target.
Dynamic Connections
Dynamic connections are off by default. When enabled in agent.ts,
a tool calling ctx.connectionManager can persist a new URL-backed MCP, OpenAPI, or HTTP
connection definition into the durable connection registry.
Saving is approval-gated by default and restricted by allowedHosts. Credentials
route through host APIs or authorization flows, never model-visible tool input,
the agent folder, sandbox, or prompt.