Skip to content

Integrations

The platform API is not only a dashboard backend. It also exposes protocol and integration boundaries that let Agirunner participate in larger systems.

Status note

Remote MCP management is already part of the main supported control plane. A2A and ACP endpoints also exist today, but they are still in active development. The current implementation exposes real routes and service logic for both, but they are not yet presented as fully production-hardened or extensively compatibility-tested protocol surfaces.

  • remote MCP server management
  • A2A task ingress and status
  • ACP session-oriented execution
  • OAuth and webhook support flows

These routes manage external MCP servers that Agirunner can verify and grant into specialist tool surfaces.

  • GET /api/v1/remote-mcp-servers
  • POST /api/v1/remote-mcp-servers
  • PUT /api/v1/remote-mcp-servers/:id
  • POST /api/v1/remote-mcp-servers/:id/reverify
  • POST /api/v1/remote-mcp-servers/:id/oauth/reconnect
  • POST /api/v1/remote-mcp-servers/:id/oauth/disconnect

POST /api/v1/remote-mcp-servers

Scope: admin

Representative body:

{
"name": "Linear MCP",
"description": "Remote MCP surface for issue and project operations.",
"endpointUrl": "https://mcp.example.com",
"transportPreference": "auto",
"callTimeoutSeconds": 300,
"authMode": "parameterized",
"enabledByDefaultForNewSpecialists": false,
"parameters": [
{
"placement": "header",
"key": "Authorization",
"valueKind": "secret",
"value": "Bearer ..."
}
]
}

The route returns the verified server record, including verification status, discovered capability snapshots, and the resolved transport choice.

FieldContractMeaning
name / descriptionstringOperator-facing identity for the remote server.
endpointUrlURL stringBase endpoint the platform will verify and call.
transportPreferenceenumPreferred remote transport mode, or auto to let verification choose.
callTimeoutSecondsintegerUpper bound on a single remote call.
authModeenum-like stringHow auth material is supplied to the remote server.
enabledByDefaultForNewSpecialistsbooleanWhether newly created specialists should automatically see this server as available.
parametersstructured object[]Header, query, or other auth/config parameters sent to the remote server. Secret-bearing values are sanitized on readback.

The A2A surface is a thin task-ingress facade over the platform task broker.

GET /.well-known/agent.json

Representative response:

{
"protocol": "a2a",
"protocol_version": "0.1",
"name": "Agirunner",
"description": "A2A ingress and query facade over the Agirunner task broker.",
"authentication": {
"type": "bearer_api_key",
"header": "Authorization"
},
"capabilities": {
"task_submission": true,
"status_query": true,
"streaming_updates": true
},
"endpoints": {
"submit_task": "https://example/api/v1/a2a/tasks",
"get_task": "https://example/api/v1/a2a/tasks/{taskId}",
"stream_task": "https://example/api/v1/a2a/tasks/{taskId}/events"
}
}
FieldContractMeaning
protocol / protocol_versionfixed stringProtocol identity this endpoint is advertising to external A2A clients.
authenticationstructured objectHow the external caller is expected to authenticate.
capabilitiesstructured objectHigh-level A2A capability flags currently exposed by the platform.
endpointsstructured objectConcrete route templates external callers should use.

POST /api/v1/a2a/tasks

Scope: agent

Request body:

{
"task": {
"id": "external-123",
"title": "Review release blockers",
"description": "Summarize open blockers and propose next actions.",
"type": "analysis",
"priority": "high",
"workflow_id": "33333333-3333-3333-3333-333333333333",
"workspace_id": "22222222-2222-2222-2222-222222222222",
"role": "reviewer",
"input": {
"focus": "release blockers"
},
"context": {},
"metadata": {
"source": "external-system"
}
}
}
FieldContractMeaning
task.idstringOptional external task identifier from the caller. The platform stores it as protocol-ingress metadata rather than replacing the platform task id.
task.titlestringRequired user-facing task title.
task.descriptionstringMain natural-language brief for the task.
task.typestringOptional external task type label.
task.prioritystringQueue priority hint. Unsupported values normalize to normal.
task.workflow_idUUIDOptional existing workflow to attach the ingressed task to.
task.workspace_idUUIDOptional workspace context for the created task.
task.rolestringPreferred specialist role name.
task.inputarbitrary JSON objectStructured execution payload.
task.contextarbitrary JSON objectAdditional surrounding context.
task.metadataarbitrary JSON objectExtra caller annotations merged into protocol-ingress metadata.

