Skip to content

Introduction ​

Kestrel is an agent platform for people who intend to keep it running.

Most agent projects start as a chat loop with tools and grow a UI around it. That works until you need a second model provider, a different transport, a sandbox, or a client on a phone. Kestrel starts from the other end: a small kernel that knows about services and lifetimes, an agent runtime that knows about sessions and runs, and a plugin host that knows how to compose both. Everything else — including the tools that edit your files — is an extension.

Design principles ​

1. Everything is a plugin ​

Above the kernel, capability is assembled from plugins: providers, tools, prompt context, memory and integrations all register through the same contract. A plugin is a named object with a version, an optional list of required plugins, a list of service keys it injects, and an apply function. It receives an isolated child context. Whatever it registers — services, listeners, timers, child plugins — is disposed when the plugin goes away.

This is the same idea that makes Cordis-based systems (and DeepSeek's Harness work) pleasant to extend: composition happens through dependency injection, not through a registry of hard-coded imports. Kestrel adopts that model and makes the service surface explicit and typed.

2. The runtime is a library ​

@kestrel/agent has no HTTP server, no CLI and no browser code. It can be embedded in a script, a worker, a desktop application or a server process. The server is a thin adapter: it validates JSON, maps errors to status codes, and forwards events. The CLI is another adapter with the same runtime.

3. Explicit lifetimes ​

A process that runs for weeks will load and unload plugins. Kestrel treats teardown as a first-class operation: every registration returns a disposer, contexts own scopes, and scopes unwind in reverse order. Plugin replacement is expected behaviour, not a restart.

4. Failure is local ​

A plugin that throws during apply is marked error and isolated. Its dependents wait; unrelated plugins keep running. Dependency cycles are detected and reported instead of deadlocking the host.

5. The wire is the API boundary ​

Clients speak JSON over HTTP and Server-Sent Events. There is no private socket protocol and no framework-specific RPC. Any language with an HTTP client can drive an agent. This is what makes "desktop, web, mobile" a packaging question rather than a rewrite.

What ships today ​

LayerPackageResponsibility
Kernel@kestrel/kernelcontexts, services, events, scopes, plugin lifecycle, logging
Protocol@kestrel/protocolshared types for events, sessions, tools, models
Runtime@kestrel/agentmodel and tool registries, sessions, runs, persistence, approvals
Plugin host@kestrel/plugin-hostdiscovery, manifests, dependency ordering, configuration
Transport@kestrel/serverREST, SSE, static console, auth, CORS
Clients@kestrel/cli, @kestrel/webterminal and browser interfaces
Extensionsplugins/*OpenAI-compatible models, filesystem and shell tools, workspace context, memory, MCP

The platform is at an early 0.x stage. The interfaces documented here are the ones we intend to keep stable; see the roadmap for what is still missing before 1.0.

Inspirations, and what we changed ​

  • Cordis / DeepSeek Harness — the service-and-injection kernel, and the idea that plugins are the unit of everything. Kestrel adds an application-wide service registry for plugin contributions, a stricter disposal story, and a manifest format that works without a bundler.
  • OpenHands and similar agent runtimes — the session/run model, tool approval, workspace confinement. Kestrel keeps the runtime headless and pushes presentation into clients.
  • Unix and LSP — small protocols with many implementations. We resisted embedding a web framework in the core for the same reason.

Who this is for ​

  • Teams that want an agent they can host themselves, on infrastructure they already run.
  • Tool authors who want to add capability without forking the agent.
  • Client authors who want a stable event stream rather than a private SDK.
  • People who care more about the next two years of maintenance than the next two weeks of demo.

Released under the MIT License.