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.0.tar.gz (27.6 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.0-py3-none-any.whl (33.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: key_agent_client-0.2.0.tar.gz
  • Upload date:
  • Size: 27.6 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.0.tar.gz
Algorithm Hash digest
SHA256 dbf2733ab739a039fc710964ff3dc29a47ad2bb89183f240ce552843b55e9790
MD5 08540d04df1d3527c652c7f064ebc07e
BLAKE2b-256 369976289661efd3085d35ed1e8ddb36d95f27871f42c226fcbff5c61f997374

See more details on using hashes here.

Provenance

The following attestation bundles were made for key_agent_client-0.2.0.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.0-py3-none-any.whl.

File metadata

File hashes

Hashes for key_agent_client-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a81abe1d591e27827276d8663dae3c67f5fa8be6cb0587a5ce04f223fd2723c
MD5 4841b5f0626a55f66c5e0563c8893fc4
BLAKE2b-256 f9b113b173613291ee0f4c104f8b1c78b6fe7638105125a2cb880fed760a373d

See more details on using hashes here.

Provenance

The following attestation bundles were made for key_agent_client-0.2.0-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

0.2.1

2 files

This release

0.2.0 This release

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