Codex
Run the Codex coding agent inside a VM with skills, MCP servers, and custom configuration.
Quick start
import { agentOS, setup } from "@rivet-dev/agentos";
import codex from "./software/codex";
const vm = agentOS({ software: [codex] });
export const registry = setup({ use: { vm } });
registry.start();
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// ── Quick start ───────────────────────────────────────────────────
async function quickStart() {
const sessionId = await agent.createSession("codex", {
env: { OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
});
const { text } = await agent.sendPrompt(
sessionId,
"What files are in the current directory?",
);
console.log(text);
}
Read Sessions first for session options, streaming events, prompts, and lifecycle management.
LLM Credentials
Set the relevant variable(s) on the session’s env, sourced from your server’s environment:
OPENAI_API_KEY— OpenAI API key (built-inopenaiprovider).OPENAI_BASE_URL— route through a gateway or OpenAI-compatible endpoint.- Custom providers — defined in
~/.codex/config.toml; each provider’senv_keynames the variable Codex reads for its key (e.g.AZURE_OPENAI_API_KEY,MISTRAL_API_KEY).
See LLM Credentials, and Codex’s config reference for details.
Skills
Codex discovers SKILL.md files from its skills directory. Write the skill into the VM before creating a session and Codex loads it automatically.
// ── Skills ────────────────────────────────────────────────────────
//
// Write a SKILL.md into the agent's skills directory before creating the
// session and the agent discovers it automatically.
async function withSkill() {
const skill = `---
name: commit-style
description: How to write commit messages in this project.
---
Write commit messages in the imperative mood and keep the subject under 50 characters.
`;
await agent.mkdir("/home/agentos/.codex/skills/commit-style");
await agent.writeFile("/home/agentos/.codex/skills/commit-style/SKILL.md", skill);
const sessionId = await agent.createSession("codex", {
env: { OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
});
console.log(sessionId);
}
MCP servers
Expose extra tools to the agent by passing mcpServers to createSession. Both local child-process servers and remote URLs are supported.
// ── MCP servers ───────────────────────────────────────────────────
//
// Codex reads MCP servers from its own config file. Write a `config.toml`
// into the VM before creating the session — local child-process servers and
// remote URLs are both supported.
async function withMcp() {
// Pre-install the MCP server so `npx` is silent — first-run install output
// would otherwise corrupt the MCP stdio handshake ("Connection closed").
await agent.exec("npm install -g @modelcontextprotocol/server-filesystem");
const config = `[mcp_servers.filesystem]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/home/agentos"]
[mcp_servers.example]
url = "https://mcp.example.com/sse"
http_headers = { Authorization = "Bearer my-token" }
`;
await agent.writeFile("/home/agentos/.codex/config.toml", config);
const sessionId = await agent.createSession("codex", {
env: { OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
});
console.log(sessionId);
}
Pre-install npx-launched servers. A local server started with npx -y … writes install progress to stdout on its first run, which corrupts the MCP stdio handshake (you’ll see Connection closed). Pre-install it in the VM so npx is silent — await agent.exec("npm install -g @modelcontextprotocol/server-filesystem") before the session — or pin the package and point command at the installed binary.
Customizing the agent
Codex is a built-in agent, but it’s just a software package under the hood. To ship your own ACP adapter, swap the underlying agent SDK, or register a tweaked build as a new agent, see Custom Agents.