Skip to content

Connect to your bot

Let your bot (OpenClaw, Hermes, Grok Bot, dot from OpenAI, OpenBot, MausBot, nanobot and others) drive Elyra, and have Elyra notify it when an agent finishes.

View Markdown

A bot is an assistant that stays up all the time and talks to you through chat, your phone or a messenger: OpenClaw, Hermes, Grok Bot, dot from OpenAI, OpenBot, MausBot, nanobot and others. This page shows how to connect it to Elyra in two directions:

  • The bot drives Elyra: it opens cards, sends tasks to agents, reads terminals and files.
  • Elyra notifies the bot: when an agent finishes, Elyra calls an address of the bot, and it tells you.

Each section has a ready-made prompt. Copy it, paste it into your bot and it does the setup for you. Where the setup depends on the bot, the prompt asks it to follow its own documentation.

What the bot can do in Elyra

Once connected, the bot uses the same tools as the Cloud connector, which act with your permissions on the computer where Elyra runs:

  • elyra: runs the Elyra CLI: projects, workspaces, Canvas cards, terminals, agents, the embedded browser and automations;
  • shell, read_file, write_file, edit_file, list_dir and search: commands and files;
  • screenshot and browser_screenshot: show what Elyra or a page displays (on the Cloud, with a link to the image);
  • list_skills and read_skill: the manuals of the Elyra skills.

The full table is in Connect outside agents through MCP.

Security. The bot acts as you, without asking for confirmation at each step. Connect only bots you trust and revoke access when you no longer need it (see Security).

Pick a path

Where the bot runs Path Needs
On the same computer as Elyra elyra mcp, over stdio Elyra open
On another machine (server, cloud, phone) Cloud MCP with OAuth Elyra Cloud on

Bot on the same computer: elyra mcp

elyra mcp is an MCP server over stdio: the bot starts it as a subprocess and talks to it in lines of JSON. It forwards each request to the open Elyra on this computer, with the same tools as the Cloud connector. No tunnel, no Cloud and no sign-in.

The configuration, in any MCP client that accepts a server started by a command, is:

{
"mcpServers": {
"elyra": {
"command": "elyra",
"args": ["mcp"]
}
}
}

The key names and the file it goes in change from bot to bot: use the format its documentation asks for and keep the elyra command with the mcp argument.

Things to watch:

  • Elyra must be open. With the app closed, each request comes back with an error telling you to open Elyra, and elyra mcp stays up for the next request.
  • The bot must find the executable. If it cannot find elyra, put the full path in command. To find it, run command -v elyra (macOS and Linux) or Get-Command elyra (PowerShell).
  • The bot and Elyra must be on the same computer, under the same system user. A bot inside a container or a server cannot reach the Elyra on your computer: for that case, use the Cloud path.
  • What elyra mcp prints to standard output is only the MCP protocol; warnings and errors go to stderr.

MausBot: MausBot works with the Claude Code and Codex on your computer. Register elyra mcp in them, and MausBot can drive Elyra:

Janela do terminal
claude mcp add --scope user elyra -- elyra mcp
codex mcp add elyra -- elyra mcp

Prompt for your bot:

Set up an MCP server named "elyra" with the command `elyra mcp` (stdio transport). If the `elyra` command is
not found, use the full path of the executable. Then list the server's tools and call the `elyra` tool with
the arguments `workspace list` to confirm it worked. Use your own MCP documentation to find where to register
the server; do not make up commands.

Bot on another machine: the Cloud MCP

When the bot does not run on your computer, it reaches Elyra through the Cloud connector: an address https://<your-user>-cloud.elyra.sh/mcp, with OAuth sign-in. You approve the connection once and access renews itself; no fixed key to copy. The step by step, the consent screen and revocation are in Connect outside agents through MCP; they are not repeated here.

The connector answers with JSON over HTTP (POST), without SSE. A bot that only speaks the old SSE transport cannot connect.

Where to register the server in each bot:

Bot Where to register the remote server
Grok Bot Setup → Plugins, Remote HTTPS server with OAuth (source)
dot, from OpenAI Plugins → + → Add custom MCP server, for personal use, without review (source)
OpenClaw Settings → MCP, in the control panel (Control UI), with HTTP transport and OAuth sign-in (source)
Hermes hermes mcp add --url <address> --auth oauth elyra and then hermes mcp test elyra (source)
nanobot Apps → MCP → Connect, with auth set to oauth (source)

Each flow ends on a page of your Cloud, where you sign in with your Elyra account and tap Allow. If the bot runs on a server without a browser, the sign-in has to come back to the bot’s machine (through port forwarding, for example); the bot’s documentation explains how.