Response:

{
"data": {
"id": "44444444-4444-4444-4444-444444444444",
"status": "submitted",
"title": "Review release blockers",
"created_at": "2026-03-31T18:55:00.000Z",
"updated_at": "2026-03-31T18:55:00.000Z",
"result": null,
"metadata": {
"task_id": "44444444-4444-4444-4444-444444444444",
"workflow_id": "33333333-3333-3333-3333-333333333333",
"workspace_id": "22222222-2222-2222-2222-222222222222"
}
}
}
FieldContractMeaning
idserver-generatedPlatform task id, not the caller-supplied external id.
statusenum-like stringA2A-facing mapped status derived from internal platform task state.
resultarbitrary JSON value or nullSanitized task output when available.
metadata.protocol_ingress.external_task_idstring or nullEcho of the external caller’s original task id when one was supplied.
metadata.task_id / workflow_id / workspace_idUUIDPlatform linkage ids to use in later Agirunner API calls.

GET /api/v1/a2a/tasks/:id/events

Scope: agent

SSE event shape:

id: 1234
event: task.state_changed
data: {"task_id":"4444...","status":"working","created_at":"2026-03-31T19:10:00.000Z"}

ACP supports session-oriented execution where the platform pairs a claimed task with an ACP session record.

POST /api/v1/acp/sessions

Scope: agent

Request body:

{
"agent_id": "99999999-9999-9999-9999-999999999999",
"worker_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"workflow_id": "33333333-3333-3333-3333-333333333333",
"transport": "websocket",
"mode": "session",
"workspace_path": "/workspace",
"metadata": {
"client": "custom-acp-runner"
}
}
FieldContractMeaning
agent_idUUIDACP-registered agent that owns the session. The platform rejects agents not registered with protocol: acp.
worker_idUUIDOptional worker backing the ACP session.
workflow_idUUIDOptional workflow scope used when reusing long-lived ACP sessions.
transportenumSession transport contract: stdio, http, or websocket.
modeenumrun for a per-task session, session for a reusable long-lived session.
workspace_pathstringPreferred working directory the ACP client should use.
metadataarbitrary JSON objectExtra ACP-session metadata. The platform also adds protocol and capability information.

Response:

{
"data": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"agent_id": "99999999-9999-9999-9999-999999999999",
"worker_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"workflow_id": "33333333-3333-3333-3333-333333333333",
"transport": "websocket",
"mode": "session",
"status": "initializing",
"workspace_path": "/workspace",
"metadata": {
"client": "custom-acp-runner"
},
"last_heartbeat_at": "2026-03-31T18:55:00.000Z",
"created_at": "2026-03-31T18:55:00.000Z",
"updated_at": "2026-03-31T18:55:00.000Z",
"reused": false
}
}
FieldContractMeaning
idserver-generatedACP session record id.
statusenumCurrent session state, such as initializing, active, idle, or closed.
last_heartbeat_atserver-generatedMost recent liveness update from the ACP client.
reusedserver-generatedPresent when the platform is reporting whether this session was newly created or reused.

POST /api/v1/acp/claim

Scope: agent

Request body:

{
"agent_id": "99999999-9999-9999-9999-999999999999",
"worker_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"routing_tags": [
"acp"
],
"include_context": true,
"session": {
"transport": "websocket",
"mode": "run"
}
}

Success response:

{
"data": {
"session": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"status": "initializing"
},
"task": {
"id": "44444444-4444-4444-4444-444444444444",
"title": "Review release blockers",
"prompt": "Summarize open blockers and propose next actions.",
"cwd": "/workspace",
"input": {},
"context": {},
"file_references": []
}
}
}
FieldContractMeaning
routing_tagsstring[]Claim filter tags. Defaults to ['acp'] when omitted.
include_contextbooleanWhether the claim response should include richer task context payloads.
session.transport / session.modeenumSession contract to use if a new session must be created or an existing one reused.
session.workspace_pathstringOptional override for the execution working directory.
task.promptstringPrompt-like summary the ACP client should execute against.
task.cwdstring or nullWorking directory the ACP client should treat as current.
task.file_referencesstructured object[]Document-style references extracted from task context for ACP clients.

As with normal claim routes, ACP claim can return 204 No Content when no task is available.