For the complete documentation index, see llms.txt. This page is also available as Markdown.

MCP Server

EDDI exposes its agent conversation and administration capabilities via the Model Context Protocol (MCP), enabling AI assistants (Claude Desktop, IDE plugins, custom MCP clients) to interact with deployed agents and manage the platform programmatically.

Transport

EDDI uses Streamable HTTP transport, served by the Quarkus MCP Server extension (quarkus-mcp-server-http).

Endpoint
Description

http://localhost:7070/mcp

MCP server endpoint (default + admin)

Client notes

  • Protocol version warnings. A client that announces an MCP-Protocol-Version newer than the bundled Quarkus MCP server knows makes the server log Invalid MCP protocol header: <version> on every call. The call still succeeds on the negotiated version; the line is noise until the extension is upgraded.

  • Retries are not idempotent. Most tools that create things — setup_agent, create_api_agent, create_group, create_schedule — are not idempotent. If a call fails with a transport error such as "session expired", it may still have completed on the server. Check first (list_agents, list_groups, …) before retrying, or you get a duplicate.

Available Tools (84)

Conversation Tools (11)

Tool
Description

list_agents

List all deployed agents with status, version, and name

list_agent_configs

List all agent configurations (including undeployed)

create_conversation

Start a new conversation with a deployed agent

talk_to_agent

Send a message and get the agent's response

chat_with_agent

Create a conversation and send a message in one call

read_conversation

Read conversation history, memory, and quick replies

read_conversation_log

Read conversation log as formatted text

list_conversations

List all conversations for a specific agent

get_agent

Get an agent's full configuration (packages, name, description)

discover_agents

Discover deployed agents enriched with intent mappings from agent triggers. Best way to find agents by purpose

chat_managed

Send a message using intent-based managed conversations (one conversation per intent+userId, auto-creates on first message)

Admin Tools (13)

Tool
Description

deploy_agent

Deploy an agent version to an environment

undeploy_agent

Undeploy an agent from an environment

get_deployment_status

Get deployment status of a specific agent version

list_workflows

List all packages (pipeline configurations)

create_agent

Create a new agent

delete_agent

Delete an agent (with optional cascade)

update_agent

Update an agent's name/description and optionally redeploy

read_workflow

Read a package's full pipeline configuration

read_resource

Read any resource config by type (behavior, langchain, httpcalls, output, etc.)

list_agent_triggers

List all agent triggers (intent→agent mappings) for managed conversations

create_agent_trigger

Create an agent trigger mapping an intent to one or more agent deployments

update_agent_trigger

Update an existing agent trigger

delete_agent_trigger

Delete an agent trigger for a given intent

Resource CRUD Tools (5)

Tool
Description

update_resource

Update any resource config by type and ID. Returns the new version URI

create_resource

Create a new resource. Returns the new resource ID and URI

delete_resource

Delete a resource (soft-delete by default, permanent=true for hard delete)

apply_agent_changes

Batch-cascade URI changes through package → agent in ONE pass, optionally redeploy

list_agent_resources

Walk agent → packages → extensions to get a complete resource inventory in one call

Diagnostic Tools (2)

Tool
Description

read_agent_logs

Read server-side pipeline logs (errors, LLM timeouts) filtered by agent/conversation/level. An unscoped or agent-only read additionally requires eddi-admin — it pulls from a shared buffer mixing every user's logs; only a conversationId-scoped read is open to a viewer (owner or admin)

read_audit_trail

Read per-task audit entries with LLM details, timing, cost, and tool calls

Setup Tools (2)

Tool
Description

setup_agent

Create a fully working agent in one call: creates behavior rules, LangChain config, optional output/greeting, package, agent, and deploys. Supports built-in tools, quick replies, and sentiment analysis. Default: anthropic/claude-sonnet-4-6

create_api_agent

