MCP Server - Expose Scenarios

The Meta Agents Research Environments MCP Server enables you to expose any Meta Agents Research Environments app or complete scenario as a Model Context Protocol (MCP) server, making Meta Agents Research Environments functionality accessible to external agentic tools like Cursor, Claude Desktop, and other MCP-compatible clients.

Overview

While the MCPApp - Model Context Protocol allows Meta Agents Research Environments to connect to external MCP servers, the Meta Agents Research Environments MCP Server does the opposite - it exposes Meta Agents Research Environments apps and scenarios as MCP servers that can be accessed by any MCP client.

This powerful capability enables you to:

  • Test scenarios with different agents: Use Claude Desktop, Cursor, or other agentic tools to interact with Meta Agents Research Environments scenarios

  • Integrate Meta Agents Research Environments into development workflows: Access Meta Agents Research Environments apps directly from your IDE or development tools

  • Create hybrid agent systems: Combine Meta Agents Research Environments simulated environments with external AI agents

  • Validate scenario quality: Test scenarios with multiple different agent implementations

Key Features

  • Universal App Exposure: Expose any Meta Agents Research Environments app as an MCP server

  • Complete Scenario Support: Load entire scenarios with all their apps and state

  • Automatic Tool Discovery: All Meta Agents Research Environments app tools are automatically exposed as MCP tools

  • State Monitoring: Real-time access to app states through MCP resources

  • Rich Metadata: Detailed tool information and parameter descriptions

  • Multiple Transports: Support for both stdio and Server-Sent Events (SSE) connections

  • State Change Notifications: Automatic notifications when app states change

Architecture

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  External Tool  │    │   ARE MCP       │    │   ARE Apps/     │
│  (Cursor, etc.) │◄──►│  Server         │◄──►│  Scenarios      │
│                 │    │                 │    │                 │
│ • Claude Desktop│    │ • Tool Exposure │    │ • Calendar      │
│ • Cursor        │    │ • State Monitor │    │ • Email         │
│ • Custom Client │    │ • Notifications │    │ • File System   │
└─────────────────┘    └─────────────────┘    └─────────────────┘

Installation

The MCP Server is included with the Meta Agents Research Environments package. Ensure you have the required dependencies:

# Install ARE with MCP support
uv pip install meta-agents-research-environments

# Install MCP CLI tools (if not already included)
uv pip install "mcp[cli]"

Usage

Command-Line Interface

Expose Individual Apps

uv run are_simulation_mcp_server.py --apps <app_class1> <app_class2> ... [options]

Expose Complete Scenarios

uv run are_simulation_mcp_server.py --scenario <scenario_id> [options]

Options

  • --name <server_name>: Optional name for the MCP server

  • --transport {stdio|sse}: Choose transport method (default: stdio)

Examples

Calendar App Server

uv run are_simulation_mcp_server.py --apps are.simulation.apps.calendar.CalendarApp --name "Calendar MCP Server"

Multiple Apps Server

uv run are_simulation_mcp_server.py --apps are.simulation.apps.calendar.CalendarApp are.simulation.apps.email_client.EmailClientApp --name "Productivity Suite"

Complete Scenario Server

uv run are_simulation_mcp_server.py --scenario scenario_tutorial --transport sse

Using with MCP Inspector

npx @modelcontextprotocol/inspector are_simulation_mcp_server.py --scenario scenario_tutorial

Integration with External Tools

Claude Desktop Integration

Add the Meta Agents Research Environments MCP Server to your Claude Desktop configuration:

{
  "mcpServers": {
    "are-calendar": {
      "command": "python",
      "args": [
        "/path/to/are_simulation_mcp_server.py",
        "--apps",
        "are.simulation.apps.calendar.CalendarApp",
        "--name",
        "Meta Agents Research Environments Calendar"
      ]
    },
    "are-scenario": {
      "command": "python",
      "args": [
        "/path/to/are_simulation_mcp_server.py",
        "--scenario",
        "scenario_tutorial"
      ]
    }
  }
}

Cursor Integration

Configure Cursor to use Meta Agents Research Environments MCP Server for testing scenarios:

