ajmx
ajmx logo

A JMX CLI for AI agents.

Inspect and control a running JVM.

curl -fsSL https://github.com/yagipass/ajmx/releases/latest/download/install.sh | sh -s -- -b ~/.local/bin
Get started

Just ask.

Add the ajmx skill and ask about a running JVM in your own words. The agent finds the JVM and its MBeans, reads them, and changes the JVM only when you ask.

gh skill install yagipass/ajmx ajmx
  • Why does the heap of OrderService keep growing?

  • Are there deadlocked threads in the JVM listening on port 9010?

  • Is the connection pool of the local Spring Boot app running out?

  • Turn on a heap dump on OutOfMemoryError in the running app.

Zero setup.

ajmx --pid 12345 ping
{"schemaVersion":1,"ok":true,"result":{"connected":true},"durationMs":13}

--pid attaches to a local HotSpot JVM even without remote JMX enabled. No JVM flags and no restart, so you can look at a problem while it is still happening.

Only JSON.

Every result is one JSON document. A failure is one too, with error.code to switch on and retryable to say whether to try again. The agent knows what happened and what to do next, with no text or stack trace to interpret.

ajmx --pid 12345 read java.lang:type=Memory HeapMemoryUsage
{"schemaVersion":1,"ok":true,"result":{"mbean":"java.lang:type=Memory","attributes":{"HeapMemoryUsage":{"committed":268435456,"init":268435456,"max":268435456,"used":41491160}}},"durationMs":19}
ajmx --pid 12345 describe com.example:type=Nope
{"schemaVersion":1,"ok":false,"error":{"code":"MBEAN_NOT_FOUND","message":"MBean was not found","retryable":false,"details":{"mbean":"com.example:type=Nope"}},"durationMs":3}

Always bounded.

ajmx --pid 12345 read java.lang:type=Runtime SystemProperties --limit 2 | jq -c .result
{"mbean":"java.lang:type=Runtime","attributes":{"SystemProperties":{"$truncated":true,"$total":55,"$items":[{"key":"apple.awt.application.name","value":"OrderService"},{"key":"file.encoding","value":"UTF-8"}]}},"truncated":true}

--limit caps every list at 100 items and --max-bytes caps stdout at 262144 bytes by default, so no command fills the agent's context with more than you allow. A cut is marked, so the agent can tell part of the data from all of it.

Find. Read. Change.

An agent needs no MBean names up front, so it can work on any JVM, even one running an application it has never seen. Each command prints what the next one takes, and batch sends several over one connection.

Find.

ps
Lists the JVMs on this machine.
search
Finds MBeans by an ObjectName pattern.
describe
Lists an MBean's attributes and operations.

Read.

read
Reads attributes, and reports the ones that failed.

Change.

write
Sets an attribute, converted to its type.
invoke
Calls an operation with the overload its arguments fit.

Inspect and control a running JVM.