Pyjab MCP
Drive Java desktop apps from an AI agent, through the JVM's own accessibility tree
Connector by gaozhao1989 · GitHub account verified by the MCP Registry
Install
Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.
npx agentmarket install connector/gaozhao1989-pyjab-mcp
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list and install config. Checked Oct 25, 2026.
- Tools
- 7 read · 6 write · 0 delete · 3 not yet classified
- Secrets
- None asked for
- Install scripts
- Not scanned yet
- Runs as
- Python package
Tools by what they do 16
Read from the source code; the running server may list different tools.
Read 7 · Look things up without changing anything.
java_findjava_get_elementjava_get_tablejava_get_textjava_list_windowsjava_screenshotjava_snapshot
Write 6 · Create, change, send or run things.
java_attach_windowjava_clickjava_fill_formjava_selectjava_send_keysjava_set_text
Not yet classified 3 · We could not tell from the name and description.
java_diagnosticsjava_focus_windowjava_wait_for
Tools (16)
Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].
java_attach_windowBind to one Java window and return a session id for later calls. Use this after java_list_windows, once you know which window to drive. Give either an exact ``hwnd`` or a ``title``; a title may be an fnmatch pattern (``"*Report*"``) exactly as pyjab matches it. Pass ``hwnd`` when several windows share a title pattern. Binding is also what arms Java Access Bridge for this server: pyjab loads the DLL, hooks the events and registers the JAB prototypes on the thread doing the binding, so the first attach is slower than the later ones. This never modifies, restarts or injects into the applicatio…
java_clickClick an element: a button, a menu item, a check box, a link, a tree node. By default this uses the element's **accessibility action**, which is what the application itself exposes: no mouse moves, no window comes to the front, and it works where there is no interactive desktop. Use `simulate=True` when the accessibility action is ignored — it drives real mouse input, which requires the window to come to the front and cannot work from a service session, and it needs real geometry (cells in some tables report `bounds = -1`, and there is no point to click). The element is checked before it is …
java_diagnosticsReport whether this machine can drive a Java application right now. Use this first when anything fails, and after installing a JVM or enabling Java Access Bridge. It reports the platform, the interpreter, the installed pyjab and which of its public APIs are present, whether Java Access Bridge is enabled, where the bridge DLL is, and the state of the bridge thread. It is read-only and never writes to the environment: it does not enable Java Access Bridge, because a diagnostics tool that changes what it is reporting on is worse than none. Args: load_bridge: When true, also start the bridg…
java_fill_formFill several fields in one call: a list of ``{"handle": ..., "value": ...}``. A form is usually several fields, and setting them one at a time costs a round trip each. This is the same verification and the same typing, applied in order, with one reply that says what happened to every field. It **does not stop at the first failure**. A form that is half filled with no report is worse than one that is half filled with one: every field is attempted, and each line says whether it worked and why not. Args: session_id: From java_attach_window. fields: ``[{"handle": "e:1a2b", "value": "adm…
java_findSearch an attached window and get a handle for each match. Use this when a snapshot is too large to read, or when you know what the control is called and do not want to walk the tree to find it. A snapshot shows you the shape of the window; this asks a question about it. Give **exactly one** selector. `name` and `description` are exact matches -- for a substring use `xpath` with `contains()`, which is pyjab's locator syntax: `//push button[@name=contains('Save')]`. `states` takes a comma-joined list such as `"enabled,showing"`. Every match gets a handle, and a handle is checked before it is…
java_focus_windowBring an attached window to the front, and report whether it actually came forward. Use it before `java_send_keys`, whose chord goes to whichever window has the keyboard focus: **attaching a window does not give it focus** (measured in pyjab#180), so a shortcut can otherwise land somewhere else entirely. **The reply is the point, not the action.** "I asked for focus" and "the window is now in front" are two different facts, and this tool answers with the second one. It does so by reading back the state pyjab left behind, because Windows' `SetForegroundWindow` has no useful return of its own.…
java_get_elementEverything known about one element, and whether it is still the same element. Use this after java_snapshot or java_find to look at one control in detail, or to confirm that a handle still points at what it did. The handle is resolved again and compared against what was recorded when it was handed out; if anything differs -- role, name, position among siblings, bounds -- this reports the difference instead of presenting the element as if nothing had changed. Args: session_id: From java_attach_window. handle: An ``e:...`` handle from a snapshot or a find. Returns: The element's ro…
java_get_tableRead a Java table, a page of rows at a time. Use this on a handle for a `table` element -- from java_snapshot or java_find. This is the tool a platform-level automation cannot replace: it reads the table's own accessibility interface, so cell text, row and column counts come from the JVM rather than from pixels or from a bridge that does not carry them. It never returns the whole table. A large table is 200 rows in pyjab's own test application and thousands in a real one, so the read is paged by `row_start` and bounded by `row_count` and `max_cells`, and the reply says what it left out and h…
java_get_textRead the text of an element: a label, a text field, a table cell, a document. Use this on a handle from a snapshot or a find. The same verification applies, so a text field that has been replaced since the snapshot reports the change instead of returning whatever is there now. Long values are cut, and the cut is reported: the reply says how much of the whole text it carries and what the whole text's length is, so a partial read is never presented as the value. Args: session_id: From java_attach_window. handle: An ``e:...`` handle from a snapshot or a find. start: Character to st…
java_list_windowsList the Java windows Java Access Bridge can see on this machine. Use this to find out whether the application is visible to JAB at all, and to get a title or hwnd for java_attach_window. If the application is not in this list, nothing else will work and the problem is the attachment or the environment, not a locator -- run java_diagnostics next. Only windows of Java applications are listed; this is not a general Windows window list. Returns: One line per window, with hwnd, pid and title. "No Java windows are visible" is a measurement and is reported as such, not as an empty string.…
java_screenshotA PNG of the window, or of one element inside it. Use it when the accessibility tree is not enough — a chart, a canvas, a layout problem — and remember what it cannot do: **a picture is not readable structure.** Anything you want to act on should be found in the tree with java_snapshot or java_find, because that is where the handles and the names are. Canvas-drawn interfaces are the case where this is the only thing that works, and the only thing that is not there. With a handle, the element is verified first, for the same reason an action is: a picture of whatever moved into the position wo…
java_selectSelect an option in a combo box, list or tab set — or a row or cell in a table. Two shapes, and which one you want is told by the arguments: * `option="Tennis"` selects by the text the application shows, for a combo box, a list or a tab. * `row=2` selects a whole table row, and `row=2, column=1` selects one cell. Table selection goes through the table's own accessible selection, which is the path the application responds to — pyjab's docs are explicit that the cells `get_cell()` returns often report `bounds = -1` and cannot be clicked. The element is verified before anything is sele…
java_send_keysSend a keyboard shortcut — ``alt+y``, ``ctrl+shift+s`` — to the window. Use it for an action the application only exposes as a chord: a menu accelerator, a toolbar shortcut, a keystroke a canvas-drawn control listens for. **Nothing is focused and nothing is clicked.** The chord goes to whichever window currently has the keyboard focus. That is deliberate on pyjab's side: clicking a control to focus its window would activate that control, and a shortcut usually exists to avoid exactly that. So if a call seems to do nothing, the window probably does not have focus — and **attaching does not f…
java_set_textType into a text field, text area or editable combo box. This sets the text rather than appending to it, and it waits for the field to report the new value before returning, so a following read sees what was typed. By default it goes through the accessibility action; `simulate=True` types real keystrokes instead, which is the fallback when the action is refused. Use java_fill_form instead when several fields need values: it is one round trip and it reports each field separately. The element is verified before anything is typed, exactly as java_click describes. Args: session_id: From ja…
java_snapshotThe bounded tree view of an attached window, one line per element, with handles. This is the tool to reach for first after attaching: it shows what is in the window, what each element is called, and a handle (``[e:1a2b]``) for every element a later call can name. Pass a handle to a tool that acts on elements; pass a session id here. The view is deliberately bounded, and it says so when it was cut short. A Java window can hold thousands of nodes, and returning one puts hundreds of thousands of tokens into the conversation, so read in rings: snapshot at depth 2, then snapshot again if you need…
Show 1 more tools
java_wait_forWait for something to happen, instead of asking too early and being told no. Three conditions, chosen by what you pass: * `window_title="A Dialog"` — wait until a Java window with that title (fnmatch, so `"*Progress*"` works) exists. Use it after an action that opens one. * `handle=..., text_equals="Saved"` — wait until that element's text *is* this. * `handle=...` alone — wait until its text *changes* from what it reads when the wait starts, and report both values. **A timeout is a result, not an error.** The reply says the condition was not met and what was seen instead, because "not …
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 0
- Weekly downloads
- 93
- Last commit
- Oct 15, 2026 (15 days ago)
- Last release
- Oct 12, 2026 (18 days ago)
- Last package publish
- Oct 12, 2026 (18 days ago)
From GitHub (fetched Oct 24, 2026) and the package registry.
Details
- Registry name
io.github.gaozhao1989/pyjab-mcp- Version
- 0.3.1
- Auth
- No auth
- Packages
- pypi pyjab-mcp
- License
- MIT
- Repository
- github.com/gaozhao1989/pyjab-mcp
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
Cite this page
Pyjab MCP. Agent Mart. https://agentmart.dev/connectors/gaozhao1989-pyjab-mcp (last updated 2026-10-24)