[ANN] Kaimon.jl — opening the gate between AI agents and Julia

It’s here!

Kaimon 2.0.0

Kaimon gives an AI agent a live Julia REPL over MCP: run code, introspect types
and methods, drive the debugger, run tests, and search code against the running
session. 2.0 reworks search and the session model, changes how agents connect,
and splits the gate into its own lightweight package.

A standalone gate: KaimonGate

The session and eval machinery now lives in KaimonGate, a separate package with a
small, tightly constrained dependency set. It is easy to add to your own project
or session without pulling in all of Kaimon, and spawned agent sessions boot it
instead of full Kaimon, so a session never recompiles Kaimon against your project.

This is a separate package in the General registry, currently at version 1.0.1.

Search

  • grep_code is a native MCP grep: an exact pattern or regex over the live
    working tree that returns the enclosing function or struct for each hit. It is a
    safer, clearer alternative to the piped grep/awk/sed bash commands models
    otherwise reach for, and much easier to read when you are watching what the
    agent runs. It is confined to the project scope by default.
  • search_code finds code by meaning, now fusing vector similarity with a local
    SQLite FTS5 index, so results hold up whether you describe the behavior or
    remember an exact identifier.
  • Both are repo scoped, respect .gitignore, and take opt-in metadata filters.
    grep_code can include logs and generated files on request.

Sessions

Agents bind to the right gate from their workspace root, start_session reuses a
running gate instead of spawning a duplicate, and a new project is approved from a
prompt inside your client instead of by editing JSON (allow_any_project covers
container and VM setups).

Long work that does not block

Any eval past about thirty seconds becomes a background job with progress and
cancellation, and it survives a restart.

Agent backends

The supported agent is Claude today, built to speak ACP so other agents can plug
in soon. New and still experimental: local model backends (MLX and an in-process
Ollama loop) for keeping inference on your own machine.

CURVE encryption, and a path to TachiRei

The gate transport can run CURVE encrypted over ZMQ, with key management and a
trust store in the TUI, which opens up secure connectivity across a network. It
also lays the groundwork for TachiRei.jl, a platform for persistent remote Julia
sessions and applications that people and multiple agents can connect to at once
(coming soon).

KaimonSlate

A browser-based notebook (a “slate”) built on Kaimon’s extension system, where you
and an agent build and run cells in the same document, with doc search and PDF
export. It ships separately as KaimonSlate.jl.

(to be released very soon, repo going public in the next day)

Windows and headless

Windows support: the gate uses TCP in place of IPC. Headless parity: the same
analytics, indexing, housekeeping, and clean shutdown as the TUI.

Stability and performance

The ZMQ transport was rewritten (persistent DEALER/ROUTER, event driven messaging,
adaptive timeouts), lowering reply latency and idle CPU, and a broad pass closed a
long list of stability issues from the 1.x line.


Thanks

To the contributors who shipped code in this release, filed issues, and helped improve the platform. Shout outs in the release notes here:

2.0 is a massive improvement in experience out of the box! Having KaimonGate spun off into its own package with only standard library dependencies is a huge deal, as is cleaning up the tools that are visible by default. I’m cranking out harnesses for our production system, connecting up Claude Code + Kaimon and having it test new/updated models, optimize performance, fix bugs, and even some multi agent closed-loop type stuff.

Great to hear! Please get in touch if you run into any snags or need any support as you progress.

Also, while it appears that we’re in the season of summer blockbusters when it comes to notebooks, stay tuned for KaimonSlate, any time now ;).

The new direction with KaimonGate looks really good. Previously, importing Kaimon from the base environment into a project would trigger a bunch of invalidations and precompiling would churn for ages. However, it would be nice to go even further and vendorize all non-base dependencies. This would ensure incompatible versions of packages didn’t get loaded and so on. (Perhaps in this case it would help to have pure-Julia zmq implementation.)

I believe ZMQ is the one and only package dependency that isn’t in the Stdlib. That’s as slim as I could go.

A pure Julia ZMQ package would be nice. I could have gone straight sockets but the ZMQ for the messaging fabric is really powerful in Kaimon. You’ll see shortly when KaimonSlate comes out why I went this direction early on. It makes doing cool stuff very feasible.

This is what DaemonicCabal.jl does, and I can confirm it is rather convenient being able to just rely on OS piping etc.

Not a concern for Kaimon, but it should also allow for very high throughput (as you may be aware the focus of DaemonicCabal.jl is offering same-behaviour, low-latency + high performance pooled connections).

Oh, I have recently added some fun things that may be of some interest to people here, namely --sync and --status.

Just saw this, if I knew about it, maybe I wouldn’t have done a similar tool (GitHub - KristofferC/JuliaDaemon.jl: Persistent julia daemon for agentic workflows · GitHub). Just posting here in case there is any value in comparing. The thing I have is much simpler, it is basically just the daemon + evaluation part. No MCP or any skills or any code searches or anything like that.

One thing that I have gotten some use of in JuliaDaemon is to convert a current session into a server that the agent can connect to (GitHub - KristofferC/JuliaDaemon.jl: Persistent julia daemon for agentic workflows · GitHub). For example if I am in a session

julia> using Plots