Prompt for your bot:

Add the remote MCP server https://<my-user>-cloud.elyra.sh/mcp with OAuth authentication and send me the
sign-in link so I can authorize it. Follow your own MCP documentation to do this; do not make up commands.
Once I have authorized it, list the server's tools and call the `elyra` tool with the arguments
`workspace list` to confirm.

Notify the bot: the “Call URL” action

For the bot to know that an agent finished (or is waiting for you, or CI failed), Elyra makes an HTTP call to the address the bot publishes. This is the Call URL action of the automations.

Create it on screen

  1. Open Automations and use Create automation.
  2. Under when, pick the event, for example an agent finishes.
  3. Under do this, pick Call URL and fill in:
    • Method: GET, POST, PUT, PATCH or DELETE;
    • Address (URL): the bot’s address, with the query if any;
    • Headers: name/value pairs;
    • Body: only for methods that carry a body. The default is a JSON with the event;
    • Sign with a secret: turns on the signature (see below).
  4. Create automation.

Event variables

The URL and the body accept these variables, written between double braces:

Variable What it carries
{{trigger}} The event that fired, such as agent-finished, agent-waiting or card-message; manual when you run the automation by hand; otherwise, the trigger type
{{agent}} For an Elyra event that comes from a card (agent finished, agent waiting, card message), that card’s agent, when Elyra knows it; otherwise, the automation’s agent
{{card}} For those events, the title of the card that fired; otherwise, the run title
{{project}} The project name
{{time}} The time, in ISO 8601
{{summary}} GitHub, GitLab or webhook event: event, repository, title and address, whatever comes. Elyra event with a card: the event and the card title (agent-finished · PR reviewer). Otherwise, empty

In the URL the values go in encoded; in the body they go in escaped for JSON. The default body is:

{
"trigger": "{{trigger}}",
"agent": "{{agent}}",
"card": "{{card}}",
"project": "{{project}}",
"time": "{{time}}",
"summary": "{{summary}}"
}

And the bot receives, for example:

{
"trigger": "agent-finished",
"agent": "claude",
"card": "PR reviewer",
"project": "my-app",
"time": "2026-10-18T14:03:00.000Z",
"summary": "agent-finished · PR reviewer"
}

Signature

With Sign with a secret on, every call carries the header:

X-Elyra-Signature-256: sha256=<HMAC-SHA256, in hexadecimal, of the exact body, with the secret as the key>

It is the same format as the incoming webhook. The secret is generated by Elyra and stored encrypted in the system vault, like the webhook’s:

  1. Save the automation and open its details.
  2. In the Call URL signature section, tap Generate secret and copy it right away: it is shown only once. If you lose it, use Rotate secret.
  3. Give the secret to the bot.

The receiver checks the signature over the exact bytes of the body. In Node.js:

import { createHmac, timingSafeEqual } from 'node:crypto'
function signatureMatches(rawBody, header, secret) {
const expected = createHmac('sha256', secret).update(rawBody).digest()
if (!/^sha256=[0-9a-f]{64}$/i.test(header ?? '')) return false
const received = Buffer.from(header.slice(7), 'hex')
return received.length === expected.length && timingSafeEqual(received, expected)
}

Without the signature turned on, Elyra does not prove who called: use it only on an address you control and that accepts nothing from strangers.

What happens on the call

  • 10-second deadline and no resend. If the bot is down, Elyra keeps no queue.
  • The call leaves your computer, and local (localhost) and internal-network addresses are accepted. That is how a bot on the same machine, such as the OpenClaw gateway, gets notified. Only use URLs you trust.
  • Only a 2xx answer counts as success. The run history shows HTTP 200 · 120 ms. Any other answer, a connection error or the deadline running out fails the action and stops the chain, with the reason in the history; on screen, the failure also shows up in a notice.
  • Elyra does not follow redirects: a 3xx counts as a failure, so the signed body is never resent to another address.
  • The secret and headers do not go to logs, and the action summary shows only the server, never the query.
  • The header values are saved with the automation. Prefer the signature over a fixed token in a header.

Example: notify OpenBot

OpenBot runs a local server on port 4132 and takes events on POST /api/publish. An an agent finishes → Call URL automation with these fields sends the notice straight to it:

  • Method: POST;
  • Address (URL): http://localhost:4132/api/publish;
  • Headers: content-type = application/json;
  • Body:
{
"type": "agent:invoke",
"data": {
"role": "user",
"content": "Agent {{agent}} finished on card {{card}} in project {{project}}. Let me know."
}
}

Create it from the command line

The bot can also create the automation, through the elyra tool, with --actions. The signing secret, however, is only generated in the app, in the automation details:

