Skip to content

API Reference

Public API

Kaimon.start! Function
julia
start!(; port=nothing, verbose=true, security_mode=nothing, julia_session_name="", workspace_dir=pwd())

Start the Kaimon MCP server.

Arguments

  • port::Union{Int,Nothing}=nothing: Server port. Use 0 for dynamic port assignment (finds first available port in 40000-49999). If nothing, uses port from configuration.

  • verbose::Bool=true: Show startup messages

  • security_mode::Union{Symbol,Nothing}=nothing: Override security mode (:strict, :relaxed, or :lax)

  • julia_session_name::String="": Name for this Julia session

  • workspace_dir::String=pwd(): Project root directory

Dynamic Port Assignment

Set port=0 (or use "port": 0 in config.json) to automatically find and use an available port. The server will search ports 40000-49999 for the first free port. This higher range avoids conflicts with common services.

Examples

julia
# Use configured port from config.json
Kaimon.start!()

# Use specific port
Kaimon.start!(port=4000)

# Use dynamic port assignment
Kaimon.start!(port=0)

# Start with a custom name
Kaimon.start!(julia_session_name="data-processor")
Kaimon.tui Function
julia
tui(; port=2828, theme=:kokaku)

Launch the Kaimon TUI. This is a blocking call that takes over the terminal.

Starts the MCP HTTP server in a background task and watches for REPL gate connections in ~/.cache/kaimon/sock/.

Arguments

  • port::Int=2828: Port for the MCP HTTP server

  • theme::Symbol=:kokaku: Tachikoma theme name

Kaimon.call_tool Function
julia
call_tool(tool_id::Symbol, args::Dict)

Call an MCP tool directly from the REPL without hanging.

This helper function handles the two-parameter signature that most tools expect (args and stream_channel), making it easier to call tools programmatically.

Examples

julia
Kaimon.call_tool(:exec_repl, Dict("expression" => "2 + 2"))
Kaimon.call_tool(:investigate_environment, Dict())
Kaimon.call_tool(:search_methods, Dict("query" => "println"))

Available Tools

Call list_tools() to see all available tools and their descriptions.

Kaimon.list_tools Function
julia
list_tools(; include_hidden=false)

List all available MCP tools with their names and descriptions.

Internal worker tools (relayed to by intermediary sessions, e.g. a notebook extension's __-prefixed tools) are omitted by default; pass include_hidden=true to include them.

Returns a dictionary mapping tool names to their descriptions.

Kaimon.tool_help Function
julia
tool_help(tool_id::Symbol)

Get detailed help/documentation for a specific MCP tool.

Kaimon.security_status Function
julia
security_status()

Display current security configuration.

Kaimon.setup_security Function
julia
setup_security(; force::Bool=false)

Launch the security setup wizard.

Kaimon.generate_key Function
julia
generate_key()

Generate and add a new API key to the global configuration.

Kaimon.revoke_key Function
julia
revoke_key(key::String)

Revoke (remove) an API key from the global configuration.

Kaimon.allow_ip Function
julia
allow_ip(ip::String)

Add an IP address to the global allowlist.

Kaimon.deny_ip Function
julia
deny_ip(ip::String)

Remove an IP address from the global allowlist.

Kaimon.set_security_mode Function
julia
set_security_mode(mode::Symbol)

Change the security mode (:strict, :relaxed, or :lax) in the global configuration.

KaimonGate

The gate is the standalone KaimonGate package. (The full Kaimon install also keeps a deprecated Kaimon.Gate alias for the old Kaimon.Gate.* API; new code should use KaimonGate.)

Lifecycle

KaimonGate.serve Function
julia
serve(; session_id=nothing, force=false, tools=GateTool[], namespace="", allow_mirror=true, allow_restart=true)

Start the eval gate. Binds a ZMQ REP socket on an IPC endpoint and listens for eval requests from the Kaimon TUI server.

Non-blocking — returns immediately. The gate runs in a background task. The session name is derived automatically from the active project path.

Skips registration for non-interactive processes (no TTY). Use force=true to override the TTY check.

Arguments

  • session_id::Union{String,Nothing}: Reuse a session ID (e.g. after exec restart)

  • force::Bool: Skip the TTY gate (for non-interactive processes that want a gate)

  • tools::Vector{GateTool}: Session-scoped tools to expose via MCP

  • namespace::String: Stable prefix for tool names. Auto-derived from project basename if empty. Use explicit namespaces for multi-instance workflows:

    julia
    serve(tools=tools, namespace="todo_dev")    # branch A
    serve(tools=tools, namespace="todo_main")   # branch B
  • mode::Symbol: Transport mode — :ipc (default, local Unix socket) or :tcp (network-accessible, for remote debugging).

  • host::String: Bind address for TCP mode (default "127.0.0.1", localhost only). Use "0.0.0.0" to accept connections from remote machines (no auth — use with care).

  • port::Int: Port for TCP mode (default 0 = ephemeral, ZMQ picks a free port). Both REP and PUB sockets support this. Use a fixed port for predictable endpoints.

  • discoverable::Bool: Whether to advertise this gate in the local discovery registry (default true). When false, the gate serves normally but writes no metadata file, so the Kaimon TUI / MCP server won't list it or import its tools — for embedded/private gates that clients reach via explicit endpoints (e.g. TachiRei atoms, reached on demand by id). IPC only; TCP gates are never file-discovered (they're connected via connect_tcp!).

