Overview
The GAIA Agent UI includes a built-in MCP (Model Context Protocol) server that exposes the full Agent UI as a set of tools. This lets external AI assistants — like Claude Code, Cursor, or any MCP-compatible client — interact with GAIA agents, manage chat sessions, index documents, and browse files, all through the same backend that powers the web UI. Conversations initiated via MCP appear in the browser UI in real time, so you can watch tool execution and agent activity as it happens.Available Tools
get_messages retrieves every page up to the message count reported at the
start of the call. Messages added during retrieval are available on the next
call. A failed or prematurely empty page returns an explicit error rather than
a partial transcript. Existing content and tool-result excerpt limits still apply.
The
memory_* tools are conditional. The read tools (memory_stats, memory_list,
memory_recall, memory_get, memory_get_by_entity, memory_get_conversation_turns)
are registered only when memory MCP access is enabled — either via the Memory Dashboard
toggle (mcp_memory_enabled) or GAIA_MEMORY_MCP_ALWAYS=1. The admin tools
(memory_seed, memory_clear) additionally require GAIA_MEMORY_ADMIN=1 on the backend
process.Setup with Claude Code
1
Start the Agent UI backend
2
Add the MCP server to Claude Code
--stdio flag tells the MCP server to use stdio transport, which is what Claude Code expects.3
Start a new Claude Code conversation
After adding the MCP server, start a new conversation (or restart Claude Code) so it picks up the new tools. You should see
gaia-agent-ui tools available.The MCP server connects to the Agent UI backend at
http://localhost:4200 by default. If your backend runs on a different port, pass --backend http://localhost:YOUR_PORT after --stdio.Setup with Other MCP Clients
The MCP server also supports Streamable HTTP transport for clients that connect over HTTP instead of stdio:http://localhost:8766/mcp.
Usage Examples
Once connected, you can ask Claude Code (or any MCP client) to interact with GAIA:Chat with the Agent
create_session, then send_message, and the conversation will appear in the Agent UI browser window in real time.
Index and Query Documents
index_folder to index the documents, then send_message to query them using RAG.
Browse and Search Files
search_files to find matching files across the filesystem.
Visual Feedback
Drive a turn without a browser
send_message blocks until the turn ends, so a turn that stops at a permission
prompt never returns. To run a real task unattended, start the turn with
start_message, then loop on wait_for_turn(until="attention"). That call
returns when the turn finishes or when it needs you. Answer each prompt it
reports, then read the result.
turn_view rebuilds the turn from the same events the browser renders. The
activity steps are folded the way the UI folds them, and the footer holds the
exact numbers the UI shows when you click the line under an answer, e.g.
12.3s · 42.5 tok/s · 123ms TTFT · 1,234 → 56 tokens.
Assert on these instead of taking a screenshot.
A few details:
turn_statusalso attaches to a turn the user started in the browser, so its prompts can be answered the same way.wait_for_turntakestimeout_msfrom 1 to 600000. Out-of-range or non-integer values are refused immediately. On timeout it returnstimed_out: truewith the state the turn had. If the turn ends before the condition, it returnsended: truerather than waiting out the clock.turn_metricsreports a value nobody measured asnull, never0.tokens_in/tokens_outare the final model call, which is what the UI footer shows.turn_input_tokens/turn_output_tokenscover the whole turn.- Turns started with
start_messageuse the model the Agent UI uses. Change it withset_model.
What answering a prompt can’t do
answer_prompt posts to the same endpoint as the user’s click in the browser,
and always names the prompt it answers. It is refused before reaching the
backend when:
The backend checks the
confirm_id again, and its rejection comes back as
backend_rejected. An always grant covers only the scope the prompt showed,
for example write_file on notes.txt, never the whole tool.
Over HTTP the server refuses any request that carries a browser Origin
header, including pages served from other localhost ports and the Agent UI’s
own origin. A web page you visit therefore can’t drive it. MCP clients send no
Origin and are unaffected. The backend’s own X-Gaia-UI header and origin
checks still apply to every call this server makes.
It listens on loopback only. A --host that other machines can reach, such as
0.0.0.0 or a LAN IP, is refused at startup unless you pass --allow-remote
and put a bearer token of at least 32 characters in GAIA_AGENT_UI_MCP_TOKEN.
Clients then send Authorization: Bearer <token> on every request. A missing or
wrong token gets 401. The token is read from the environment, not the command
line, and is never logged or echoed.
Architecture
send_message, it streams the response via SSE (Server-Sent Events) from the backend, collects tool outputs and agent steps, and returns the complete result. The web UI receives the same SSE events simultaneously, so you see real-time activity in the browser.
Configuration
Removing the MCP Server
Troubleshooting
MCP tools not appearing in Claude Code
MCP tools not appearing in Claude Code
Make sure you started a new conversation after adding the MCP server. Claude Code only loads MCP tools at conversation start. Also verify the backend is running with
curl http://localhost:4200/api/health.'Cannot connect to GAIA backend' errors
'Cannot connect to GAIA backend' errors
The Agent UI backend must be running before the MCP server can work. Start it with
uv run python -m gaia.ui.server or use the startup scripts in installer/scripts/.send_message times out
send_message times out
Large documents or complex queries can take time. The default timeout is 180 seconds. If the Lemonade LLM server is slow to respond, check its status with
system_status. A turn that is waiting on a permission prompt never finishes on its own. Use start_message and answer_prompt instead (see Drive a turn without a browser).403 'Invalid Origin header' over HTTP
403 'Invalid Origin header' over HTTP
The server refuses requests that carry a browser
Origin, so a web page can’t answer prompts. Connect from an MCP client (Claude Code, the Python SDK), or use --stdio.