Janela do terminal
elyra automations create --name "Notify the bot" \
--trigger-json '{"kind":"elyra-event","events":["agent-finished"]}' \
--actions '[{"kind":"http-call","method":"POST","url":"https://bot.example.com/elyra","headers":[],"body":"{\"card\":\"{{card}}\"}","sign":true}]' \
--trigger daily --prompt "Event notice" --provider codex --repo <project>

Prompt for your bot:

I want you to receive notices from Elyra. Publish an HTTP POST address (or tell me which of your addresses to
use) and, when a notice arrives, check the X-Elyra-Signature-256 header: it is "sha256=" plus the
hexadecimal HMAC-SHA256 of the exact body, using as the key the secret I will give you. If the signature does
not match, ignore the notice. If it matches, the body is a JSON with trigger, agent, card, project, time and
summary: tell me in the chat what happened. Answer 200 to Elyra within 10 seconds. Once the address exists,
create in Elyra, with the `elyra` tool, the automation "an agent finishes → Call URL" (method POST, that
address, signature on) and tell me so I can generate the secret in the automation details.

Skills in the bots’ folders

The Elyra skills are short manuals that teach the agent to use the CLI. Elyra installs them by itself in the skills folders of the assistants that are already on your computer, and that now includes OpenClaw:

Bot Folder
OpenClaw ~/.openclaw/skills (or <OPENCLAW_STATE_DIR>/skills, if you moved the state folder)
Hermes Hermes’s skills folder (~/.hermes/skills, %LOCALAPPDATA%\hermes\skills on Windows, or HERMES_HOME)
Other assistants ~/.agents/skills and the Claude, Codex, Grok CLI, Cursor and other folders

The rules are always the same:

  • Elyra never creates a bot’s folder. Without OpenClaw installed, nothing is written.
  • Each installed skill carries the .elyra-managed.json marker. What is not Elyra’s is not touched, and uninstalling Elyra removes only what has the marker.
  • MausBot: it uses the skills in the Claude Code and Codex folders, where Elyra already installs them.
  • OpenBot: gets Elyra’s notices through the Call URL action (example above).
  • The ~/.grok/skills folder is the Grok CLI’s, not Grok Bot’s; Grok Bot gets Elyra through the connector.

A bot that does not see the skills may need to reload its own skills; see how in its documentation.

Prompt for your bot:

List the skills you have loaded and tell me whether there is one called "elyra". If there is, read it now
and, before using the `elyra` tool, follow what it says. If there is not, reload your skills following your
own bot's documentation and check again; do not make up commands.

End-to-end example

The bot sends a task to an agent and is notified when it finishes.

  1. Connect the bot to Elyra through elyra mcp or through the Cloud.

  2. Create the automation “an agent finishes → Call URL” pointing to the bot’s address, with a signature, and give it the secret (see Notify the bot).

  3. Ask in the bot’s chat: “ask an agent to review the changes in project X”.

  4. The bot uses the elyra tool to find the project and open the agent, something like:

    Janela do terminal
    elyra workspace list --json
    elyra canvas create terminal --workspace 'id:<ID-FROM-THE-LIST>' --agent <agent> --title 'Bot task' --json
    elyra terminal wait --terminal '<HANDLE>' --for tui-idle --json
    elyra terminal send --terminal '<HANDLE>' --text-file <file-with-the-task> --json

    The <HANDLE> comes from the second command’s reply.

  5. The agent works. When it finishes, Elyra makes the Call URL call, the bot checks the signature and tells you in the chat that it is done. To read the result, the bot uses elyra terminal read --terminal '<HANDLE>'.

Prompt for your bot:

Use Elyra for this task: open an agent in the project "<project name>" (list the workspaces with
`elyra workspace list --json` through the `elyra` tool, and read the "elyra" skill first), ask it to
"<the task>" and keep an eye on it. When Elyra notifies me at your address that the agent finished (check the
X-Elyra-Signature-256 signature), read the result from its terminal and tell me here, in the chat, what was
done.

Troubleshooting

Symptom What to do
The bot gets “open the Elyra app” Elyra is closed. Open the app; elyra mcp works again on the next request.
The bot cannot find the elyra command Use the executable’s full path in command.
The Cloud refuses the bot’s connection See Troubleshooting the Cloud.
The action failed with “The server answered 401” The bot refused the call. Check the address and the secret it uses to validate.
The action failed with “Signing is on, but the secret does not exist” Open the automation details and tap Generate secret.
The action failed with “The call took longer than 10 s to answer” The bot took too long. Answer 200 right away and process the notice afterwards.