Skip to content

agent-host

Status: Current | Last reviewed: 2026-10-13

Hosts the MCP (Model Context Protocol) endpoints that pipeline LLMs call as tools. The agent itself never executes tool code — it asks agent-host, which dispatches to the right backend.

Source

apps/agent-host

Runtime

Aspect Value
Language Python 3.12
Framework FastAPI + the MCP SDK
Ports :8003 MCP streamable transport

:8003 is the endpoint pipelines connect to. ai-orchestrator rewrites the symbolic host agent-host-mcp:8003 to localhost:8003 in Vanguard. The old ADK demo agents were moved to .backup/agent-host-demo-adk/; they are no longer part of the deployed runtime.

Tool types

Type Backend
http Outbound HTTP to a URL with headers from tools.encrypted_config
python Sandboxed code via code-executor
host_action Copilot-only suggestion via the conversation-event bridge
mcp_proxy Transparent proxy to a customer-supplied MCP server
transfer Warm hand-off; see warm-handoff.md
workflow_run Triggers an async-agent workflow

Catalog tools live in apps/agent-host/catalogs/.

Dependencies

Service Purpose
Postgres tools, tool_secrets, integrations rows
code-executor Python tool execution
async-agent workflow_run tool
ari-controller transfer tool target
Customer MCP servers mcp_proxy

Workflows as named external MCP tools

Generic and named workflow tools submit through async-agent's authenticated HTTP execution API. They return a durable execution_id; status accepts this receipt or a later run_id. wait_for_result joins the same asynchronous execution for up to 120 seconds. Generic idempotency_key and named workflow_idempotency_key map to Idempotency-Key. Polling failure preserves the receipt. Status and approval forward the caller's validated bearer and tenant; external callers cannot borrow the service credential. See startup and recovery.

The token-authed /workflow/mcp endpoint always serves the generic tools (trigger_workflow, check_workflow_status, approve_execution_request). Additionally, workflows a tenant opted in via workflow_configs.expose_mcp (migration 196 — column, not config: the collab Yjs allow-list would drop a config key) are advertised as named tools — workflow_<slug> (or the explicit mcp_tool_name), with an inputSchema derived from the workflow's input_parameters (rows flagged is_input: false are excluded; a wait_for_result boolean is always added, default true).

Implementation: apps/agent-host/workflow_mcp_expose.py overrides the workflow FastMCP instance's low-level list_tools (appends the authed tenant's exposed workflows) and intercepts CallToolRequest for workflow_* names, dispatching through the same catalogs/workflow.py trigger_workflow (tenant re-checked at call time). Fails soft: pre-migration DBs or a transient DB error serve the static tools unchanged. The opt-in toggle lives in the workflow editor's Start-node inspector ("External MCP Exposure" card → PATCH /api/workflows/:id/expose-mcp).

This is the outward direction — external agents calling our workflows. The internal direction (ai-manager agents using a workflow as an LLM tool) is the Agent Tool trigger, which the publisher projects into tool_configs; the two are independent.

Note: trigger_workflow previously compared workflow_configs.id with a ::uuid cast — the column has been an integer PK since migration 130, so every call errored. Fixed 2026-06-11 (numeric coercion + native int comparison).

Vanguard

overmind restart agent-host

External MCP access is via https://tools.<host>.dev.trueserve.deloitte.com/mcp — the nginx ingress strips Cookie/UA/Referer and forwards to :8003.

Required env: MASTER_ENCRYPTION_KEY (to decrypt tool secrets).

MCP callers should authenticate with Authorization: Bearer tsf_* or X-Internal-Service-Token for trusted service-to-service calls. Query-string token auth is disabled by default (MCP_ALLOW_QUERY_TOKEN_AUTH=false) because URLs can land in browser, proxy, and gateway logs; enable it only for a client that cannot set headers and migrate that client as soon as possible. Tool-call diagnostic logs redact token, secret, password, cookie, and share-code-shaped fields, and enable_multimodal no longer returns the raw share code or link to the LLM after SMS delivery.

CES (Genesys Cloud) session binding

Custom MCP headers like $context.variables.* only resolve when bound via the REST runSession inputs[].variables envelope, not via WebSocket sessionInput.variables or remoteDialogflowQueryParameters. The orchestrator pre-registers the mapping at session start; agent-host resolves the internal conv_id from the x-ces-session-id header.

Operators populate those variables from the agent editor's Session variables field on the CES stage (both the voice/S2S CESLLMService and the text CESTextLLMService), stored as config.input_variables. ElevenLabs Agent has the equivalent Dynamic variables field (config.dynamic_variables). Each value is a literal or a $var: runtime binding resolved at session start — see universal pipeline builder → session variables. The CES text service forwards input_variables on its first runSession call (same inputs[].variables channel as the WebSocket path).

See ces-session-variable-binding for the full diagnosis.

Production

Helm chart at charts/agent-host. Pod env must include MASTER_ENCRYPTION_KEY mounted from trueserve-master-key. The active service is agent-host-mcp on :8003.

See also

Agent evaluation

Performance tests use durable jobs, pinned runtime configurations and shared mock state. See agent evaluation and worker operations for this service’s role, admission limits, authenticated stream ownership and recovery.

Studio access and personal tokens

Personal tokens resolve the current tenant role with the same access model as Studio: Admin, Builder and Viewer; legacy Developer → Builder, Operator → Admin, Analyst → Viewer. Viewer gets run access, Builder gets agent/tool authoring, and Platform Admin gets every capability within the token's tenant. Inactive users, tenants and removed memberships are rejected. Run/read scopes never become authoring scopes through normalization. Tool management also permits data analysis; existing dedicated analysis scopes remain accepted.

Named tenant roles are authoritative. Retired direct permission grants, including wildcards, do not elevate Viewer or Builder.