Create an agent from an OpenAPI 3.0/3.1 spec. Parses the spec, generates HttpCalls configs (grouped by API tag), creates the full pipeline, and deploys. Supports endpoint filtering, base URL override, auth header propagation, and mcpServerUrls to add an MCP server's tools alongside the generated ones. A generated write tool takes the whole request body as one requestBody parameter — see below

The approval gate is not settable over MCP. POST /administration/agents/setup-api accepts a hitlConfig on the request body, so a caller can provision an agent whose write tools are gated from v1 onward. The MCP create_api_agent tool deliberately has no such parameter and always passes null: it already provisions an agent with a caller-chosen endpoint filter, so letting the caller also choose the gate would make it a complete escape from whatever allow-list governs the agent doing the calling. Provisioning a gated agent goes through REST (eddi-admin).

Schedule Management Tools (6)

Tool
Description

create_schedule

Create a new scheduled agent trigger (cron job or heartbeat). For CRON: provide cron. For HEARTBEAT: provide heartbeatIntervalSeconds. Heartbeats default to persistent conversations

list_schedules

List all scheduled agent triggers with name, type, cron/interval, status, next fire time, and fire count. Optionally filter by agentId

read_schedule

Read a schedule's full configuration including recent fire history (last 10 executions)

delete_schedule

Delete a scheduled agent trigger

fire_schedule_now

Manually trigger a schedule fire immediately. Useful for testing or one-off executions

retry_failed_schedule

Re-queue a dead-lettered schedule for another fire attempt after fixing the cause of failure

Group Conversation Tools (18)

Tool
Description

describe_discussion_styles

Rich descriptions of all seven built-in discussion styles plus CUSTOM, with phase flows, member roles, and use cases

list_groups

List all group configurations with name, style, member count

read_group

Read a group configuration's full details

create_group

Create a group (members, moderator, style, roles, member types, tasks). Supports nested groups via memberTypes=GROUP and pre-configured TASK_FORCE tasks via tasks param

update_group

Update a group configuration (full JSON replacement)

delete_group

Delete a group configuration

discuss_with_group

Start a multi-agent discussion on a question. Returns full transcript + synthesized answer

read_group_conversation

Read a group conversation transcript

list_group_conversations

List past group discussions for a group, with state and timestamps

start_group_discussion

Start a discussion asynchronously (returns immediately with groupConversationId). Poll with read_group_conversation

delete_group_conversation

Delete a group conversation. Its shared artifacts and any ephemeral agents are deleted; member conversations are ended, not deleted, and remain readable

followup_with_member

Ask one member a follow-up on a finished discussion. The agent retains its full context; question and answer are both recorded on the group transcript. Accepts an agent ID or a member's display name

continue_group_discussion

Continue a finished discussion with a new question. Every member re-runs the phases retaining memory of prior rounds; the round counter increments

close_group_conversation

Close a conversation permanently — ends member conversations and cleans up dynamically-created agents. No further follow-ups or continuations

add_team_task

File a task on a standing team's backlog (I13). The backlog outlives any one discussion; cadences pull executable tasks from it into task-force runs

list_team_backlog

List a standing team's backlog (I13) with each task's status, priority, assignee, and verification outcome

list_group_templates

List the packaged group templates (I10), each naming the roles create_group_from_template expects

create_group_from_template

Create a group from a template by assigning agents to its named roles (roleAssignments maps role → agent ID, or principal ID for HUMAN roles). Saves through the normal store path, so every save-time validation applies

See Group Conversations for full style details, custom phases, and nested groups.

Docs Tools (2)

Read EDDI's own documentation over MCP tools — the counterpart to the eddi://docs/* resources below, and the pair the toolsWhitelist: ["read_docs", "list_docs"] example further down consumes. Tools and resources serve different clients: agentic MCP clients (EDDI's own included) consume tools/list and never call resources/read, so before these existed EDDI's docs were readable by a desktop client and not by any agent consuming EDDI's MCP server. Role set mirrors the REST docs endpoints exactly (any of the five roles). Both delegate to DocsService, so eddi.docs.enabled=false switches this surface off together with REST and the resources.