julia> f(x,y) = exp(-(x^2 + y^2))
f (generic function with 1 method)

julia> # I forgot how to make a contour plot

julia> using JuliaDaemon

julia> JuliaDaemon.serve()
jld: serving this session as v1.12-repl-aaac5b80
     agents: jld --id=v1.12-repl-aaac5b80 eval '<code>' | transcript | stacks | eval-repl
"v1.12-repl-aaac5b80"

then I can ask Claude:

 Hey claude, can you help me make a contour plot of my function in v1.12-repl-aaac5b80. It is f(x,y) and I have plots loaded. Evaluate the result into my REPL

and it connects and puts

julia> xs = ys = range(-3, 3; length=200); plt = contour(xs, ys, (x, y) -> f(x, y); levels=20, fill=true, color=:viridis, xlabel="x", ylabel="y", title="f(x,y)", aspect_ratio=:equal); display(plt)
QApplication: invalid style override 'kvantum' passed, ignoring it.
        Available styles: Windows, Fusion

in my REPL window and I get a contour plot. Is that possible in Kaimon?

Edit: And now I found [ANN] julia-client — persistent Julia sessions as CLI as well :laughing:

ZMQ also delivers on this, but I’m not pushing it to it limits.

And so much more …

This is KaimonSlate which builds on top of Kaimon, it will be out in a day or two.

But the REPL based stuff has been working for a while:

I use per-worker sockets with IOUring/kqueue for rapid copying, which I think is probably the fastest viable approach I’m aware of short of using a shared memory map.

PRs welcome if you’d like to offer it as a ZMQ alternative. :slight_smile:

I like the collaborative spirit, but I’m rather settled on my own thing :slight_smile:

Fair, ZMQ does what I need it to do and has the messaging patterns which support the use cases. And being able to switch seamlessly between ICP and TCP is quite powerful.

It makes sense: I think in the end we’re making distinct but overlapping tools. Kaimon is clearly intended to be an all-in-one interface to Julia for LLMs, while I’ve got a Julia session manager that can be handed to an LLM if you want to use it that way.

You’ve been building out a whole bunch of features for LLMs, I’ve been trying to optimise the latency/throughput, and make juliaclient behave like julia (with a few fun session-based extras).

❯ juliaclient --help

    juliaclient [switches] -- [programfile] [args...]

Switches (a '*' marks the default value, if applicable):

 -v, --version              Display version information
 -h, --help                 Print this message
 -P, --project[=<dir>|@.]    Set <dir> as the home project/environment
 -e, --eval <expr>          Evaluate <expr>
 -E, --print <expr>         Evaluate <expr> and display the result
 -L, --load <file>          Load <file> immediately on all processors
 -i                         Interactive mode; REPL runs and `isinteractive()` is true
 -t, --threads <N|auto>[,<M|auto>]  Launch N threads (and M interactive threads)
 -q, --quiet                Quiet startup: no banner, suppress REPL warnings
 --banner={yes|no|auto*}    Enable or disable startup banner
 --color={yes|no|auto*}     Enable or disable color text
 --history-file={yes*|no}   Load or save history

Client-specific switches:

 -a, --address <addr>       Connect to conductor at <addr> instead of default
 --session[=<label>]        Reuse worker state in Main module. With a label,
                            multiple clients can share the same session.
 --sync                     Attach to shared REPL (requires --session=<label>)
 --revise[=yes|no*]         Enable or disable Revise.jl integration
 --restart                  Kill workers for the project and exit
 --sandbox                  Run in an isolated sandbox (Linux only)
 --status[=json]            Show the state of the workers, optionally in json
❯ hyperfine -N --warmup=10 "juliaclient -e '1+1'"
Benchmark 1: juliaclient -e '1+1'
  Time (mean ± σ):       1.8 ms ±   0.6 ms    [User: 0.3 ms, System: 0.2 ms]
  Range (min … max):     1.2 ms …  12.1 ms    972 runs

How can I update from Kaimon 1.x?

Can I just do:

]app add Kaimon

Or are there other/better ways to update?

Yes, some variation on that. You should get

Yes, ideally it should be that easy. Depending on how you had set up your packages and environments, it’s possible that there might be some variation like removing the dependency from a specific project. But the first time you run it, you should get a prompt about installing the lightweight KaimonGate package globally and it tries to just handle things for you. If you do run into any issues here let me know as I’d like to improve it to work as reliably as possible.

OK, I had to remove all my Kaimon logic from my run_julia script.

Question: Is Kaimon able to use a custom system image? I know, not so important as long as Kaimon can keep a session open, but sometimes you also have to restart a session.

This was a custom script? Yeah it tries to manage a little block in the global startup.jl, it’s just a few lines so you could always use the option under config (g key)to write it and see what’s there (it’s basically just optionally loading Revise and the new KaimonGate package).

I haven’t tried to but I see no reason why it would cause any problem, the whole thing is just straight Julia, kaimon as the CLI tool and TUI should run with or without the system image, and the connection with the sessions is over the wire through ZMQ, so it should talk to any process that has the KaimonGate package and runs KaimonGate.serve(). But again, if you run into any snags please get in touch and we’ll figure it out.