Aether

The open-source coding agent you control

Aether has no hardcoded prompts or tools, so you control every token in context. Embrace MCP without bloat, and go from minimal to batteries-included in a few lines of config. Use it in a TUI, IDE, headlessly, or as a Rust/TS library.

Terminal window
$ brew install contextbridge/tap/aether
Terminal window
$ curl -fsSL aether-agent.io/install | sh
Terminal window
$ cargo install aether-agent-cli

Use any LLM you want, cloud or local

You can bring your own too.

Cloud

Anthropic, OpenAI, Codex, OpenRouter, DeepSeek, Moonshot, ZAI, Gemini, and other catalog providers are supported by model specs.
.aether/settings.json
{
"agents": [
{
"name": "Plan",
"description": "Plans implementation strategy",
"model": "codex:gpt-5.5",
"userInvocable": true,
"reasoningEffort": "high",
"prompts": [".aether/PLAN.md"]
},
{
"name": "Build",
"description": "Builds features and fixes bugs",
"model": "zai:glm-5.1",
"userInvocable": true,
"prompts": [".aether/BUILD.md"]
},
{
"name": "Fast",
"description": "Quick tasks and lookups",
"model": "openai:gpt-5.5",
"userInvocable": true,
"prompts": [".aether/FAST.md"]
}
]
}

Local

Run local models with llama.cpp or Ollama.
.aether/settings.json
{
"agents": [
...
{
"name": "Local",
"description": "Runs locally via Ollama",
"model": "ollama:llama3.2",
"userInvocable": true,
"prompts": [".aether/LOCAL.md"]
}
]
}

Alloy multiple models together

Combine the strengths of multiple models by round-robining between them each conversation turn. You can even mix cloud and local models together.
.aether/settings.json
{
"agents": [
...
{
"name": "Alloy",
"description": "Mixes cloud and local models",
"model": "zai:glm-5.1,ollama:llama3.2",
"userInvocable": true,
"prompts": [".aether/ALLOY.md"]
}
]
}

Control every token in your system prompt

Start with a blank slate and add only what you need.

Start with a blank slate

Agents begin with no system prompt or tools.
terminal
$ aether show-prompt -a Build
---
Prompt chars: 0
Tool schema chars: 0
Est. tokens: ~ 0
MCP tools: 0

Use any markdown files you want

Your system prompt is an array of prompt sources. Load AGENTS.md, CLAUDE.md, GEMINI.md, per-agent files, inline text, or globs; prompt files can also run shell interpolation with !`command` markers.
.aether/settings.json
{
"agents": [
{
"name": "Build",
"description": "Builds features and fixes bugs",
"model": "zai:glm-5.1",
"userInvocable": true,
"reasoningEffort": "high",
"prompts": [".aether/BUILD.md", "AGENTS.md"]
}
]
}
.aether/BUILD.md
# Build Agent
You are a staff+ level engineer.
...
AGENTS.md
# Agents
Use the Explorer agent to search code.
...

View your agent's system prompt with a single command

Including an est. token count
terminal
$ aether show-prompt -a Build
output
# System Prompt
You are an expert senior Rust engineer.
...
# Agents
Use the Explorer agent to search code.
...
---
Prompt chars: 120
Tool schema chars: 0
Est. tokens: ~ 30
MCP tools: 0

Connect tools via MCP servers (local or remote)

Be minimal…or maximal. Give your agent a single tool (Bash) and point it at some CLIs + skill files. Or, go full batteries-included by adding a few lines to your .aether/mcp.json file.

Batteries included MCPs

Aether includes several built-in MCP servers you can enable. They run in a custom in-memory transport.
  • coding — file I/O, grep, bash, web, and LSP-backed coding tools
  • skills — reusable skills, rules, and notes
  • subagents — spawn parallel child agents with their own models and tools
  • tasks — task tracking for multi-step work, with optional persistence
  • survey — allow the agent to ask structured questions
  • plan — submit markdown plans for approval and feedback
.aether/settings.json
{
"agents": [
{
"name": "Build",
"description": "Builds features and fixes bugs",
"model": "zai:glm-5.1",
"userInvocable": true,
"prompts": [".aether/BUILD.md", "AGENTS.md"],
"mcps": [".aether/mcp.json"]
}
]
}
.aether/mcp.json
{
"servers": {
"coding": {
"type": "in-memory",
"args": ["--rules-dir", ".aether/skills"]
},
"skills": {
"type": "in-memory",
"args": ["--dir", ".aether/skills", "--notes-dir", ".aether/notes"]
},
"subagents": { "type": "in-memory" },
"tasks": { "type": "in-memory" },
"survey": { "type": "in-memory" },
"plan": { "type": "in-memory" }
}
}

Any MCP server

Plug in any external MCP server via stdio, SSE, or streamable HTTP. Remote server OAuth credentials are stored securely in your keychain.
.aether/mcp.json
{
"servers": {
...
"linear": {
"type": "http",
"url": "https://mcp.linear.app/mcp"
}
}
}

MCP tool proxy stops tools from eating your context

Set proxy on external servers (or on a file source) and Aether exposes a single proxy__call_tool plus on-disk tool definitions, so agents discover nested tools on demand instead of loading every schema up front.
.aether/mcp.json
{
"servers": {
"chrome-devtools": {
"type": "stdio",
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest"],
"proxy": true
},
"linear": {
"type": "http",
"url": "https://mcp.linear.app/mcp",
"proxy": true
}
}
}

Run in a TUI, Editor/IDE or Headless

You’ll be up and running in two commands

Run in a TUI

First run opens onboarding when .aether/settings.json is missing, writes project-local config, and launches the terminal UI backed by aether acp.
First run (auto-scaffolds)
$ aether
Created .aether/settings.json
Created .aether/mcp.json
Created .aether/BUILD.md
Created AGENTS.md
Launching TUI via aether acp...

Run in your editor

Expose over ACP for VS Code, JetBrains, or any editor with agent support.
Editor/IDE (via ACP)
$ aether acp

Run headlessly

Run headless for scripts, CI, and automation.
Headless
$ aether headless "refactor auth"

Use as a Library

Embed Aether directly into your app with the Rust runtime or the TypeScript SDK.

Rust SDK

Use aether-core to build agents in-process, stream events, attach MCP tools, and compose the runtime with your own Rust services.
Rust
use aether_core::core::{Prompt, agent};
use aether_core::events::{AgentMessage, UserMessage};
use llm::{ProviderFactory, providers::AnthropicProvider};
let provider = AnthropicProvider::from_env()
.await?
.with_model("claude-sonnet-4-5");
let (user_tx, mut agent_rx, handle) = agent(provider)
.system_prompt(Prompt::text("You are a concise assistant."))
.spawn()
.await?;
user_tx.send(UserMessage::text("Review this diff")).await?;
while let Some(message) = agent_rx.recv().await {
match message {
AgentMessage::Text { chunk, .. } => print!("{chunk}"),
AgentMessage::Done => break,
_ => {}
}
}
handle.await_completion().await;

TypeScript SDK

Use @aether-agent/sdk from Node apps and scripts. It starts an ACP-backed Aether session, streams messages, and can host closure-backed tools in your process.
TypeScript
import { AetherSession } from "@aether-agent/sdk";
await using session = await AetherSession.start({
cwd: process.cwd(),
agent: "Build",
});
for await (const message of session.prompt("Review this diff")) {
if (message.type === "session_update") {
console.log(message.update);
}
}

Ready to build?

Use the full CLI or pick individual crates — aether-core, llm, mcp-servers, wisp, crucible — to compose your own agent.