Skip to content

MCP Server ​

Agentfleet is also an MCP server. External agents (Claude, Copilot, portal assistants, your own) can discover Agentfleet workflows and run them as tools through the Model Context Protocol. They connect to the API host's /mcp endpoint over Streamable HTTP.

Only workflows someone has deliberately exposed appear, and only their latest published version ever runs. Every call is authorised for the calling user.

What an agent sees ​

ToolWhat it does
run_<tool_name>One per exposed workflow you may run. Runs its latest published version with the inputs you give, waits up to wait_seconds (default 30, capped at 120) and returns the run: run_id, state, done, and the final output (the first 4,000 characters) when it finished.
get_run_statusrun_id → the run's state, and its output once finished. Poll this for a long run.
get_run_outputrun_id, optional offset and max_characters → the finished run's output, in pages.

A run_… tool's input schema lists the workflow's declared inputs as strings; required ones are marked as such. A non-string argument is passed to the run as its JSON text. Two optional arguments are added to every run_… tool:

  • wait_seconds: how long to wait for the run before returning its run_id to poll.
  • client_request_id: an idempotency key. Calling again with the same key returns the same run instead of starting a second one.

Results come back as JSON text and as structured content, for example:

json
{
  "run_id": "6f0c…",
  "workflow": "Duplicate investor sweep",
  "state": "Completed",
  "done": true,
  "output": "{\"duplicates\":[…]}",
  "truncated": false,
  "output_length": 812
}

The result also carries failure_reason, started_at and completed_at when they apply. A run still going returns "done": false and a hint to poll get_run_status. A cut output returns a hint naming the offset to read next. Errors, such as a missing input, an unknown tool or a run you cannot see, come back as tool errors with a code and a readable error.

Exposing a workflow ​

On a workflow's page, MCP tool → Expose (permission agentfleet:expose-workflows; workflow admins and admins):

  • Tool name: a lower-case letter followed by lower-case letters, digits and _ (up to 48 characters), so the tool is run_<tool name>. It must be unique within the tenant.
  • What it does: this is what agents read to decide when to call the tool. Write it for them (up to 1,000 characters).
  • Inputs: up to 20 run input context keys a call provides, each required or optional. A call with an undeclared input, or without a required one, is refused. Declare purpose or task_id as inputs if callers should supply them.

The workflow must be published first. An MCP call names no agent, so the run uses the workflow's default agent (set in its run policy). A workflow without one cannot be run this way. Exposing, changing and withdrawing are each recorded as an Activity, and every run started through MCP is recorded with the calling OAuth client. The API is PUT / DELETE /api/workflows/{id}/mcp-exposure with toolName, description and inputs.

Authentication and access ​

  • OAuth through Authlink. Send an Authlink access token for the Agentfleet API as Authorization: Bearer …. The browser session cookie is never accepted at /mcp.
  • Discovery. An unauthenticated call returns 401 with a resource_metadata pointer to /.well-known/oauth-protected-resource, which names Authlink as the authorization server. MCP clients that support OAuth discovery use this to sign the user in.
  • Connecting needs agentfleet:use-mcp-server. Workflow authors, operators and workflow admins hold it.
  • Every call is decided by the policy decision point for the workflow it touches, with that workflow's tenant, status and creator as resource attributes:
    • running needs agentfleet:run-workflow-instance;
    • reading a run needs agentfleet:view-workflow-instance.
  • Tenant isolation. You only ever see your own tenant's exposed workflows and their runs. A tool or run you may not use is reported as not found, exactly as one that does not exist.
  • Runs are yours. A run started through MCP is an ordinary run as the calling user. The run queue, retries and usage limits apply, and it appears in the console like any other.

Configuration ​

The endpoint is on by default. These settings live in the API's McpServer configuration section:

SettingDefaultMeaning
EnabledtrueWhether /mcp is served at all.
DefaultWaitSeconds30How long a run_… call waits when it gives no wait_seconds.
MaxWaitSeconds120The cap on wait_seconds.
InlineOutputCharacters4000How much output a run_… or get_run_status result carries.
MaxOutputCharacters100000The most get_run_output returns in one call (the cap on max_characters).

The endpoint is stateless, so it scales out with the API. See the MCP server runbook for operations detail.

Client examples ​

Claude Code ​

bash
claude mcp add --transport http agentfleet https://<your-agentfleet-host>/mcp

Then /mcp in Claude Code to sign in with Authlink. If your client cannot complete the OAuth flow (for example, it needs dynamic client registration), pass a token instead:

bash
claude mcp add --transport http agentfleet https://<your-agentfleet-host>/mcp \
  --header "Authorization: Bearer $AGENTFLEET_TOKEN"

Any MCP client (JSON configuration) ​

json
{
  "mcpServers": {
    "agentfleet": {
      "type": "http",
      "url": "https://<your-agentfleet-host>/mcp",
      "headers": { "Authorization": "Bearer ${AGENTFLEET_TOKEN}" }
    }
  }
}

.NET (ModelContextProtocol SDK) ​

csharp
using ModelContextProtocol.Client;

var transport = new HttpClientTransport(new HttpClientTransportOptions
{
    Endpoint = new Uri("https://<your-agentfleet-host>/mcp"),
    AdditionalHeaders = new Dictionary<string, string> { ["Authorization"] = $"Bearer {accessToken}" },
});

await using var client = await McpClient.CreateAsync(transport);

foreach (var tool in await client.ListToolsAsync())
    Console.WriteLine($"{tool.Name}: {tool.Description}");

var result = await client.CallToolAsync(
    "run_duplicate_investor_sweep",
    new Dictionary<string, object?> { ["investor_id"] = "INV-1042", ["wait_seconds"] = 60 });

// Long run? Poll get_run_status with the run_id from result.StructuredContent, then read get_run_output.

The access token is an Authlink token whose audience is the Agentfleet API, obtained the same way as for the REST API.

Agentfleet — agent workflow orchestration.