Skip to main content

key-agent-client

A Python client for the headless KeY theorem prover server — for proving that Java code satisfies its JML specification, and for finding out what to do when it does not.

This is a third-party tool. It is not an official KeY component.

It talks to a running keyext.server over JSON-RPC and does nothing else. It contains no Java, ships no jar and never starts a JVM: the server is a separate long-lived process, which is the whole reason it is worth talking to instead of re-running a prover from cold on every attempt.

Install

uv add key-agent-client        # or: pip install key-agent-client

No dependencies. Python 3.10 or newer. Add the [mcp] extra for the MCP server.

Start a server

This client does not start one, on purpose: a library that spawns JVMs is a library that owns processes it cannot supervise. keyext.server lives in this KeY fork — it is not part of upstream KeY — and every release there carries a prebuilt jar. Its name carries both KeY's version and the server's, so ask the release for it rather than writing it down:

gh release download --repo AzoteGwei/key --pattern 'keyext.server-*-exe.jar'
java -Xmx4g -jar keyext.server-*-exe.jar --port 0 --workspace /path/to/project

Give it -Xmx4g. KeY is memory-hungry and the default heap will not survive a real proof. The server publishes the port it got, so nothing needs to be passed to this client. The usage guide has the same download without gh, how to build the jar instead, and the rest of the server's options.

Prove something

from keyclient import KeyClient

with KeyClient.discover(workspace="/path/to/project") as key:
    load = key.wait_for_task(key.load("/path/to/project").task_id)
    env = load.result["envId"]

    contract = key.obligations(env)[0].contract_id
    proof = key.start_proof(env, contract)
    key.wait_for_task(key.run_auto(proof, timeout_ms=60_000).task_id)

    stats = key.statistics(proof)
    print("closed" if stats.closed else f"{stats.open_goals} goal(s) still open")

Or from a shell. This one runs as written, against the example in this repository:

java -Xmx4g -jar keyext.server-*-exe.jar --port 0 --workspace examples/first-proof &

key-agent load .
# env	env-e84opq9w                     your id will differ
key-agent prove env-e84opq9w 'Max[Max::max(int,int)].JML normal_behavior operation contract.0'
# closed	true

Start there. examples/first-proof holds three contracts — one that closes, one whose code is wrong, one missing a loop invariant — so the first answer you see is one you already know, and a closed false afterwards is about the code rather than about the setup.

The one thing to know

Statistics.closed is the server's report of KeY's own Proof.closed(). It is the only value in this library that means a contract was proved. Nothing here computes it, infers it or defaults it.

In particular a finished task is not a closed proof: slow work returns a handle whose status becomes SUCCEEDED, meaning the work ran to an end. A macro that ends leaving three goals open is a succeeded task with three open goals.

Where to go next

If you want to Read
Drive the prover yourself, from Python or the shell Usage guide
Look up a method, a field or an error code API reference
Check that your setup works at all examples/first-proof
Give an agent the prover over MCP MCP server
Install the Claude Code skill skills/key-prover
Work on this client, or cut a release Contributing

The guide's vocabulary section is worth five minutes before anything else: the distinctions in it — finished versus closed, out of ideas versus out of budget — are the ones that get misread.

Licence

MIT. The KeY server it talks to is GPL-2.0-only; this client is a separate program that communicates with it over a network protocol.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

key_agent_client-0.2.1.tar.gz (27.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

key_agent_client-0.2.1-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file key_agent_client-0.2.1.tar.gz.

File metadata

  • Download URL: key_agent_client-0.2.1.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for key_agent_client-0.2.1.tar.gz
Algorithm Hash digest
SHA256 1d7ad7bc90d43e96d255dbda7c6f8263046a39a455bd908cc06dd88b0fc63cde
MD5 8f34f05e422ac52fe3f7024c289bcd10
BLAKE2b-256 32d09cdd66acb32e6f582f48aef92ef09e38e77d8c1518b19960a133b62395fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for key_agent_client-0.2.1.tar.gz:

Publisher: release.yml on AzoteGwei/key-agent-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file key_agent_client-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for key_agent_client-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3367182863aae1f0941f51a2b1918b8e15d10e657dfdd026d6cbaa51d180a223
MD5 396fd1bb3307c4ad8f1f32d6873879e4
BLAKE2b-256 a88624f9091c6d6c3182b0176a2b6aba6d76e5e24756d50898c275a3f2c50c3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for key_agent_client-0.2.1-py3-none-any.whl:

Publisher: release.yml on AzoteGwei/key-agent-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page