the agent orchestrator you can watch. every event is like a spectral line, every agent a lane on the screen.
website · user guide · dev docs · gallery · releases · release notes
the spectrum · four agents review a pull request in parallel; every event is a tick on its agent's lane
spectroscope is a JVM agent harness and fleet orchestrator. One Java core drives every face: a terminal REPL, headless runs, a Spring Boot web UI, a signed macOS desktop app, an MCP example server, and a fleet of agents on a shared bus.
Everything an agent does lands in one stream of typed JSONL RunEvents, the
same wire format on every face. The UI reads that stream the way a spectroscope
reads light: watch it live, store it as plain files, replay it step by step,
lens it for reasoning and timing, and answer permission gates while the run
waits. There is no separate telemetry stack to deploy; the session file is the
record.
spectroscope began as the reference harness of a build-an-agent-harness workshop and grew into its own product.
var agent = Spectro.agent()
.model(Anthropic.opus())
.tools(Tools.readFile(), Tools.runCommand())
.workspace(Path.of("/tmp/scratch"));
for (RunEvent event : agent.run("Write hello.py and run it")) {
System.out.println(event); // the stream IS the observability
}The same style scales to a fleet: Spectro.panel() runs several lanes as full
agents on a shared bus and hands you one merged event stream. Both artifacts
are on Maven Central:
implementation("dev.spectroscope:spectro-core:0.5.0")
implementation("dev.spectroscope:spectro-orchestrator:0.5.0") // fleets
the trace · every frame with its causal chain, a reasoning lens, and a replay scrubber |
the gate · writes and commands wait for allow or deny; every decision lands in the stream |
the fleet canvas · spawn edges and per-node spectral lines, live from the bus |
the machine room · a running fleet as one composed system diagram, scrubbable in time |
thinking, live · the model's self-report streams next to what it then did |
explain · an LLM reading of the whole run, honestly labeled as a reading |
grow into it · a fresh home starts small and asks; an existing home is never asked and never locked |
the tutorial · levels tick from observed usage, every tick with a receipt into the session it happened in |
no key, no cloud · pick a local model, see whether your machine holds it, download once — tools included |
More in the gallery and the user guide, both in light and dark.
Four routes to 0.5.0, each with the platform it covers. Every asset is on the
release page,
where SHA256SUMS.linux covers the two Linux kits.
Homebrew — macOS on Apple silicon.
brew install --cask spectroscope/tap/spectroscopeThe signed and notarized desktop kit, which brings its own Java runtime and its
own llama-server. Uninstalling leaves ~/.spectro alone: that is where your
sessions live, and the CLI and the server jar share it. Apple silicon only,
there is no Intel build.
The disk image — macOS on Apple silicon. spectroscope-0.5.0-arm64.dmg
from the release page is the same kit without the tap.
apt — Debian 12 and Ubuntu 24.04, x86_64.
curl -fsSL https://apt.spectroscope.dev/spectroscope.asc | sudo gpg --dearmor -o /usr/share/keyrings/spectroscope.gpg
echo "deb [signed-by=/usr/share/keyrings/spectroscope.gpg] https://apt.spectroscope.dev stable main" | sudo tee /etc/apt/sources.list.d/spectroscope.list
sudo apt update && sudo apt install spectroscopeThe index is GPG-signed and pinned to that one key with signed-by; there is no
trusted=yes and no allow-insecure switch. x86_64 only, so on arm64 apt takes
the source and then finds nothing to install. For x86_64 distributions that do
not use apt, spectroscope-0.5.0-x86_64.AppImage is the same kit as one file.
Neither Linux kit is signed, because Linux has no equivalent gate to pass. Both
are covered by SHA256SUMS.linux on the release page, so the check to run on a
download is:
sha256sum -c SHA256SUMS.linux --ignore-missingFrom source. Clone this repository and use the ./spectro launcher below.
Everywhere else — arm64 Linux, Windows, anything with a JVM. There is no
desktop kit, and no macOS route will help. Take spectro-0.5.0.zip (the CLI) or
spectro-server-0.5.0.jar and run them on a JDK 21; that is the smallest way
in, and the only way onto a platform with no kit. Two things the kits carry are
missing there: a bundled llama-server for the built-in models, which you
supply yourself (brew install llama.cpp, or your package manager), and the
spectro-pty helper the Files tab terminal needs, which is POSIX-only either
way. The bundled example MCP server ships separately as
spectro-mcp-notes-0.5.0.zip.
The desktop kits open the cockpit themselves. From a clone, the ./spectro
launcher resolves a JDK 21+ for you and loads the gitignored ./.env:
./spectro web start # web UI → http://127.0.0.1:8080, in the background
./spectro web # what the web group can do, and whether it is running
./spectro repl # terminal REPL
./spectro run -p "…" # headless run
./spectro desktop # Electron desktop app
./spectro doctor # environment check
./spectro tour # guided feature tourIt also knows node, cron, sessions, resume <id>, level and
mcp-notes. Raw Gradle works too (JDK 21+ as JAVA_HOME):
./gradlew build # everything + all tests
./gradlew :spectro-server:bootRun # the web face
(cd spectro-web && npm install && npm run build) # rebuild the UI into the server jarThe web build writes into spectro-server/src/main/resources/static/, where
the committed bundle lives, so rebuilding it dirties tracked files by design.
Web development wants Node 20+.
The core has a tracing seam, and two sinks ship with it: the JSONL session
file (always on, the source of truth) and an OTLP exporter that maps
sessions to GenAI-semconv spans. Point it at Langfuse, Jaeger, or any OTLP
endpoint under settings, observability; spectro doctor probes the endpoint
with an empty batch and tells you whether it answers. Details in
docs/OBSERVABILITY.md.
| module | what it is |
|---|---|
spectro-core |
the agent loop, providers, tools, permission gate, sessions, tracing seam |
spectro-cli |
terminal face: REPL, headless runs, doctor, tour, scheduler |
spectro-server |
Spring Boot web face: WebSocket stream + REST, serves the built UI |
spectro-web |
the React UI (Vite): chat, spectrum, trace, graph, text, lab |
spectro-desktop |
Electron shell that spawns and supervises the server jar |
spectro-mcp-notes |
bundled example MCP server (notes search/add over stdio) |
spectro-orchestrator |
the fleet: lanes as full agents on a shared bus, one merged stream |
Runs on Spring and almost nothing else. Twenty-one hand-built architecture diagrams live in docs/diagrams/, each in both themes; docs/ARCHITECTURE.md and docs/WEB-UI.md go deep.
Seven chat providers, switchable mid-session from the header picker with history intact:
| provider | runs | needs |
|---|---|---|
built-in |
local, via llama-server | nothing with the desktop kits, which bundle one; with the server jar, brew install llama.cpp |
anthropic |
cloud | ANTHROPIC_API_KEY |
ollama |
local | a running Ollama |
openai |
api.openai.com or any compatible server | OPENAI_API_KEY (optional for local servers) |
lmstudio |
local | LM Studio's server |
openrouter |
cloud | OPENROUTER_API_KEY |
gemini |
cloud | GEMINI_API_KEY |
The built-in provider is the no-setup path: the app offers a small catalogue
of open models (Qwen3 1.7B/4B/8B, Qwen2.5 Coder 7B, VibeThinker 3B), says
which of them can drive the agent's tools and whether your machine has the
memory and disk for each, then downloads your pick sha256-pinned — four of
them from Qwen's own repository, VibeThinker from a community requantization
of WeiboAI's model. Each row links its licence and its source. The desktop
kits carry their own llama-server, so nothing else needs installing; with the
server jar you bring your own (brew install llama.cpp) and the chooser says
so when it is missing. No key and no account, and the model itself runs on
your machine.
Keys are set once, in the UI (masked, written to ~/.spectro/.env with mode
0600) or via CLI set-key; one Gemini or OpenAI key serves chat and the
generate_image tool alike. Config layers from env up to per-workspace
settings files; spectro doctor names anything shadowed.
Beyond that, the tool belt covers files, shell, sandboxed grep and glob, web fetch, tiered web search, JS-capable page browsing through the system Chrome, image generation, subagents, skills, and MCP servers, all behind the same permission gate.
The v0.5.0 gate: 1166 JUnit tests and 1841 vitest tests across 130 files, no failures, measured on the release tree with the build cache and the up-to-date checks disabled. The suites run without any API key; provider wire mappings are tested against scripted local servers, and the one live contract check skips itself unless a key is set. Concurrency suites (bus, hub, fleet) pass three consecutive runs before a release.
- user guide, 120+ pages, HTML and PDF, light and dark editions, real captured screens
- dev portal with a generated, searchable reference extracted from this source tree
- samples/ — eight numbered examples, six of them standalone Gradle projects that resolve spectroscope from Maven Central rather than from this tree: the five lines, a fleet, recording a run for
spectro web, a fleet across processes, OTel export, and a LangChain4j provider - docs/ARCHITECTURE.md, docs/WEB-UI.md, docs/OBSERVABILITY.md, docs/INTEROP.md
- docs/WEB-BUNDLE.md — why the built UI is a tracked file, and the one command that resolves it when two branches collide in it
- release-notes/ for what each version brought
Found a bug or a rough edge? Open an issue; the project is young and moves fast.
Two licenses, one rule: the name stays attached.
Code: MIT, copyright Christopher Ezell. Use it, fork it, ship it, sell with it; the one thing the license asks is that the copyright notice travels with copies of the code. Stripping it ends the license.
Images: CC BY 4.0 for the screenshots, the architecture diagrams and the banner. Reuse them in posts, talks, papers or products, commercially too, as long as visible attribution stays with them: "spectroscope — Christopher Ezell, github.com/spectroscope/spectroscope, CC BY 4.0". The spectroscope logo and wordmark are the exception: fine for referring to the project, not for branding something else — LICENSE-ASSETS.md has the exact terms.
If spectroscope shows up in your product or your research, a mention with a link back is very welcome. GitHub reads CITATION.cff, so "cite this repository" in the sidebar gives you a ready-made reference.


