Deploy on your own infrastructure: agents serve

agents serve deploys your agent with Studio, on infrastructure you host. It starts a long-running process, the worker, on your machine or in your cluster, that runs the agent's sessions. Mistral stores each session, so the work survives a crash, and your app opens sessions by the agent's name. The agent's tools run on infrastructure you control. Use it to run the agent in production on your own infrastructure, or to try what a deployment does.

How it works

How it works

  1. Your app, or agents chat, starts a session on the agent's name. Mistral stores the session and queues its turn.
  2. Your worker polls that queue and takes the turn.
  3. The worker runs the agent loop and the tools on your machine, calls the model, and records each finished step with Mistral. A worker that stops loses no finished step.

You need a project with an Agent that sets name=, and a MISTRAL_API_KEY whose user has a workspace role with Workflows access, such as Developer or Workspace Contributor; a workspace admin assigns it in the admin console: Organization > Workspaces > your workspace > Members, as agents deploy explains.

What the CLI loads

What the CLI loads

agents info, agents serve and agents deploy all need the same thing: the Agent object you built in Python. By default they look for agent in main.py, so a project that is a single main.py runs as it is:

from mistralai import agents

@agents.tool
async def get_weather(city: str) -> str:
    """Get the current weather in a city."""
    return f"It is 18°C and sunny in {city}."

agent = agents.Agent(
    model="mistral-large-4",
    name="hello-agent",
    instructions="You are a friendly agent. Greet the user in one sentence.",
    tools=[get_weather],
)

The CLI imports main.py, so code at its top level runs on load. Put the code that runs the agent from a script, such as asyncio.run(main()), under if __name__ == "__main__":.

To keep the agent somewhere else, declare it in pyproject.toml as module:attr: the module that defines it, then the variable that holds it:

[tool.mistralai.agents]
entrypoint = "src.service:support_agent"

The module is imported with the project root on the import path, so a module at the root works without the project being an installable package. Every command takes a project root as its argument, so agents serve ./hello-agent runs one you are not standing in.

The agent must be named

The agent must be named

Agent(...) has to set name= explicitly. It is the name agents serve registers and the name agents deploy routes on, so the CLI refuses to guess it:

Error
✕ main:agent must set an explicit name: `agents.Agent(model=..., name=...)`. The name is the deployed workflow name. Set it in code even when you pass `--name`.

The name is unique per workspace, not globally: serving or deploying hello-agent again from the same workspace updates that same agent, but another workspace's hello-agent is a separate one. So two people who serve hello-agent in one workspace share one agent: each session goes to either process, and runs that person's code. While you build, give each person their own name, for example agents serve --name hello-agent-ada.

A name that contains a dot, such as acme.bot, is reserved for the platform's own agents: Agent(...) raises agents.SdkError for it.

Serve the agent

Serve the agent

From the project's folder:

export MISTRAL_API_KEY="<your-key>"
agents serve                              # the project in the current directory
agents serve ./hello-agent --name hello-agent

agents serve runs a worker, registers the agent under its name, and prints where to try it:

Output
✓ Agent hello-agent is serving on agents-sdk-hello-agent
Try the agent:
• in Vibe Code Web: https://chat.mistral.ai/managed-agents/hello-agent
• programmatically, using the Session API: https://docs.mistral.ai/studio/agents/learn/sessions/sessions
Debug: https://console.mistral.ai/managed-agents/<agent-id>/sessions?shareContext=<share-context>
Press Ctrl+C to stop.

The Debug link opens the agent's sessions in the console. <agent-id> is the agent's ID, and <share-context> is your organization and workspace IDs, URL-encoded, so the console opens the right workspace.

--name overrides the agent's name=, which is also what sessions are routed on. In your app, open sessions on the served agent by that name:

from mistralai import agents

agent = agents.Agent.load_from(agent_name="hello-agent")

Stop agents serve and the agent stops answering, but Mistral stores the sessions. A running turn usually resumes from its last finished step once agents serve runs again. A tool call that was running is not made again by the SDK, but the model may call the tool again, so keep tools idempotent: see Durability.

Warning

Tools run on the machine that runs agents serve

Every session on this agent, whether it comes from Vibe Code Web or from the Session API, runs its tools on that machine. To isolate what the agent runs, give it a sandbox.

Try the agent by its name, from another terminal:

agents chat hello-agent
Output
Talking to hello-agent (session 01a1a89e-c09f-7043-85a7-af2170ff112d). Ctrl+D or /exit to quit.
> What is the weather in Paris?
It's currently 18°C and sunny in Paris! ☀️
Check what was loaded

Check what was loaded

agents info prints what the CLI loaded, and names the first thing it could not load. For the main.py above:

Output
hello-agent mistral-large-4
instructions You are a friendly agent. Greet the user in one sentence.
sandbox none
tools
client.get_weather
connectors (none)
mcps (none)
skills (none)
guardrails (none)
hooks (none)
subagents (none)
subagent policy (none)
permissions auto · no policy

Run it after you change the agent's tools, connectors or hooks. A tool that does not appear here does not appear to the model either. See agents info for its options.

Set the environment

Set the environment

Against production, agents serve needs only MISTRAL_API_KEY. To point one at another deployment, set MISTRAL_API_URL and AGENTS_SDK_DEPLOY_CONTROL_PLANE_URL together: see Environment.

By default, a self-hosted session ends after 4 hours idle, or after 24 hours in total. Change these limits with AGENTS_SDK_IDLE_TIMEOUT_SECONDS and AGENTS_SDK_LIFETIME_LIMIT_SECONDS, in seconds, up to a year each: see Session limits.

agents serve traces its turns to Mistral Studio by default: see See your sessions and traces, and Custom redaction to choose what the traces mask.

Code that replays

Code that replays

Once deployed, the agent loop is replayed whenever a worker picks a turn back up, for example after a restart. To read the time, sleep, or make ids and random numbers, use agents.now(), agents.sleep(), agents.uuid4() and agents.random(): they give the same answer on replay. Tools and the agent's hooks= run outside the loop, as recorded steps, and the four functions work there too. A sandbox hook and a redaction policy run in the loop: use the four functions there.

Common issues

Common issues

agents serve prints only warnings and the banner. Set AGENTS_SDK_DEBUG=1 for the full log, which names the Workflows API it resolved. LOG_LEVEL does not work here.

  • Cannot serve agent: MISTRAL_API_KEY was refused (HTTP 401). The next line reads agents serve needs a credential allowed to run agent workers in this workspace; check MISTRAL_API_KEY. The key is wrong, expired or revoked: check it, or create a new one.
  • Cannot serve agent: registration failed at https://api.mistral.ai/v2/agents: <detail>. No session reaches the agent until its name points at your agents serve process. <detail> names the cause:
    • the name hello-agent is already bound to another workflow or deployment. See Freeing a name.
    • Other causes: an agents API that is not enabled for the account, or a control-plane URL that does not end in /v2/agents, which fails with 404 Not Found.
  • The user associated with this worker credential does not have permission to use Workflows in this workspace. Ask a workspace admin to assign the key's user a role with Workflows access, such as Developer or Workspace Contributor, in the admin console: Organization > Workspaces > your workspace > Members. Then serve again.
  • MISTRAL_API_KEY is not set. Export it in your shell, or put it in .env and run uv run --env-file .env agents serve: the CLI does not read .env itself.
Next steps

Next steps