Build your first agent in just a few minutes with [Rasa Copilot](https://hello.rasa.com/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta).

### New Beta Feature in 3.14

Rasa supports native integration of MCP servers.

This feature is in a beta (experimental) stage and may change in future Rasa versions. We welcome your feedback on this feature.

## Overview

Rasa integrates with [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers to connect your agent to external APIs, databases, and other services. MCP servers expose tools that your agent can [use directly in flows](/content/docs/pro/build/mcp-integration/#using-an-mcp-tool-in-a-flow/index.html) or provide to [ReAct style sub agents](/content/docs/pro/build/mcp-integration/#dynamic-selection-of-tools-in-an-autonomous-step/index.html) for dynamic decision-making.

## Defining an MCP Server

Define your MCP servers in the `endpoints.yml` file:

```yaml
mcp_servers:
  - name: trade_server
    url: http://localhost:8080
    type: http
```

For detailed information on available authentication methods and other parameters, head over to the [reference page](/content/docs/reference/integrations/mcp-servers/index.html).

To send server-side context on every tool call without exposing it to the LLM, configure optional [`meta_map`](/content/docs/reference/integrations/mcp-servers/#passing-metadata-to-tools-meta_map/index.html) on the MCP server in `endpoints.yml`.

## Using an MCP tool in a flow

Use MCP tools directly in flows with the [`call` step](/content/docs/reference/primitives/flow-steps/#calling-an-mcp-tool/index.html), specifying input/output mappings:

```yaml
flows:
  buy_order:
    description: helps users place a buy order for a particular stock
    steps:
    - collect: stock_name
    - collect: order_quantity
    - action: check_feasibility
      next:
        - if: slots.order_feasible is True
          then:
            - call: place_buy_order  # MCP tool name
              mcp_server: trade_server  # MCP server where tool is available
              mapping:
                input:
                - param: ticker_symbol  # tool parameter name
                  slot: stock_name      # slot to send as value
                - param: quantity
                  slot: order_quantity
                output:
                - slot: order_status     # slot to store results
                  value: result.structuredContent.order_status.success
        - else:
            - action: utter_invalid_order
              next: END
```

This way of directly invoking tools from flows avoids having to write any [custom action code](/content/docs/pro/build/custom-actions/index.html) just for the purpose of integrating with external APIs.

### Tool Results and Output Handling

MCP tools return results in two possible formats:

#### Structured Content

When tools provide an output schema (see [for example](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema)), you get structured data as output:

```json
{
  "result": {
    "structuredContent": {
      "order_status": {"success": true, "order_id": "bcde786f1"}
    }
  }
}
```

In such a case, specific values from the resulting dictionary can be accessed using the dot notation:

```yaml
  - call: place_buy_order
    mcp_server: trade_server
    ...
    output:
    - slot: order_status
      value: result.structuredContent.order_status.success
```

#### Unstructured Content

When the invoked tool has no output schema defined, the entire output is captured as a serialized string:

```json
{
  "result": {
    "content": [\
      {\
        "type": "text",\
        "text": "{\"order_status\": {\"success\": true, \"order_id\": \"bcde786f1\"}"\
      }\
    ],
  }
}
```

You can still use the dot notation to capture the output but the complete serialized string will have to be captured in the slot.

```yaml
output:
- slot: order_data
  value: result.content
```

## Dynamic selection of tools in an autonomous step

Flows can also contain [**autonomous** steps](/content/docs/reference/primitives/flow-steps/#autonomous-steps/index.html), where the business logic is dynamically determined at runtime, based on the available context and tools from the MCP server. In order to do so, Rasa requires the creation of [ReAct sub agents](/content/docs/reference/config/agents/react-sub-agents/index.html).

### Sub agent Configuration

Each sub agent that has access to MCP tools operates in a [ReAct](https://arxiv.org/abs/2210.03629) loop, determining which tools to call based on the conversation context.

To create a sub agent, add a folder specific to that agent in the `sub_agents/` directory of your Rasa agent:

```text
your_project/
├── config.yml
├── domain/
├── data/flows/
└── sub_agents/
    └── stock_explorer/
        ├── config.yml
        └── prompt_template.jinja2  # optional
```

Configure the agent in `sub_agents/stock_explorer/config.yml`:

```yaml
# Basic agent information
agent:
  name: stock_explorer
  description: "Agent that helps users research and analyze stock options"

# MCP server connections
connections:
  mcp_servers:
  - name: trade_server
    include_tools:   # optional - specify which tools to include
    - find_symbol
    - get_company_news
    - apply_technical_analysis
    - fetch_live_price
    exclude_tools:   # optional - tools to exclude
    - place_buy_order
    - view_positions
```

Add a `configuration` block when you need LLM settings, [intermediate messages](/content/docs/reference/config/agents/react-sub-agents/#intermediate-messages/index.html) (enabled by default for ReAct; implemented as tool acknowledgements), or other options.

More details on available configuration parameters can be found in the [reference section](/content/docs/reference/config/agents/react-sub-agents/#configuration/index.html).

### Invoking a sub agent

A sub agent can be invoked from a flow using the [`call` step](/content/docs/reference/primitives/flow-steps/#autonomous-steps/index.html):

```yaml
flows:
  stock_investment_research:
    description: helps research and analyze stock investment options
    steps:
    - call: stock_explorer  # runs until agent signals completion
```

A sub agent remains active until it signals a completion by itself or meets a defined criteria, for e.g. -

```yaml
flows:
  stock_investment_research:
    description: helps research and analyze stock investment options
    steps:
    - call: stock_explorer
      exit_if:
        - slots.user_satisfied is True
```

Here, `stock_explorer` agent will keep running until the `user_satisfied` slot is set to `True`.

To read more details about the runtime execution of a ReAct style sub agent inside Rasa, head over to the [reference documentation](/content/docs/reference/config/agents/overview-agents/#how-rasa-interacts-with-sub-agents/index.html).

### Selective Tool Access

You can have fine-grained control over the specific MCP tools a sub agent can access by using the `include_tools` and `exclude_tools` properties in the agent configuration:

```yaml
connections:
  mcp_servers:
  - name: trade_server
    include_tools:     # only allow specific tools
    - find_symbol
    - get_company_news
    exclude_tools:     # explicitly block dangerous operations
    - place_buy_order
    - delete_account
  - name: analytics_server
    exclude_tools:     # block admin-only tools
    - admin_analytics
```

### Customization

A React style sub agent's behavior can be customized by one of three modes:

1. **Custom prompt templates** - Include specific instructions and slot context
2. **Python customization modules** - Override agent behavior with custom python classes
3. **Additional tools** - Add Python-based tools alongside existing tools from MCP servers

See the [Sub Agents Reference](/content/docs/reference/config/agents/react-sub-agents/#customization/index.html) for detailed customization options.

## Error handling

When an MCP tool call or sub agent call fails at runtime, Rasa cancels the active flow and triggers [`pattern_internal_error`](/content/docs/reference/primitives/patterns/index.html). The pattern frame exposes structured context in `context.info` so you can customize the user-facing response—for example by tool name, agent name, or failure type. See the [`context.info` field reference](/content/docs/reference/primitives/patterns/#handling-agent-and-mcp-tool-failures/index.html) for available keys.

Override `pattern_internal_error` in your `flows.yml` and branch on `context.info.error_source`, or on a specific `context.info.tool_name` or `context.info.agent_name`. See [Handling agent and MCP tool failures](/content/docs/reference/primitives/patterns/#handling-agent-and-mcp-tool-failures/index.html) for a complete example.

## Best Practices

### MCP Server Setup

- Define servers in `endpoints.yml` for consistency with other Rasa endpoints.
- Use descriptive server names that indicate their purpose.
- Ensure MCP servers are accessible from your Rasa environment.

### Tool Usage in Flows

- Always account for both structured and unstructured response content from tools.
- Use clear parameter and slot names for maintainability.

### Security Considerations

- Use `include_tools` to provide only necessary tools for security.
- Use `exclude_tools` to block sensitive or dangerous operations.
- Set clear exit conditions to prevent infinite loops.
- Limit context sharing to necessary slots only.
- Prefer [`pre_call_hook`](/content/docs/reference/integrations/mcp-servers/#call-time-credential-hooks-pre_call_hook/index.html) on MCP servers (and [`build_custom_tool_call_metadata`](/content/docs/reference/config/agents/react-sub-agents/#call-time-credentials-for-custom-tools/index.html) for ReAct custom tools) for per-conversation secrets: credentials are resolved only at outbound call time and are not stored in slots or the tracker.
- Use [`meta_map`](/content/docs/reference/integrations/mcp-servers/#passing-metadata-to-tools-meta_map/index.html) for static, non-secret server context (API version labels, non-sensitive identifiers from slots). Those values are not part of tool schemas shown to the LLM, and Rasa avoids logging or telemetry leakage of metadata values (key names only where needed).
- Regularly audit agent permissions and access to tools.
