🐍 coding agent SDK

The coding agent
you npm install.

LLM SDKs give you chat. Sandbox providers give you containers. noumen is everything in between — the tool loop, file editing, shell execution, and session management that turn a language model into a coding agent.

Provider-agnosticFull tool loop
Virtual infraMIT licensed
$pnpm add noumen

The missing layer between LLMs and codebases

The tool loop, session management, and virtual infrastructure that every coding agent needs — so you don't have to build it yourself.

🛠️

Read, write, edit, execute

ReadFile, WriteFile, EditFile, Bash, Glob, Grep — the same tools shipping inside production coding agents, wired up and ready to go.

🔌

Swap models in one line

OpenAI, Anthropic, Google Gemini. Same streaming interface, same tool dispatch, same results. Bring your own keys.

💻

Run anywhere

Local Node.js, remote containers via sprites.dev, or implement VirtualFs yourself. The agent doesn't care where it runs.

💾

Resume, compact, persist

Conversations save as JSONL. Auto-compaction keeps context under control. Resume any thread by ID, right where you left off.

📚

Teach your agent

Inject markdown instructions into the system prompt. Load SKILL.md files from the filesystem. Shape behavior without changing code.

🔗

Connect to anything

Client and server support for Model Context Protocol. Expose external tools and resources to the agent seamlessly.

Quick Start

Up and running in 12 lines.

Pick a provider, point at a filesystem, and start streaming events. The serpent handles the rest.

index.ts
import {
  Code,
  OpenAIProvider,
  LocalFs,
  LocalComputer,
} from "noumen";

const code = new Code({
  aiProvider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
  virtualFs: new LocalFs({ basePath: "/my/project" }),
  virtualComputer: new LocalComputer({ defaultCwd: "/my/project" }),
});

const thread = code.createThread();

for await (const event of thread.run("Add a health-check endpoint")) {
  switch (event.type) {
    case "text_delta":
      process.stdout.write(event.text);
      break;
    case "tool_use_start":
      console.log(`\n[tool] ${event.toolName}`);
      break;
    case "tool_result":
      console.log(`[result] ${event.result.content.slice(0, 200)}`);
      break;
  }
}

The agent loop stays the same. Swap the brain.

One interface. Three providers. Same streaming, same tool dispatch, same results. Pick the model that fits.

OpenAI

gpt-4o

Anthropic

claude-sonnet-4

Google Gemini

gemini-2.5-flash
🐍

Stop building the plumbing.
Ship the agent.

$pnpm add noumen
$import { Code, OpenAIProvider } from "noumen"
Read the quickstart