docs
This commit is contained in:
+45
-123
@@ -1,145 +1,67 @@
|
||||
# Agents over MCP
|
||||
|
||||
The engine exposes the flow API to agents over the
|
||||
[Model Context Protocol](https://modelcontextprotocol.io). Point Claude Code,
|
||||
Claude Desktop, Codex or anything else that speaks MCP at it, and it can read,
|
||||
build, publish and run flows.
|
||||
Fluksio exposes flow tools over MCP. An agent can inspect, edit, publish,
|
||||
and run flows with the permissions of the user who authorizes it.
|
||||
|
||||
## Switching it on
|
||||
## Connect an agent
|
||||
|
||||
```sh
|
||||
MCP_ENABLED=true
|
||||
```
|
||||
Set `MCP_ENABLED=true` in the engine's environment and restart it. The Python
|
||||
package defaults to off; the Docker template enables it.
|
||||
|
||||
It is off by default: switching it on opens client registration to whoever can
|
||||
reach the host.
|
||||
Configure your MCP client with an HTTP endpoint:
|
||||
|
||||
The endpoint is `https://api.${DOMAIN}/mcp`, or `http://api.localhost/mcp` on a
|
||||
local stack.
|
||||
- Local Docker stack: `http://api.localhost/mcp`
|
||||
- Deployment: `https://api.<your-domain>/mcp`
|
||||
|
||||
## Connecting a client
|
||||
The client registers, opens browser authorization, and receives an OAuth
|
||||
token after you approve access. The issuer and browser redirects use
|
||||
`DOMAIN`, `ENVIRONMENT`, and `FRONTEND_HOST`, so configure those for the
|
||||
addresses your client and browser can reach.
|
||||
|
||||
```sh
|
||||
claude mcp add --transport http fluksio https://api.${DOMAIN}/mcp
|
||||
```
|
||||
Manage registered clients under **Admin → Agents**. Revoking a client
|
||||
invalidates its access. MCP uses a separate signing key at
|
||||
`OAUTH_PRIVATE_KEY_FILE`; rotating that key invalidates all MCP tokens.
|
||||
|
||||
The OAuth flow does the rest: the client registers itself, you approve it in
|
||||
the browser, and it exchanges the grant for a token. Nothing to paste.
|
||||
MCP is not forwarded by the [portal tunnel](../interface/portal.md).
|
||||
Connect directly to the instance's API host.
|
||||
|
||||
## What an agent may do
|
||||
## Available tools
|
||||
|
||||
An agent acts as **the person who approved it**, and only through the same REST
|
||||
API the dashboard uses. It cannot do anything you could not do in the browser,
|
||||
and it cannot do anything *you* cannot do. An agent approved by a non-superuser
|
||||
is not one either.
|
||||
|
||||
Its tokens are signed with a keypair of their own, kept beside the flow store.
|
||||
Deleting that file revokes every agent's access without logging anyone out of
|
||||
the dashboard.
|
||||
|
||||
Registered clients are managed under **Admin**.
|
||||
|
||||
## The tools
|
||||
|
||||
Read-only:
|
||||
|
||||
| Tool | Returns |
|
||||
| Task | Tools |
|
||||
|---|---|
|
||||
| `list_flows` | every flow with its node count and state |
|
||||
| `get_flow` | one flow's definition, node status and issues |
|
||||
| `get_node_source` | a node's Python |
|
||||
| `list_node_types` | every type and its parameter schema |
|
||||
| `get_flow_state` | the current value of each of a flow's messages |
|
||||
| `get_message_history` | one message's recent numeric values |
|
||||
| `get_graph` | every flow as one graph |
|
||||
| `list_shared_nodes` | the shared library and its usages |
|
||||
| `list_secrets` | secret **names**, never values |
|
||||
| `get_modules` | the packages node code can import |
|
||||
| `get_health` | flows, nodes, queue and loop lag |
|
||||
| `get_metrics` | executions, errors and timings per minute |
|
||||
| `list_failures` | what went wrong recently |
|
||||
| `list_runs` | recent cascades |
|
||||
| Inspect flows | `list_flows`, `get_flow`, `get_node_source`, `list_node_types`, `get_graph`, `list_shared_nodes` |
|
||||
| Inspect values | `get_flow_state`, `get_message_history` |
|
||||
| Inspect the instance | `list_secrets` (names only), `get_modules`, `get_health`, `get_metrics`, `list_failures`, `list_runs` (live cascades) |
|
||||
| Edit flows | `save_flow`, `save_node_source`, `validate_flow`, `publish_flow`, `discard_draft`, `delete_flow` |
|
||||
| Operate flows | `run_flow`, `trigger_node`, `start_flow`, `stop_flow`, `pause_flow`, `resume_flow`, `cancel_node` |
|
||||
| Install node packages | `apply_modules` |
|
||||
|
||||
Editing:
|
||||
Tools call the same API as the browser. Drafts, validation, version checks,
|
||||
and superuser restrictions apply. Secrets cannot be read back.
|
||||
|
||||
| Tool | Does |
|
||||
|---|---|
|
||||
| `save_flow` | write a draft |
|
||||
| `save_node_source` | write a node's code into the draft |
|
||||
| `validate_flow` | the issues, without saving |
|
||||
| `publish_flow` | put the draft live (takes the version it saw) |
|
||||
| `discard_draft` | throw the draft away |
|
||||
| `delete_flow` | delete it |
|
||||
| `apply_modules` | replace the package manifest |
|
||||
|
||||
Operating:
|
||||
|
||||
| Tool | Does |
|
||||
|---|---|
|
||||
| `run_flow` | run every node once from the values given |
|
||||
| `trigger_node` | feed one node and run what is downstream |
|
||||
| `start_flow` / `stop_flow` | activate or tear down |
|
||||
| `pause_flow` / `resume_flow` | hold messages, or let them through |
|
||||
| `cancel_node` | kill a node's code while it runs |
|
||||
|
||||
## Why it is shaped this way
|
||||
|
||||
The tools do not reach into the engine. Each one calls the same REST endpoint
|
||||
the dashboard calls, over an in-process transport.
|
||||
|
||||
That keeps exactly one description of what a flow is and how it may be changed:
|
||||
the validation, the draft/publish split, and the version check that stops two
|
||||
clients overwriting each other. An agent saving a flow through a private back
|
||||
door could write one the canvas cannot open.
|
||||
|
||||
The caller's token rides along on every hop, so the API sees the agent's own
|
||||
identity rather than a service account. The audit trail on Home names it.
|
||||
A useful workflow: ask the agent to inspect the flow, save a draft, and
|
||||
validate it. Review the draft before asking it to publish. The agent has
|
||||
a publish tool, so make your intent explicit.
|
||||
|
||||
## The assistant
|
||||
|
||||
The same tools drive the chat inside the dashboard. An operator sets a
|
||||
provider under **Settings → Assistant** (anything OpenAI-compatible: OpenAI,
|
||||
Anthropic, OpenRouter, a local Ollama), and an **Assistant** entry appears in
|
||||
the sidebar for everyone. The panel opens on any screen and keeps its place
|
||||
from screen to screen; on a flow, it knows which one you are looking at.
|
||||
A superuser configures an OpenAI-compatible provider under
|
||||
**Settings → Assistant**, with a base URL, API key, and model. This enables
|
||||
the dashboard's Assistant entry for signed-in users.
|
||||
|
||||
The model calls the tools above, in-process, as **you**: every call carries
|
||||
your own token, so the chat can do nothing you could not do yourself, and its
|
||||
edits show up in the editor as drafts the moment they are saved. It is told to
|
||||
publish only when asked, but it has the tool, so read what it did before
|
||||
saying so. The trace under each answer lists every call it made.
|
||||
|
||||
The conversation is one per person, kept on the instance beside the
|
||||
configuration, and the bin in the panel's header starts it over. `MCP_ENABLED`
|
||||
is not needed for it: the endpoint is for agents outside, the chat for the
|
||||
one inside.
|
||||
The assistant uses the same tools with your own permissions. Draft edits
|
||||
appear in the editor, and each answer includes a tool trace. Conversations
|
||||
are stored per user on the instance; the bin button clears yours.
|
||||
`MCP_ENABLED` is only needed for external clients, so the built-in assistant
|
||||
works without it.
|
||||
|
||||
## Control
|
||||
|
||||
Where a live flow has a [`wren` node](../reference/node-types.md#wren) with
|
||||
its `prompt` and `actions` wired, the chat gains a **Control** tab, and Home a
|
||||
chat button at the top right of the brain graph (in the header, on a phone)
|
||||
that opens it. No provider is needed for this one: the model is the node.
|
||||
A live [Wren node](../reference/node-types.md#wren) with both `prompt` and
|
||||
`actions` wired adds a **Control** tab to the chat. It uses the node's local
|
||||
model and needs no assistant provider.
|
||||
|
||||
A command is published to the node's `prompt` message as a value from the
|
||||
chat, and the answer is the next value of its `actions`: each call, the
|
||||
message it went to, whether it was applied, and how sure the model was. A
|
||||
failing node answers with its error, and one that says nothing for fifteen
|
||||
seconds is reported as such. With several nodes, a picker in the header
|
||||
chooses. The conversation is kept in the browser only, and a reload clears
|
||||
it.
|
||||
|
||||
## A note on working this way
|
||||
|
||||
The pattern that works is the same one that works with a person: let the agent
|
||||
read the flow and its issues, let it write a **draft**, and publish yourself
|
||||
once you have looked. `validate_flow` before `publish_flow` is cheap and tells
|
||||
you what the canvas would have told you.
|
||||
|
||||
## Limits
|
||||
|
||||
- MCP is not currently reachable through a [portal](../interface/portal.md)
|
||||
tunnel: the proxy forwards `/api/v1/` only. Connect an agent on the same
|
||||
network as the instance.
|
||||
- Secrets are never readable, by an agent or by anyone else. `list_secrets`
|
||||
returns names.
|
||||
Choose a node, type a command, and inspect the reported actions: target
|
||||
message, value, confidence, and whether each action was applied.
|
||||
The node's `apply` and `min_confidence` settings decide whether it writes
|
||||
to devices. Control conversations stay in the browser and clear on reload.
|
||||
|
||||
Reference in New Issue
Block a user