Tool
Description

list_docs

List the documentation pages this deployment serves (one name per line, no .md suffix). Read this first — the runtime set is smaller than the repository's

read_docs

Read one page as markdown by name, e.g. architecture. Distinguishes an invalid name from an absent page

HITL Tools (10)

Resolve Human-in-the-Loop approval gates over MCP — the counterpart to the REST HITL endpoints, at parity for both the regular (1:1) and group surfaces. Authorization mirrors REST exactly (per-conversation owner / eddi-admin / eddi-approver via the shared HitlAccessGuard); decisions are attributed server-side as mcp:<principal>. Mutating tools honour the eddi.mcp.hitl.mutations.enabled kill-switch and return structured errors (errorCodeNOT_FOUND | WRONG_STATE | FORBIDDEN | DISABLED | BAD_REQUEST).

Tool
Description

list_pending_approvals

List regular (1:1) conversations awaiting approval (owner-scoped; includes RULE and TOOL_CALL pauses)

get_approval_status

Read a paused conversation's status; summary reports pauseType, detail=full returns the snapshot incl. any tool-call batch

resume_conversation

Resume with APPROVED/REJECTED (case-insensitive); resolves both RULE and TOOL_CALL pauses

cancel_conversation

Cancel a paused or running conversation

list_group_pending_approvals

List a group's conversations awaiting approval (owner-scoped)

list_all_group_pending_approvals

Cross-group HITL inbox across all groups (owner-scoped)

get_group_approval_status

Read a paused group discussion's status (summary; detail=full returns the whole conversation)

approve_group_phase

Approve/reject a paused phase, with optional taskApprovals JSON for TASK granularity; returns the resumed discussion

submit_group_human_input

Submit a HUMAN member's response for the turn an AWAITING_HUMAN_INPUT discussion is waiting on (I6). Recorded as that member's transcript entry; the discussion resumes from the next speaker. Only the pending member's own principal (or an admin) may submit — this is the member speaking, not approving

cancel_group_discussion

Cancel an in-progress or paused group discussion

See HITL for the full authority model, the kill-switch, and REST-endpoint parity.

Memory Tools (8)

Tool
Description

list_user_memories

List all persistent memory entries for a user

get_visible_memories

Get memories visible to a specific agent, considering self/group/global visibility scopes

search_user_memories

Search user memories by keyword across keys and values

get_memory_by_key

Get a specific memory entry by key for a user

upsert_user_memory

Create or update a persistent memory entry for a user

delete_user_memory

Delete a specific memory entry by ID

delete_all_user_memories

Delete all memory entries for a user (GDPR-compliant bulk erasure)

count_user_memories

Count total memory entries for a user

See User Memory for visibility scoping, recall order, and dream consolidation.

GDPR Tools (2)

Tool
Description

delete_user_data

Cascade-delete all user data across all stores (GDPR Art. 17 Right to Erasure). Requires confirmation='CONFIRM'. Irreversible

export_user_data

Export all data for a user (GDPR Art. 15/20 Right of Access / Data Portability)

See GDPR / CCPA Compliance for data erasure, export, and retention details.

Channel Integration Tools (5)

Tool
Description

list_channel_integrations

List all channel integrations with name, type, and target count

read_channel_integration

Read a channel integration's full configuration

create_channel_integration

Create a new channel integration (Slack, Teams, etc.) with platform config and agent targets

update_channel_integration

Update an existing channel integration

delete_channel_integration

Delete a channel integration (soft or permanent)

See Slack Integration for Slack-specific setup and multi-agent thread discussions.

MCP Resources

EDDI also exposes its documentation as MCP resources, allowing AI agents to browse and read the docs programmatically.

Resource
Description

eddi://docs/index

List all available documentation pages

eddi://docs/{name}