{
  "mcp": {
    "servers": {
      "are.simulation": {
        "command": "python",
        "args": ["/path/to/are_simulation_mcp_server.py", "--scenario", "your_scenario"]
      }
    }
  }
}

Available Resources

The Meta Agents Research Environments MCP Server exposes several MCP resources for monitoring and introspection:

Global Resources

  • app://info: Information about all exposed apps and their tools

App-Specific Resources

For each app, the following resources are available:

  • app://{app_name}/info: General information about the specific app

  • app://{app_name}/state: Current state of the app (updated in real-time)

Testing Scenarios with External Agents

The Meta Agents Research Environments MCP Server enables powerful testing workflows where you can validate your

scenarios using different AI agents and tools.

Scenario Testing Workflow

  1. Develop Scenario: Create your Meta Agents Research Environments scenario with apps and validation logic

  2. Expose via MCP: Use Meta Agents Research Environments MCP Server to expose the scenario

  3. Test with Multiple Agents: Connect different agentic tools to test the scenario

  4. Compare Results: Analyze how different agents perform on the same scenario

  5. Iterate and Improve: Refine scenarios based on multi-agent testing results

Example Testing Setup

# Terminal 1: Start Meta Agents Research Environments MCP Server with your scenario
uv run are_simulation_mcp_server.py --scenario my_test_scenario --transport sse

# Terminal 2: Test with Claude Desktop (configured to connect to the server)
# Use Claude Desktop to interact with the scenario

# Terminal 3: Test with custom agent
python my_custom_agent.py --mcp-server http://localhost:8000/sse

Benefits for Scenario Development

  • Multi-Agent Validation: Test scenarios with different reasoning approaches

  • Real-World Integration: See how scenarios perform with production AI tools

  • Debugging Support: Monitor app states and tool calls in real-time

  • Rapid Iteration: Quickly test scenario changes across multiple agents

API Reference

Meta Agents Research Environments MCP Server - Expose multiple Meta Agents Research Environments apps as an MCP server.

This script creates an MCP server that wraps multiple Meta Agents Research Environments apps, exposing the apps’ tools as MCP tools. This allows any MCP client to interact with Meta Agents Research Environments apps.

Usage:

python are_simulation_mcp_server.py –apps <app_class1> <app_class2> … [–name <server_name>] [–transport sse|stdio] python are_simulation_mcp_server.py –scenario <scenario_id> [–name <server_name>] [–transport sse|stdio]

Example:

python are_simulation_mcp_server.py –apps are.simulation.apps.calendar.CalendarApp are.simulation.apps.email.EmailApp –name “Meta Agents Research Environments MCP Server” python are_simulation_mcp_server.py –scenario scenario_mz_dinner –transport sse

class are.simulation.apps.mcp.server.are_simulation_mcp_server.ARESimulationToolManager(apps)[source]

Bases: ToolManager

A custom ToolManager for Meta Agents Research Environments apps that creates MCP tools from Meta Agents Research Environments AppTool objects. The normal tool manager gets confused parsing the signature of the AppTool function and we already have all the information we need to create the tool, so we can just create the tool directly.

Initialize the ARESimulationToolManager.

Parameters:

apps (Sequence[App]) – A sequence of Meta Agents Research Environments apps to expose tools from

class are.simulation.apps.mcp.server.are_simulation_mcp_server.ARESimulationMCPServer(apps=None, server_name=None, scenario=None)[source]

Bases: object

A class that creates an MCP server wrapping multiple Meta Agents Research Environments apps.

This class takes multiple Meta Agents Research Environments apps and exposes their tools as MCP tools, allowing any MCP client to interact with the apps.

Initialize the Meta Agents Research Environments MCP Server.

Parameters:
  • apps (Optional[Sequence[App]]) – A sequence of Meta Agents Research Environments apps to wrap. If scenario is provided, this parameter is ignored.

  • server_name (Optional[str]) – Optional name for the MCP server. Defaults to “Meta Agents Research Environments MCP Server”.

  • scenario (Optional[Scenario]) – Optional scenario to load apps and their states from.

get_app_by_name(app_name)[source]

Get an app by name.

Parameters:

app_name (str) – The name of the app.