Example

julia
using KaimonGate
KaimonGate.serve()

# With custom tools
KaimonGate.serve(tools=[GateTool("send_key", my_key_handler)])

# TCP mode for remote debugging (e.g. from a model server)
KaimonGate.serve(mode=:tcp, port=9876, force=true)

Environment variables

These override the keyword defaults when set:

  • KAIMON_GATE_MODE: "ipc" or "tcp" (default: "ipc")

  • KAIMON_GATE_HOST: Bind address for TCP (default: "127.0.0.1")

  • KAIMON_GATE_PORT: Port for TCP (default: "0" = ephemeral)

  • KAIMON_GATE_STREAM_PORT: PUB stream port for TCP (default: "0" = ephemeral). Use a fixed port when tunneling so the client can connect to a known port.

KaimonGate.stop Function
julia
stop()

Stop the eval gate, clean up socket and metadata files.

KaimonGate.restart Function
julia
restart()

Restart the Julia session, preserving the Kaimon session ID so the TUI reconnects automatically. Equivalent to what the agent's manage_repl tool does, but callable directly from your REPL.

Uses execvp to replace the current process image — same PID, fresh Julia state. Your startup.jl runs again and KaimonGate.serve() reconnects with the same session key.

KaimonGate.status Function
julia
status()

Print current gate status.

KaimonGate.connect! Function
julia
connect!()

Connect this Julia session to a running Kaimon TUI. Loads Revise (if available) for live code reloading, then starts the gate in the background. Call from any REPL where KaimonGate is available:

julia
using KaimonGate
KaimonGate.connect!()

Tools

KaimonGate.GateTool Type
julia
GateTool(name, handler)

A tool declared by a gate session. The handler is a normal Julia function; the gate infrastructure reflects on its signature to generate MCP schema and reconstructs typed arguments from incoming Dict values.

Example

julia
function send_key(key::String, modifier::Symbol=:none)
    # handle key event
end

KaimonGate.serve(tools=[GateTool("send_key", send_key)])
KaimonGate.call_tool Function
julia
KaimonGate.call_tool(tool_name::Symbol, args::Dict{String,Any}) -> Any

Call a Kaimon MCP tool from within a gate session. The request is sent over a dedicated ZMQ REQ socket to the Kaimon server's service endpoint, which looks up the tool in its registry and calls the handler.

This gives extensions access to all of Kaimon's registered tools — Qdrant search, Ollama embeddings, code indexing, etc. — without bundling their own clients.

Example

julia
# From a gate tool handler:
result = KaimonGate.call_tool(:qdrant_search_code, Dict{String,Any}(
    "query" => "function that handles HTTP routing",
    "limit" => "5",
))

# List collections
collections = KaimonGate.call_tool(:qdrant_list_collections, Dict{String,Any}())
KaimonGate.list_tools Function
julia
KaimonGate.list_tools() -> Vector{NamedTuple}

Discover all MCP tools registered on the Kaimon server. Returns a vector of (name, description, parameters) tuples.

Example

julia
tools = KaimonGate.list_tools()
for t in tools
    println(t.name, " — ", first(split(t.description, '\n')))
end

Background jobs & progress

KaimonGate.is_cancelled Function
julia
is_cancelled(; job_id::String="") -> Bool

Check if the current job has been cancelled. Call this in long-running loops to support cooperative cancellation.

If called from within a GateTool handler or async eval, the job ID is detected automatically. Otherwise, pass job_id explicitly.

Example

julia
for epoch in 1:1000
    KaimonGate.is_cancelled() && break
    loss = train_epoch!(model)
    KaimonGate.stash("epoch", epoch)
    KaimonGate.progress("Epoch $epoch: loss=$loss")
