Skip to main content
Agents

OpenCode

Run the OpenCode coding agent inside a VM with skills, MCP servers, and custom configuration.

Quick start

Read Sessions first for session options, streaming events, prompts, and lifecycle management.

LLM Credentials

OpenCode auto-detects a provider when its key is present on the session’s env, sourced from your server’s environment. Common variables:

  • ANTHROPIC_API_KEY — Anthropic (Claude), the default.
  • OPENAI_API_KEY — OpenAI.
  • OPENROUTER_API_KEY — OpenRouter.
  • GEMINI_API_KEY — Google Gemini.
  • GROQ_API_KEY — Groq.
  • …plus Amazon Bedrock, Azure, Google Vertex, and 70+ providers via models.dev.

See LLM Credentials, and OpenCode’s providers docs for the full list.

Model configuration

To pin a specific model — or point a provider at a custom endpoint — write an OpenCode config file into the VM before creating the session. OpenCode reads <HOME>/.config/opencode/opencode.json (the agent’s HOME is /home/agentos by default).

Two settings will silently produce an empty response if wrong:

  • The Anthropic provider baseURL must end in /v1 (https://api.anthropic.com/v1). Without /v1, OpenCode calls …/messages and Anthropic returns 404 Not Found.
  • The model must be a current model id. A retired id returns a 404 not_found_error and the turn ends with zero output.
// Write the config before creating the session
await agent.mkdir("/home/agentos/.config/opencode", { recursive: true });
await agent.writeFile(
  "/home/agentos/.config/opencode/opencode.json",
  JSON.stringify({
    $schema: "https://opencode.ai/config.json",
    model: "anthropic/claude-haiku-4-5-20251001", // use a current model id
    provider: {
      // The Anthropic baseURL MUST include /v1, or requests 404.
      anthropic: { options: { baseURL: "https://api.anthropic.com/v1" } },
    },
  }),
);

await agent.openSession({
  agent: "opencode",
  env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});

Skills

OpenCode discovers SKILL.md files from its skills directory. Write the skill into the VM before creating a session and OpenCode loads it automatically.

	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.
`;

	// Write the skill before creating the session
	await agent.mkdir("/home/agentos/.config/opencode/skills/commit-style");
	await agent.writeFile(
		"/home/agentos/.config/opencode/skills/commit-style/SKILL.md",
		skill,
	);

	// OpenCode discovers the skill automatically
	await agent.openSession({
		agent: "opencode",
		env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
	});

MCP servers

Expose extra tools to the agent by passing mcpServers to openSession. Both local child-process servers and remote URLs are supported.

const config = {
	mcp: {
		filesystem: {
			type: "local",
			command: [
				"npx",
				"-y",
				"@modelcontextprotocol/server-filesystem",
				"/home/agentos",
			],
			enabled: true,
		},
		example: {
			type: "remote",
			url: "https://mcp.example.com/sse",
			headers: { Authorization: "Bearer my-token" },
			enabled: true,
		},
	},
};

await agent.writeFile(
	"/home/agentos/.config/opencode/opencode.json",
	JSON.stringify(config, null, 2),
);

await agent.openSession({
	agent: "opencode",
	env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});

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

OpenCode 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.