Buckets:
| # Simulation vs Production Mode | |
| OpenEnv has two related but different ideas of "mode": | |
| - **Simulation mode** is for training, evaluation, and any workflow where the orchestrator controls episode boundaries. | |
| - **Production mode** is for exposing tools directly to clients over MCP without the training loop controlling `reset()`, `step()`, or `state()`. | |
| This guide explains when to use each mode and how they interact with MCP tools. | |
| ## The Short Version | |
| Use **simulation mode** when you need: | |
| - `reset()`, `step()`, and `state()` | |
| - rewards and `done` signals | |
| - one action per step in a controlled trajectory | |
| - training or evaluation loops | |
| Use **production mode** when you need: | |
| - direct MCP tool access | |
| - no simulation control routes | |
| - an agent or client talking to tools as a live service | |
| - the environment to get out of the way and expose the tool interface directly | |
| ## Why OpenEnv Has Two Modes | |
| This split follows the core OpenEnv design principles: | |
| - training and evaluation need a controlled step loop | |
| - production integrations need direct tool access | |
| - the same environment should support both without inventing separate environment implementations | |
| In practice, simulation mode models **trajectory time** and production mode models **service time**. | |
| ## Simulation Mode | |
| Simulation mode is the default environment-control model. | |
| In simulation mode, the orchestrator owns the episode: | |
| 1. Call `reset()` to start an episode. | |
| 2. Call `step()` for each action. | |
| 3. Read `reward`, `done`, and `state()` as part of the rollout. | |
| For environments with MCP tools, the canonical simulation-mode pattern is still `step()`. | |
| ```python | |
| from openenv.core.env_server.mcp_types import CallToolAction, ListToolsAction | |
| obs = env.step(ListToolsAction()) | |
| obs = env.step( | |
| CallToolAction( | |
| tool_name="echo_message", | |
| arguments={"message": "Hello from simulation mode"}, | |
| ) | |
| ) | |
| ``` | |
| That pattern matters because the training loop can then: | |
| - count tool usage as actions | |
| - assign rewards to tool interactions | |
| - record a full trajectory | |
| - preserve the same `reset`/`step` contract across environments | |
| ### Simulation-Mode Routes | |
| When an `HTTPEnvServer` registers routes in simulation mode, it exposes the full control surface: | |
| - `/ws` | |
| - `/mcp` | |
| - `/reset` | |
| - `/step` | |
| - `/state` | |
| This is the right mode for RL training infrastructure and for most environment testing. | |
| ## Production Mode | |
| Production mode is for exposing tools directly. | |
| In production mode, clients should interact with MCP tools as a service instead of driving the environment through `reset()` and `step()` as a trajectory loop. | |
| Production mode keeps the MCP surface and removes the HTTP simulation control routes. | |
| ### Production-Mode Routes | |
| When an `HTTPEnvServer` registers routes in production mode, OpenEnv does **not** expose: | |
| - `/reset` | |
| - `/step` | |
| - `/state` | |
| It still registers `/ws`, because the WebSocket transport remains part of the infrastructure boundary. | |
| That does **not** mean `/ws` should be exposed to agents. | |
| - `/ws` is for orchestration and simulation control | |
| - `/mcp` is the agent-facing boundary | |
| - production deployments should restrict `/ws` at the network, auth, or gateway layer if agents can reach the service directly | |
| In other words, production mode removes the HTTP simulation endpoints, but operators must still treat `/ws` as infrastructure-only. | |
| This is the right mode when: | |
| - you are serving a tool-backed environment to external clients | |
| - you do not want callers controlling episode boundaries | |
| - the MCP interface is the product surface | |
| ## How MCP Fits Into Both Modes | |
| MCP is available in both modes, but the role is different. | |
| ### In simulation mode | |
| MCP tools are part of the environment action space. | |
| - tool discovery can still happen | |
| - tool calls are modeled as actions | |
| - rewards and episode control remain in the OpenEnv loop | |
| This is why examples such as `examples/echo_mcp_demo.py` use `ListToolsAction` and `CallToolAction` through `step()`. | |
| ### In production mode | |
| MCP is the primary interface. | |
| - clients call tools directly | |
| - OpenEnv does not present simulation-control endpoints | |
| - the service behaves like a live MCP endpoint, not an RL rollout loop | |
| ## Server-Side Configuration | |
| The server-side switch happens when routes are registered. | |
| ```python | |
| from fastapi import FastAPI | |
| from openenv.core.env_server.http_server import HTTPEnvServer | |
| from openenv.core.env_server.types import ServerMode | |
| app = FastAPI() | |
| server = HTTPEnvServer(env=MyEnv, action_cls=MyAction, observation_cls=MyObservation) | |
| # Training / evaluation | |
| server.register_routes(app, mode=ServerMode.SIMULATION) | |
| # Direct MCP serving | |
| server.register_routes(app, mode=ServerMode.PRODUCTION) | |
| ``` | |
| `ServerMode.SIMULATION` is the default route-registration mode. | |
| ## Client-Side Patterns | |
| For simulation-style interaction, use a client that participates in the OpenEnv control loop. | |
| Examples: | |
| - an environment-specific `EnvClient[...]` subclass | |
| - `GenericEnvClient(base_url=..., mode="simulation")` | |
| - `step(ListToolsAction())` and `step(CallToolAction(...))` for MCP-backed environments | |
| For direct MCP access, use an MCP-oriented client. | |
| Examples: | |
| - `MCPToolClient(base_url=...)` | |
| - environment-specific clients built on top of `MCPToolClient` | |
| `MCPToolClient` defaults to production mode and rejects `mode="simulation"`. | |
| ## Mode-Aware Tools | |
| `MCPEnvironment` supports mode-aware tool registration, so you can expose different tools depending on how the environment is being used. | |
| ```python | |
| class MyEnv(MCPEnvironment): | |
| def __init__(self): | |
| @self.tool(mode="simulation") | |
| def score_candidate(answer: str) -> str: | |
| return "Used inside the training loop" | |
| @self.tool(mode="production") | |
| def lookup_docs(query: str) -> str: | |
| return "Used by live MCP clients" | |
| ``` | |
| This lets one environment preserve the training contract while still serving a cleaner production surface. | |
| ## Choosing the Right Mode | |
| Choose **simulation mode** if the caller needs to control trajectories. | |
| Typical cases: | |
| - RL training | |
| - policy evaluation | |
| - benchmarking with rewards | |
| - environments where tool calls should count as agent actions | |
| Choose **production mode** if the caller needs direct tool access. | |
| Typical cases: | |
| - agent runtimes that speak MCP directly | |
| - demos and hosted services | |
| - integrations where `reset()` and `step()` should not be public | |
| ## Common Mistake | |
| The most common confusion is assuming that "MCP environment" automatically means "production mode only". | |
| That is not the model OpenEnv uses. | |
| - An MCP-backed environment can still run in **simulation mode**. | |
| - In simulation mode, MCP tool interactions are represented through the OpenEnv step loop. | |
| - Production mode changes the public control surface, not the underlying environment concept. | |
| ## Related Reading | |
| - [Core API](../reference/core) | |
| - [Getting Started Tutorials](../tutorials/index) | |
| - [RFC 002: Environment Spec](https://github.com/huggingface/OpenEnv/blob/main/rfcs/002-env-spec.md) | |
| - [RFC 005: Agentic Harnesses](https://github.com/huggingface/OpenEnv/blob/main/rfcs/005-agentic-harnesses.md) | |
Xet Storage Details
- Size:
- 7.13 kB
- Xet hash:
- c25867c499ff748413f655f8aecb6ae0dc991784452436f641c0c38024f06a2d
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.