Read a specific doc (e.g., eddi://docs/getting-started)

Configure the docs path with: eddi.docs.path (default: docs/, in Docker: /deployments/docs).

The same docs over REST

MCP resources do not reach an EDDI agent. A resource is only usable by a client that asks for it, and EDDI's own MCP client never calls resources/read — it consumes tools. So eddi://docs/* made EDDI's documentation readable by a desktop MCP client and not by an agent running on EDDI, which is precisely backwards for an agent whose job is to explain the platform.

The same doc set is therefore served read-only over REST, where an agent generated from EDDI's OpenAPI spec picks it up as ordinary tools:

Endpoint
Role
Returns

GET /administration/docs

any of eddi-admin, eddi-editor, eddi-user, eddi-approver, eddi-viewer

JSON array of page names, without the .md suffix

GET /administration/docs/{name}

same

The page's markdown source as text/plain; 404 if absent

Roles are enumerated, not inherited. EDDI has no role hierarchy — JAX-RS @RolesAllowed and the MCP layer's requireRole are both literal hasRole checks — so eddi-viewer alone would refuse an eddi-admin. The widest read tier is spelled out because these are published documentation pages.

Both surfaces delegate to DocsService, which owns the filesystem access and the path-traversal guard.

The runtime doc set is smaller than the repository's. The container image copies only top-level docs/*.md (non-recursive, so nothing under docs/agent-configs/ or docs/templates/ is reachable) and then removes changelog.md, code-review-standards.md, incident-response.md and SUMMARY.md. Call the index and read from it — do not assume a particular page exists.

Quick Start

Client Configuration

EDDI uses Streamable HTTP transport at http://localhost:7070/mcp. How you connect depends on your client's transport support.

Direct HTTP (Streamable HTTP clients)

Clients that natively support HTTP transport (e.g., IDE plugins, custom MCP clients) can connect directly:

Antigravity (Google)

Add EDDI as an MCP server in your Antigravity settings (.gemini/config/settings.json or workspace .agents/settings.json):

Antigravity connects natively via Streamable HTTP — no bridge required.

stdio Bridge (Claude Desktop, Cursor, Windsurf, etc.)

Many MCP clients — including Claude Desktop's claude_desktop_config.json — only support stdio transport (spawning a local subprocess). They cannot connect to HTTP endpoints directly.

Use mcp-remote to bridge the gap. It runs as a local stdio process and proxies requests to EDDI's HTTP endpoint:

Windows users — if npx is not on your shell PATH, wrap via cmd:

What is mcp-remote? An open-source npm package (github.com/geelen/mcp-remote) that acts as an invisible bridge between stdio-only MCP clients and HTTP-based MCP servers. It handles protocol translation, session management, and authentication. Requires Node.js 18+.

Example Workflow

Discovering Agents by Purpose

Intent-Based Managed Chat

Inspecting Agent Configuration

Modifying Resources + Cascade

Debugging an Agent

Scheduling a Cron Job

Setting Up a Heartbeat

Running a Multi-Agent Discussion


Tool Reference — Agent Discovery & Managed Conversations

EDDI provides two tiers of conversation management:

Tier
Tools
Conversations
Use Case

Low-level

create_conversation + talk_to_agent

Multiple per user, manually managed

Custom apps, multi-conversation UIs

Managed

chat_managed

One per intent+userId, auto-created

Single-window chat, intent-based routing

The managed tier relies on agent triggers — mappings from an intent string to one or more agent deployments. Use the discovery and trigger tools below to configure and interact with this system.

discover_agents

Discover deployed agents with their capabilities. Returns an enriched list of deployed agents, cross-referenced with intent mappings from agent triggers. This is the best way to find agents by purpose.

Parameters:

Parameter
Type
Required
Default
Description

filter

string

No

""

Filter agents by name (case-insensitive substring match)

environment

string

No

"production"

Environment: production, production, or test

Response:

Note: The intents array only appears for agents that have agent triggers configured. Agents without triggers are still returned — they can be interacted with via chat_with_agent (low-level tier) but not via chat_managed.


chat_managed

Send a message to an agent using intent-based managed conversations. Unlike chat_with_agent (which requires a agentId and creates multiple conversations), this tool uses an intent to find the right agent and maintains exactly one conversation per intent+userId — like a single chat window.

The conversation is auto-created on first message and reused on subsequent calls. Requires an agent trigger to be configured for the intent (see list_agent_triggers / create_agent_trigger).

Parameters:

Parameter
Type
Required
Description

intent

string

Yes

Intent that maps to an agent trigger. E.g. "customer_support"

userId

string

Yes

User ID for conversation management (one conversation per intent+userId)

message

string

Yes

The user message to send

environment

string

No

Environment: production (default), production, or test

Response:

Behavior:

  • First call with a new intent+userId: creates a new conversation and sends the message

  • Subsequent calls with the same intent+userId: reuses the existing conversation (like continuing in the same chat window)

  • Returns an error if no agent trigger is configured for the given intent


list_agent_triggers

List all agent triggers (intent→agent mappings). Returns all configured intents with their agent deployments. Agent triggers enable intent-based conversation management via chat_managed.

Parameters: None.

Response:

Tip: Each trigger can map to multiple agent deployments — useful for A/B testing or environment-specific routing.


create_agent_trigger

Create an agent trigger that maps an intent to one or more agents. Once created, the intent can be used with chat_managed to talk to the agent.

Parameters:

Parameter
Type
Required
Description

config

string (JSON)

Yes

Full trigger configuration (see schema below)

Config schema:

Field
Type
Required
Description

intent

string

Yes

Unique intent identifier. Convention: slug-agentId (e.g. support-agent-abc123)

agentDeployments

array

Yes

List of agent deployments this intent routes to

agentDeployments[].agentId

string

Yes

The agent ID to route messages to

agentDeployments[].environment

string

No

Deployment environment (default: production)

agentDeployments[].initialContext

object

No

Key-value pairs injected into the conversation context on creation

Response:


update_agent_trigger

Update an existing agent trigger. Changes the agent deployments for a given intent (e.g., to point to a new agent version, add A/B routing, or change the initial context).

Parameters:

Parameter
Type
Required
Description

intent

string

Yes

The intent to update

config

string (JSON)

Yes

Full updated trigger configuration (same schema as create_agent_trigger)

Response:


delete_agent_trigger

Delete an agent trigger for a given intent. After deletion, chat_managed calls with this intent will return an error. Existing conversations are not deleted — they become orphaned but can still be read.

Parameters:

Parameter
Type
Required
Description

intent

string

Yes

The intent to delete

Response:


End-to-End Example: Setting Up Managed Chat

Configuration

In application.properties:

Tool Filtering

EDDI uses a whitelist-based ToolFilter (McpToolFilter.java) to control which tools are exposed via MCP.

Why? EDDI's langchain4j integration registers internal agent tools (calculator, datetime, websearch, etc.) that are meant ONLY for agent pipeline execution — not for external MCP clients. The ToolFilter SPI only sees a tool's name (not its declaring class or annotation type), so the whitelist is by name. It currently exposes all 84 intended tools — conversation, admin/resource/schedule/channel, setup, group, HITL approvals (McpHitlTools), persistent user memory (McpMemoryTools), GDPR/CCPA (McpGdprTools), and docs (McpDocTools).

To add a new MCP tool: add its name to the MCP_TOOLS set in McpToolFilter.java. A quarkus-MCP @Tool has no other invocation path, so a tool that is not whitelisted is unreachable dead code. McpToolFilterTest.test_allMcpToolMethods_areWhitelisted() auto-discovers every @Tool in the engine.mcp package and fails the build if any is missing from the whitelist — so forgetting this step is caught by CI.

Authentication & Authorization

  • The MCP endpoint inherits EDDI's existing OIDC/Keycloak authentication

  • When auth is enabled (quarkus.oidc.tenant-enabled=true), MCP clients must provide valid tokens

  • Authorization is enforced in-code, not via @RolesAllowed: most tools call requireRole(identity, authEnabled, "<role>") (McpToolUtils), and the HITL tools use the shared HitlAccessGuard (per-conversation owner / eddi-admin / eddi-approver). When authorization.enabled=false (the default dev posture) requireRole is a no-op — production is guarded by AuthStartupGuard, which fails startup if OIDC is disabled.

  • Future: Per-agent MCP access control via agent configuration for multi-tenant SaaS

Role Mapping

These are the actual Keycloak role strings the tools check (not aliases). Roles are additive in intent — grant an editor/admin the read scope too. For exact per-tool roles see the code (requireRole calls) and the per-category sections above (HITL / Memory / GDPR).

Role
Scope

eddi-viewer

The conversation tools (list_agents, list_agent_configs, get_agent, discover_agents, create_conversation, talk_to_agent/chat_with_agent/chat_managed, read_conversation, read_conversation_log, list_conversations, read_agent_logs, read_audit_trail), running a discussion and reading its transcript (describe_discussion_styles, discuss_with_group, start_group_discussion, read_group_conversation, list_group_conversations, followup_with_member, continue_group_discussion, list_team_backlog, list_group_templates), and the memory read tools (list_user_memories, get_visible_memories, search_user_memories, get_memory_by_key, count_user_memories). read_agent_logs additionally requires eddi-admin unless a conversationId is supplied

eddi-editor

setup_agent, create_api_agent, and the group configuration/lifecycle tools: list_groups, read_group, create_group, update_group, delete_group, create_group_from_template, add_team_task, close_group_conversation, delete_group_conversation

eddi-admin

Every tool in McpAdminTools, read as well as write — deploy_agent/undeploy_agent, get_deployment_status, agent and resource CRUD (list_workflows, read_workflow, read_resource, create_resource, update_resource, delete_resource, list_agent_resources, apply_agent_changes), and trigger/schedule/channel authoring and listing — plus the memory writes (upsert_user_memory, delete_user_memory, delete_all_user_memories) and GDPR tools (delete_user_data, export_user_data)

eddi-approver

Decide HITL approvals (with the conversation owner and eddi-admin): resume_conversation, approve_group_phase, cancel_*, *_pending_approvals, *_approval_status — see HITL

Sentiment Monitoring

Agents created with enableSentimentAnalysis=true (via setup_agent or create_api_agent) include sentiment data in every LLM response. The sentiment object includes: score (-1.0 to +1.0), trend, emotions, intent, urgency, confidence, and topicTags.

This data is stored in conversation memory and can be:

  • Read via read_conversation (in the conversation snapshot)

  • Aggregated for monitoring dashboards (Manager UI log panel)

  • Used for alerting (e.g., negative sentiment spike triggers notification)

Architecture

MCP Client — Agents as MCP Consumers

In addition to acting as an MCP server, EDDI agents can also consume external MCP servers as tool providers. This enables agents to call tools exposed by other MCP-compatible services during conversations.

Configuration

External MCP servers are configured as mcpcalls workflow extensions — a first-class, versioned configuration resource (the MCP equivalent of httpcalls). There is no inline MCP server array on the LLM task.

Step 1 — create an mcpcalls configuration (POST /mcpcallsstore/mcpcalls), one per MCP server:

Field
Type
Required
Default
Description

mcpServerUrl

string

Yes

MCP server URL

name

string

No

Human-readable name for logging

transport

string

No

"http"

Only Streamable HTTP is implemented; an unimplemented value is rejected as invalid configuration rather than silently substituted

apiKey

string

No

API key, sent as Authorization: Bearer <key>. Resolved through global variables and ${vault:key} references, or ${caller:token} to call as the chatting user (see below)

timeoutMs

long

No

30000

Connection and request timeout in milliseconds

toolsWhitelist

string[]

No

If non-empty, only these tool names are exposed (names as returned by the server's tools/list)

toolsBlacklist

string[]

No

Tool names to exclude. Applied after the whitelist

mcpCalls

object[]

No

Deterministic, action-triggered tool bindings (see Pipeline mode below). Omit for agent-mode-only servers

exposeResources

boolean

No

false

Opt-in bridge for the server's MCP resources: synthesizes <name>_list_resources and <name>_read_resource tools so the agent can list and read them (text capped at 64K chars, binary described, not returned). Independent of the whitelist/blacklist, which govern server-advertised names

How create_api_agent builds a write tool's body

A generated POST/PUT/PATCH tool takes the entire request body as a single requestBody parameter, whose description names the schema's properties, their types, and which are required. The model writes the JSON itself.

It is worth knowing why, because the obvious alternative is worse. Decomposing the schema into one parameter per property means every one becomes required (an ApiCall's parameter map has nowhere to record optionality), so a PATCH of one field forces the model to restate all the others and a partial update silently becomes a full overwrite. It also substitutes model-written values into JSON unescaped, so a value containing a quote can break the body or add fields the schema never declared.

The whole-body form matters most under HITL approval: the approval card shows tool arguments, so "what the approver sees is what gets sent" only holds while the body is one of them.

Calling an MCP server as the chatting user

Set apiKey to ${caller:token} and the tool call carries the identity of the person chatting, instead of a standing service credential:

The same guarantees apply as for API call headers — same origin only, fails closed rather than sending a placeholder, never persisted. See httpcalls.md.

Two behaviours worth knowing, because they are deliberate:

  • Only tool calls carry the caller. The initialize handshake and tools/list are sent unauthenticated, because the client is cached: a session opened with one user's token would be reused by everyone after them, and a tool list reflecting one user's permissions would be offered to the next. If your server requires authentication to list tools, use a static key.

  • Clients are cached per credential, not per URL. Two agents pointing at the same server with different keys get separate clients. A caller-bound config still yields one shared client — the credential is applied per request, so there is no client per user.

A ${caller:token} key with eddi.caller-identity.enabled=false is rejected as invalid configuration when the server is validated, rather than failing on every tool call.

Step 2 — add an mcpcalls step to the agent's workflow, before the LLM step:

A workflow may contain any number of mcpcalls steps — one per MCP server.

Two Modes, One Configuration

  • Agent modeAgentOrchestrator.discoverMcpCallTools() traverses the agent → workflow → every mcpcalls step at execution time, connects to each server, applies that config's whitelist/blacklist, and hands the surviving tools to the LLM. The LLM calls them reactively. Controlled by enableMcpCallTools on the LLM task (langchain.json), default true — no per-server opt-in is needed:

  • Pipeline modeMcpCallsTask (eddi://ai.labs.mcpcalls, pipeline position Parser → Rules → HttpCalls → McpCalls → LLM → Output) matches behavior-rule actions against mcpCalls[].actions and invokes the named tool deterministically, with no LLM involved. Only active when mcpCalls is non-empty.

Both modes read the same mcpcalls configuration; they are not mutually exclusive.

Using setup_agent with MCP Servers

The mcpServerUrls parameter accepts a comma-separated list of URLs. For each URL, AgentSetupService creates one mcpcalls configuration (transport: "http", timeoutMs: 30000, no whitelist/blacklist, no mcpCalls bindings — i.e. agent-mode only) and inserts a matching eddi://ai.labs.mcpcalls step into the generated workflow ahead of the LLM step. Nothing is written inline into the LLM configuration.

Architecture

Key Behaviors

  • Graceful degradation: Failed MCP connections log warnings but never kill the pipeline

  • Connection caching: McpToolProviderManager reuses connections across conversation turns

  • Budget/rate-limiting: MCP tools are subject to the same ToolExecutionService controls as built-in tools

  • Vault references: API keys support ${vault:key} syntax via SecretResolver

  • Clean shutdown: All MCP clients are closed on application shutdown via @PreDestroy

Last updated

Was this helpful?