Returns:

The app instance or None if not found.

Return type:

App or None

run(transport='stdio')[source]

Run the MCP server.

are.simulation.apps.mcp.server.are_simulation_mcp_server.load_scenario_class(scenario_class_path)[source]

Load a Scenario class from its fully qualified path.

Parameters:

scenario_class_path (str) – The fully qualified path to the scenario class (e.g., “are.simulation.scenarios.calendar.CalendarScenario”).

Returns:

The scenario class.

Return type:

Type[Scenario]

Raises:
  • ImportError – If the scenario class cannot be imported.

  • TypeError – If the imported class is not a subclass of Scenario.

are.simulation.apps.mcp.server.are_simulation_mcp_server.load_app_class(app_class_path)[source]

Load a Meta Agents Research Environments app class from its fully qualified path.

Parameters:

app_class_path (str) – The fully qualified path to the app class (e.g., “are.simulation.apps.calendar.CalendarApp”).

Returns:

The app class.

Return type:

Type[App]

Raises:
  • ImportError – If the app class cannot be imported.

  • TypeError – If the imported class is not a subclass of App.

ARESimulationMCPServer Class

class are.simulation.apps.mcp.server.are_simulation_mcp_server.ARESimulationMCPServer(apps=None, server_name=None, scenario=None)[source]

Bases: object

A class that creates an MCP server wrapping multiple Meta Agents Research Environments apps.

This class takes multiple Meta Agents Research Environments apps and exposes their tools as MCP tools, allowing any MCP client to interact with the apps.

Initialize the Meta Agents Research Environments MCP Server.

Parameters:
  • apps (Optional[Sequence[App]]) – A sequence of Meta Agents Research Environments apps to wrap. If scenario is provided, this parameter is ignored.

  • server_name (Optional[str]) – Optional name for the MCP server. Defaults to “Meta Agents Research Environments MCP Server”.

  • scenario (Optional[Scenario]) – Optional scenario to load apps and their states from.

__init__(apps=None, server_name=None, scenario=None)[source]

Initialize the Meta Agents Research Environments MCP Server.

Parameters:
  • apps (Optional[Sequence[App]]) – A sequence of Meta Agents Research Environments apps to wrap. If scenario is provided, this parameter is ignored.

  • server_name (Optional[str]) – Optional name for the MCP server. Defaults to “Meta Agents Research Environments MCP Server”.

  • scenario (Optional[Scenario]) – Optional scenario to load apps and their states from.

get_app_by_name(app_name)[source]

Get an app by name.

Parameters:

app_name (str) – The name of the app.

Returns:

The app instance or None if not found.

Return type:

App or None

run(transport='stdio')[source]

Run the MCP server.

ARESimulationToolManager Class

class are.simulation.apps.mcp.server.are_simulation_mcp_server.ARESimulationToolManager(apps)[source]

Bases: ToolManager

A custom ToolManager for Meta Agents Research Environments apps that creates MCP tools from Meta Agents Research Environments AppTool objects. The normal tool manager gets confused parsing the signature of the AppTool function and we already have all the information we need to create the tool, so we can just create the tool directly.

Initialize the ARESimulationToolManager.

Parameters:

apps (Sequence[App]) – A sequence of Meta Agents Research Environments apps to expose tools from

Inherits from mcp.server.fastmcp.tools.tool_manager.ToolManager.

__init__(apps)[source]

Initialize the ARESimulationToolManager.

Parameters:

apps (Sequence[App]) – A sequence of Meta Agents Research Environments apps to expose tools from

Utility Functions

are.simulation.apps.mcp.server.are_simulation_mcp_server.load_app_class(app_class_path)[source]

Load a Meta Agents Research Environments app class from its fully qualified path.

Parameters:

app_class_path (str) – The fully qualified path to the app class (e.g., “are.simulation.apps.calendar.CalendarApp”).

Returns:

The app class.

Return type:

Type[App]

Raises:
  • ImportError – If the app class cannot be imported.

  • TypeError – If the imported class is not a subclass of App.

are.simulation.apps.mcp.server.are_simulation_mcp_server.load_scenario_class(scenario_class_path)[source]