end
KaimonGate.stash Function
julia
stash(key::String, value; job_id::String="")

Stash a value in the current job's safehouse. If called from within a GateTool handler or async eval, the job ID is detected automatically. Otherwise, pass job_id explicitly.

Retrieve stashed values with check_eval or inspect_job.

Example

julia
for epoch in 1:100
    loss = train_epoch!(model)
    KaimonGate.stash("epoch", epoch)
    KaimonGate.stash("loss", loss)
    KaimonGate.stash("lr", get_lr(optimizer))
    KaimonGate.progress("Epoch $epoch: loss=$loss")
end
julia
stash(pairs::Pair...; job_id::String="")

Stash multiple values at once.

Example

julia
KaimonGate.stash("epoch" => epoch, "loss" => loss, "accuracy" => acc)
KaimonGate.progress Function
julia
progress(message::String)

Stream a real-time progress update to the agent from inside a running eval or GateTool handler. The message is delivered as an MCP notifications/progress event (and echoed in the host REPL), which also keeps long-running HTTP requests from timing out.

Only has an effect while running inside a gate request (it keys off the current request via task-local storage); outside one it's a no-op.

julia
function analyze(passes::Int)
    for i in 1:passes
        KaimonGate.progress("pass $i/$passes complete")
        # ...
    end
end
KaimonGate.push_panel Function
julia
push_panel(key::String, value)

Push a state update to the extension's TUI panel. The value is delivered via PUB/SUB and appears in the panel's ctx._cache[:panel_state][key] on the next frame.

Use this from tool handlers or background tasks to stream data to the panel without the panel needing to poll via ctx.eval().

Example

julia
function my_tool_handler(args)
    result = do_work(args)
    KaimonGate.push_panel("result", result)
    KaimonGate.push_panel("status", "done")
    return "OK"
end
julia
push_panel(pairs::Pair{String}...)

Push multiple panel state updates at once.

Example

julia
KaimonGate.push_panel("greetings" => greetings, "rolls" => rolls)

Terminal

KaimonGate.tty_path Function
julia
tty_path() -> Union{String, Nothing}

Return the TTY device path configured for this gate session (e.g. "/dev/ttys042"), or nothing if no external TTY has been set.

Use this in app code to forward rendering to a separate terminal window:

julia
Tachikoma.app(model; tty_out = KaimonGate.tty_path(), tty_size = KaimonGate.tty_size())
KaimonGate.tty_size Function
julia
tty_size() -> Union{Nothing, NamedTuple{(:rows, :cols)}}

Return the detected size of the configured external TTY, or nothing.

KaimonGate.uninstall_infiltrator_hook! Function
julia
uninstall_infiltrator_hook!()

Restore Infiltrator's original start_prompt so @infiltrate opens the normal interactive REPL prompt instead of routing through the gate debug protocol.

Host-integration hooks

When the full Kaimon package loads, it installs these providers so the standalone gate can report Kaimon's version, apply personality, and so on. They are only needed when embedding KaimonGate in another host.

KaimonGate.PROTOCOL_VERSION Constant
julia
KaimonGate.PROTOCOL_VERSION

Wire-protocol version reported in the gate's pong. The gate and the Kaimon client exchange Serialization-encoded messages over ZMQ; this constant gates wire compatibility independently of the package version — it is bumped only on a wire-breaking change to the request/response or PUB/SUB message format. The client compares this against the range it speaks rather than comparing package versions, so a KaimonGate session and a Kaimon CLI on different releases interoperate as long as their protocol versions match.

Version 2: the request channel moved from per-request ephemeral REQ → a single persistent DEALER (client) multiplexed by correlation id onto a ROUTER (gate). Framing is now [corr_id (8-byte UInt64), payload]; v1 REP gates are incompatible.

KaimonGate.set_version_provider! Function

Install the host's version provider — () -> String reported in the pong.

KaimonGate.set_personality_provider! Function

Install the host's personality/emoticon provider — () -> String.

KaimonGate.set_mirror_pref_provider! Function

Install the host's REPL-mirror preference provider — () -> Bool.

KaimonGate.set_tachikoma! Function

Install the host's Tachikoma module (or nothing to disable TTY hand-off).

KaimonGate.set_auth_token_provider! Function

Install the host's TCP auth-token provider — () -> String ("" for no auth).

KaimonGate.set_restart_code_builder! Function

Install the host's restart-code builder — (serve_args::String) -> code::String.