Expose Flows as MCP Tools with the McpToolTrigger
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
Expose a flow as a named tool on a Kestra MCP server.
The McpToolTrigger makes any flow discoverable and callable by MCP-compatible AI agents such as Claude Desktop, Claude Code, and Cursor. Flow inputs are automatically converted to a JSON schema tool spec so the AI agent knows exactly what parameters to pass. Each invocation creates a new flow execution tagged with system.from:mcp for observability.
type: io.kestra.plugin.core.trigger.McpToolTriggerEvery tenant has a default MCP server provisioned on startup, so the trigger works without creating a server first. See MCP Server to create additional servers and connect AI agent clients.
Example
id: hello_worldnamespace: company.team
inputs: - id: user type: STRING defaults: John Doe description: "The name of the user to greet."
tasks: - id: greet type: io.kestra.plugin.core.output.OutputValues values: greeting: "Hello, {{ inputs.user }}!"
outputs: - id: greeting type: STRING value: "{{ outputs.greet.values.greeting }}"
triggers: - id: mcp type: io.kestra.plugin.core.trigger.McpToolTrigger toolName: hello_world title: Hello World greeting tool toolDescription: Returns a personalised greeting. Call this when the user asks for a greeting. mcpServer: defaultWhen deployed, an MCP client connected to the default server will discover a tool named hello_world. It will accept a user parameter (typed as string from the flow input) and return a greeting string in the tool response.
Properties
| Property | Required | Default | Description |
|---|---|---|---|
toolName | Yes | — | Tool identifier shown to the AI agent. Must contain only alphanumeric characters, hyphens, underscores, or dots, and must start and end with an alphanumeric character. Maximum 64 characters. |
title | Yes | — | Human-readable name shown to the AI agent. |
toolDescription | Yes | — | Description of the tool shown to the AI agent, used to decide when to invoke it. A well-written description significantly improves tool-selection accuracy. |
mcpServer | No | "default" | ID of the MCP server to register this tool on. Must match the id of an existing MCP server. |
annotations.readOnly | No | false | Hint that this tool does not modify its environment. |
annotations.destructive | No | true | Hint that this tool may perform destructive updates. Only meaningful when readOnly is false. |
annotations.openWorld | No | true | Hint that this tool may interact with entities outside its closed domain. |
annotations.idempotent | No | false | Hint that calling the tool repeatedly with the same arguments has no additional effect. Only meaningful when readOnly is false. |
annotations.returnDirect | No | false | When true, the AI agent forwards the raw tool output to the user without further interpretation or summarization. |
Annotations are informational hints for MCP clients. They do not affect execution behavior.
A flow can be registered on exactly one MCP server at a time via the mcpServer property. Multiple flows can share the same server, each appearing as a separate tool.
Writing effective tool descriptions
The toolDescription is what the AI agent reads to decide whether to call your tool. Describe when and why to invoke the flow, not just what it does. For example:
toolDescription: > Returns a personalised greeting for a named user. Call this tool whenever the user asks to be greeted or wants a welcome message.Common trigger properties
McpToolTrigger supports all common trigger properties, including when (a Pebble guard evaluated before invoking the flow) and inputs (values passed to flow inputs on each invocation).
Input and output mapping
Flow inputs and outputs are automatically mapped to the MCP tool’s input and output schema.
- Each flow
inputbecomes a tool parameter. Thedescriptionfield on the input is passed to the AI agent as the parameter description. - Flow
outputsare returned in the tool response. Each output’sdisplayNameis used as the label in the response.
To constrain the structure of a JSON-type input, use the jsonSchema property. See JSON input validation.
Observability
Every execution created via MCP carries these system labels:
| Label | Value |
|---|---|
system.from | mcp |
system.mcpServerId | The id of the MCP server that invoked the tool |
system.mcpSessionId | The session ID of the MCP client connection |
Filter executions by system.from: mcp in the Executions view to see all MCP-triggered runs.
Was this page helpful?