Load a Scenario class from its fully qualified path.

Parameters:

scenario_class_path (str) – The fully qualified path to the scenario class (e.g., “are.simulation.scenarios.calendar.CalendarScenario”).

Returns:

The scenario class.

Return type:

Type[Scenario]

Raises:
  • ImportError – If the scenario class cannot be imported.

  • TypeError – If the imported class is not a subclass of Scenario.

Referenced Classes

class are.simulation.apps.app.App(name=None, *args, **kwargs)[source]

Bases: ABC, SkippableDeepCopy

Base class for all applications in the Meta Agents Research Environments environment.

register_time_manager(time_manager)[source]
set_seed(seed)[source]
Return type:

None

register_to_env(key, add_event)[source]
add_event(event)[source]
Return type:

None

get_implemented_protocols()[source]

App can provide protocols, e.g. FileSystem which could be used by other apps Returns a list of protocol names that the app implements.

Return type:

list[Protocol]

connect_to_protocols(protocols)[source]

App can connect to other apps via protocols.

Return type:

None

get_state()[source]
Return type:

dict[str, Any] | None

load_state(state_dict)[source]
reset()
app_name()[source]
Return type:

str

set_failure_probability(failure_probability)[source]
Return type:

None

get_tools_with_attribute(attribute, tool_type)[source]

Retrieves a list of tools that have a specific attribute from the class and its base classes.

Parameters:
  • attribute (ToolAttributeName) – The attribute to look for in the tools as a ToolAttributeName enum value.

  • tool_type (ToolType) – The type of tool being registered.

Returns:

A list of AppTool objects that have the specified attribute.

Return type:

list[AppTool]

get_tools()[source]

Retrieves the list of agent tools, initializing the tool registry if necessary.

Return type:

list[AppTool]

Returns:

A list of AppTool objects for agents.

get_user_tools()[source]

Retrieves the list of user tools, initializing the user tool registry if necessary.

Return type:

list[AppTool]

Returns:

A list of AppTool objects for users.

get_env_tools()[source]

Retrieves the list of environment tools, initializing the environment tool registry if necessary.

Return type:

list[AppTool]

Returns:

A list of AppTool objects for the environment.

get_tool(tool_name)[source]

Retrieves a specific tool by name, searching through all tool types.

Parameters:

tool_name (str) – The name of the tool to retrieve.

Returns:

The AppTool object with the specified name, or None if not found.

Return type:

AppTool | None

get_data_tools()[source]

Retrieves the list of data tools, initializing the data tool registry if necessary.

Return type:

list[AppTool]

Returns:

A list of AppTool objects for data.

pause_env()[source]
Return type:

None

resume_env()[source]
Return type:

None

class are.simulation.scenarios.scenario.Scenario(_initialized=False, is_benchmark_ready=False, events=<factory>, apps=None, tags=<factory>, scenario_id='', seed=0, nb_turns=None, run_number=None, config=None, has_a2a_augmentation=False, status=ScenarioStatus.Draft, comment=None, annotation_id=None, hints=None, additional_system_prompt=None, start_time=<factory>, duration=None, queue_based_loop=False, time_increment_in_seconds=1, working_dir='', _initial_apps=None, tool_augmentation_config=None, env_events_config=None, gui_config=None, augmentation_data=<factory>)[source]

Bases: object

is_benchmark_ready: bool = False
events: list[AbstractEvent]
apps: list[App] | None = None
tags: tuple[CapabilityTag, ...]
scenario_id: str = ''
seed: int = 0
nb_turns: int | None = None
run_number: int | None = None
config: str | None = None
has_a2a_augmentation: bool = False
status: ScenarioStatus = 'Draft'
comment: str | None = None
annotation_id: str | None = None
hints: list[Hint] | None = None
additional_system_prompt: str | None = None
start_time: float | None
duration: float | None = None
queue_based_loop: bool = False
time_increment_in_seconds: int = 1
working_dir: str = ''
tool_augmentation_config: ToolAugmentationConfig | None = None
env_events_config: EnvEventsConfig | None = None
gui_config: ScenarioGUIConfig | None = None
augmentation_data: dict[str, Any]
initialize(*args, **kwargs)[source]
Return type:

None

soft_reset()[source]
reset_apps(new_apps)[source]
init_and_populate_apps(*args, **kwargs)[source]

Initialize the apps that will be used in the Scenario.

Return type:

None

build_events_flow()[source]

Core logic of the scenario, this is where the scenario is built. Where events are scheduled, event triggers are defined, as well as any element of the task. By default, this function is empty, and should be overridden by the scenario if any extra logic is needed.

Return type:

None

get_app(app_name)[source]

Get the app with the given name

Return type:

App

get_typed_app(app_type, app_name=None)[source]

Get the app with the given type and optional name. If name is not provided, it will be inferred from the app type.

Return type:

TypeVar(T, bound= App)

get_tools_by_app()[source]

Get for each app, the list of tools it has.

Return type:

dict[str, list[AppTool]]

get_tools()[source]

Get the entire list of tools from all the apps.

Return type:

list[AppTool]

get_user_tools_by_app()[source]

Get for each app, the list of tools it has that are accessible to the User.

Return type:

dict[str, list[AppTool]]

get_user_tools()[source]

Get the entire list of User tools from all the apps.

Return type:

list[AppTool]

is_send_message_to_user(event)[source]

Check if the event is a send message to user event

Return type:

bool

build_event_id_to_turn_idx()[source]

Build a dictionary to store the turn of each event The turn of an event is the number of event send_message_to_user among its ancestors The dictionary and the number of turns are stored to the scenario

get_env_tools_by_app()[source]

Get for each app, the list of tools it has that are accessible to the Environment.

Return type:

dict[str, list[AppTool]]

get_env_tools()[source]

Get the entire list of Env tools from all the apps.

Return type:

list[AppTool]

get_data_tools_by_app()[source]

Get for each app, the list of tools it has that are accessible to the Data.

Return type:

dict[str, list[AppTool]]

get_data_tools()[source]

Get the entire list of Data tools from all the apps.

Return type:

list[AppTool]

edit_hint_content(event_id, content)[source]

Edit the content of a hint.

validate(env)[source]

Validate the state of the environment after the scenario has been executed.

Return type:

ScenarioValidationResult

set_duration(duration)[source]

Set the duration of the scenario.

set_time_increment(time_increment_in_seconds)[source]

Set the time increment of the scenario.

delete_completed_events()[source]
Return type:

None

delete_event(event_id)[source]
Return type:

None

validate_predecessors(predecessor_event_ids, function_name, event_type, events)[source]
filter_connected_events(predecessor_event_ids, events)[source]

Filters out all events connected with the given predecessor_event_ids, including the predecessor events themselves, their successors and dependencies. :type predecessor_event_ids: list[str] :param predecessor_event_ids: List of event IDs to start filtering from. :type events: list[AbstractEvent] :param events: List of all events. :rtype: list[AbstractEvent] :return: List of events excluding those connected with the predecessor_event_ids.

Return type:

list[AbstractEvent]

validate_events_dag_aui_single_branch(predecessor_event_ids, function_name, events, event_id=None)[source]
accumulate_times_from_event(events, event_id=None, new_event_time=None, new_event_relative_time=None)[source]
Return type:

dict[str, float]

validate_events_dag_message_to_user_time(predecessor_event_ids, function_name, new_event_relative_time=None, new_event_time=None, event_id=None)[source]
add_event(app_name, function_name, parameters, predecessor_event_ids, event_type, event_id=None, event_relative_time=None, event_time=None, event_time_comparator=None)[source]
Return type:

AbstractEvent

edit_event(app_name, function_name, parameters, event_id, event_type, predecessor_event_ids, event_relative_time=None, event_time=None, event_time_comparator=None)[source]
Return type:

AbstractEvent

process_events(events)[source]
patch_oracle_user_message_order()[source]

Patches the event dependencies to ensure send_message_to_user events are executed last in each turn.

This method groups events by turns and ensures that send_message_to_user events depend on all other events with maximum accumulated time in the same turn. This guarantees that user messages are sent after all other operations in a turn are completed, maintaining proper execution order in oracle mode.

Return type:

None

apply_augmentation_configs()[source]