LiquidJava MCP server
Commit 26. Okt. 2026Stellt LiquidJava-Verifizierungstools für LLM-Agents bereit, um Verifizierungen durchzuführen, strukturierte Diagnosen abzurufen und den Solver abzufragen.
Auch bekannt als liquid-java/liquidjava-mcp
- Stars
- 1
- Tools
- 8
- Downloads, 30 Tage
- —
- Neueste Version
- —
- Letzter Commit
- 26. Okt. 2026
- Lizenz
- MIT
Was ist LiquidJava MCP?
LiquidJava ist ein MCP server. Stellt LiquidJava-Verifizierungstools für LLM-Agents bereit, um Verifizierungen durchzuführen, strukturierte Diagnosen abzurufen und den Solver abzufragen. Er stellt 8 Tools bereit, etwa verify, get_diagnostics, get_locals.
Zusammenfassung generiert aus dem README des Projekts
Über LiquidJava MCP server
Software-Engineers und AI-Agents können mit liquidjava-mcp eine formale Verifizierung von Java-Code durchführen. Dieser Server verbindet sich via stdio mit einem MCP-Client, wodurch ein Agent LiquidJava-Tools direkt auf lokalen Java-Dateien ausführen kann. Er ermöglicht den Schritt über die einfache textbasierte Verifizierung, indem er strukturierte, maschinenlesbare Daten bereitstellt, die ein LLM ohne manuelles Parsing verarbeiten kann.
Nutzer können das verify Tool für den Standard-Output verwenden oder get_diagnostics nutzen, um detaillierte Error- und Warning-Arrays zu erhalten, die Refinements und Gegenbeispiele enthalten. Der Server erlaubt zudem eine tiefe Inspektion des Programms durch Tools wie get_locals für den Variablen-Scope, get_globals für Aliase und States sowie get_contracts für Methodenspezifikationen. Für fortgeschrittene Logik-Tests kann der Solver via check_validity und check_satisfiability abgefragt werden, um eigene Annahmen und Schlussfolgerungen zu prüfen. Das System verfügt über ein integriertes Caching, um wiederholte Requests für dieselben Source-Dateien zu beschleunigen.
Was du damit machen kannst
- 1Strukturierte Verifizierungsfehler analysierenEin AI-Agent kann detaillierte Error-Arrays inklusive Refinements und Gegenbeispiele abrufen, anstatt rohen Terminal-Text parsen zu müssen.
- 2Variable Refinements im Scope inspizierenEin Developer kann einen Agent bitten, die spezifischen Refinement-Prädikate für Variablen an einer bestimmten Zeile und Spalte zu finden.
- 3Eigene logische Annahmen verifizierenDu kannst den Solver nutzen, um zu prüfen, ob ein bestimmter Satz von Annahmen logisch eine gewünschte Schlussfolgerung impliziert.
- 4Typestate-Protokolle extrahierenEin Agent kann eine Java-Datei parsen, um die durch LiquidJava-Annotationen definierten States und Transitions abzubilden.
Geschrieben aus dem README des Projekts. Jeder Use Case wurde gegen ein Zitat daraus geprüft.
LiquidJava MCP tools 8
Erkannt aus dem READMEverifyget_diagnosticsget_localsget_globalsget_contractsget_state_machinecheck_validitycheck_satisfiability
| verify | — | |
| get_diagnostics | — | |
| get_locals | — | |
| get_globals | — | |
| get_contracts | — | |
| get_state_machine | — | |
| check_validity | — | |
| check_satisfiability | — |
Automatisierte Checks
Geluften am 14. Nov. 2026Vollständiger Bericht →Noch nicht verifiziert. Ein Server benötigt einen Score von 80, keine kritischen Befunde und genug Daten für unsere Prüfung. Wie die Checks funktionieren · Was du für mehr Punkte verbessern kannst
- Source Repository verknüpft und erreichbarliquid-java/liquidjava-mcp is public and reachablegithub.com/liquid-java/liquidjava-mcp ↗Bestanden
- Paket nennt dieses Repository als QuelleNicht geprüft
- Build-Provenienz (Sigstore-Attestierung)Nicht geprüft
- Open Source Lizenz (OSI)MITspdx.org/licenses/MIT.html ↗Bestanden
- Commit oder Release im letzten JahrLast commit or release 2026-10-26github.com/liquid-java/liquidjava-mcp ↗Bestanden
- OpenSSF ScorecardNicht geprüft
- Package-Name ähnelt keinem populären PackageNicht geprüft
- Keine kritischen Advisories im Paket oder seinen AbhängigkeitenNicht geprüft
- Keine versteckten Anweisungen an das Modell8 tool descriptions and the README read; no override phrases, credential paths or hidden charactersBestanden
- Destruktive Tools sind markiertNo tool named like delete, drop or execBestanden
- Remote-Endpoint beantwortet den MCP-HandshakeNicht geprüft
README
Auf GitHub ansehenLiquidJava MCP
A Java MCP server that exposes LiquidJava verification tools to LLM agents over stdio.
It allows agents to run the LiquidJava verification, retrieve structured diagnostics, inspect the verification context, and query LiquidJava's solver with custom assumptions and conclusions. It also comes with a skill that guides agents on how and when to use the MCP tools.
Installation
Build the project with mvn package and then point your MCP client at the resulting jar:
{
"servers": {
"liquidjava-mcp": {
"type": "stdio",
"command": "java",
"args": [
"-jar",
"/path/to/liquidjava-mcp/target/liquidjava-mcp.jar"
]
}
}
}
Tools
Overview
| Tool | Purpose | Input | Output |
|---|---|---|---|
verify |
Run the verification and get human-readable output (same as the CLI) | path, debug? |
standard LiquidJava output |
get_diagnostics |
Run the verification and get more detailed structured diagnostics | path |
errors and warnings arrays (type, severity, location, message, refinements, hints, counterexamples) |
get_locals |
Inspect verification context (variables in scope) at a specific source position | path, file?, line, column |
variables (name, internal name, type, refinement, location) |
get_globals |
Inspect global definitions (aliases, ghosts, states) available in the program | path, file? |
aliases, ghosts, states |
get_contracts |
Inspect method and constructor contracts | path, className?, signature? |
contracts (qualified signature, parameters, return refinement, state transitions, location) |
get_state_machine |
Parse a Java file's LiquidJava typestate protocol | path |
stateMachine with states and transitions |
check_validity |
Check if assumptions imply a conclusion via the solver | variables, ghosts, assumptions, conclusion |
status (valid, invalid, or unknown), counterexample (for invalid results) |
check_satisfiability |
Check if constraints are satisfiable via the solver | variables, ghosts, constraints |
status (sat, unsat, or unknown), assignment (for satisfiable results) |
The verify, get_diagnostics, get_locals, get_globals, and get_contracts tools reuse cached analysis when the input path, source hash, and debug option match. Requests time out after 60 seconds, including time waiting for another analysis, and return a verifier error with any captured output.
verify
Runs the LiquidJava verification and returns the same output normally shown to developers.
Allows agents to inspect verification conditions, their simplifications, and solver results using the debug flag.
Input: File or directory path, with optional debug flag.
Output: Verification status and the standard LiquidJava verification output.
{
"path": ".../Example.java",
"debug": false
}
{
"success": false,
"output": "Running LiquidJava on: .../Example.java\n\nRefinement Error: input >= 0 && #ret¹ == input is not a subtype of #ret¹ > 0\n..."
}
get_diagnostics
Runs the LiquidJava verification and exposes diagnostics in a machine-readable format, avoiding the need for agents to parse terminal output.
Input: File or directory path.
Output: Verification status and errors and warnings arrays of structured diagnostics, including type, severity, location, message, refinements, VCs, details, hints, and counterexamples when available.
{
"path": ".../Example.java"
}
{
"success": false,
"errors": [
{
"refinements": {
"expected": "#ret_1 > 0",
"found": "input >= 0 && #ret_1 == input"
},
"vc": {
"expected": "#ret_1 > 0",
"found": "∀input:int, input >= 0 => \n∀#ret_1:int, #ret_1 == input",
"history": [
{
"implication": "∀input:int, input >= 0 => \n∀#value_0:int, #value_0 == input => \n∀#ret_1:int, #ret_1 == #value_0"
},
{
"implication": "∀input:int, input >= 0 => \n∀#ret_1:int, #ret_1 == input",
"simplification": "Substitution"
}
]
},
"type": "RefinementError",
"severity": "error",
"counterexample": [
{"variable": "input", "value": "0"},
{"variable": "#ret_1", "value": "0"}
],
"declarationLocation": {
"file": ".../Example.java",
"startColumn": 9,
"endLine": 14,
"endColumn": 5,
"startLine": 11
},
"location": {
"file": ".../Example.java",
"startColumn": 9,
"endLine": 13,
"endColumn": 21,
"startLine": 13
},
"message": "input >= 0 && #ret¹ == input is not a subtype of #ret¹ > 0"
}
],
"warnings": []
}
get_locals
Exposes the verification context available at a specific point in the program.
Input: A path to the Java source file or directory to verify, plus line and column identifying the source position to inspect. An optional file parameter specifies a different file for filtering variables. When omitted, path is used instead. Lines and columns are one-based.
Output: variables. Each variable includes its source name, verifier internalName, Java type, refinement predicate, and source location (inclusive ends). Entries include declarations and refinement instances recorded before the position in enclosing scopes. Internal names preserve relationships between predicates. Positions outside recorded scopes return an empty array. This exposes source-filtered verifier history; synthesized branch-merge instances can carry the original declaration location, so it does not reconstruct the exact solver state at the cursor.
{
"path": ".../Example.java",
"line": 13,
"column": 20
}
{
"variables": [
{
"name": "input",
"internalName": "input",
"location": {
"file": ".../Example.java",
"startColumn": 41,
"endLine": 11,
"endColumn": 45,
"startLine": 11
},
"type": "int",
"refinement": "input >= 0"
},
{
"name": "value",
"internalName": "#value_0",
"location": {
"file": ".../Example.java",
"startColumn": 13,
"endLine": 12,
"endColumn": 26,
"startLine": 12
},
"type": "int",
"refinement": "#value_0 == input"
},
{
"name": "value",
"internalName": "value",
"location": {
"file": ".../Example.java",
"startColumn": 13,
"endLine": 12,
"endColumn": 26,
"startLine": 12
},
"type": "int",
"refinement": "true"
},
{
"name": "ret",
"internalName": "#ret_1",
"location": {
"file": ".../Example.java",
"startColumn": 9,
"endLine": 13,
"endColumn": 21,
"startLine": 13
},
"type": "int",
"refinement": "#ret_1 == #value_0"
},
{
"name": "this#Example",
"internalName": "this#Example",
"location": {
"file": ".../Example.java",
"startColumn": 9,
"endLine": 13,
"endColumn": 21,
"startLine": 13
},
"type": "com.example.Example",
"refinement": "true"
}
]
}
get_globals
Provides global definitions available in the program.
Input: A path to the Java source file or directory to verify, optionally with a file identifying which source file's ghosts and states to return.
Output: aliases, ghosts, and states. Aliases include parameter names, parameter types, and predicates; ghosts and states include qualified names, return types, parameter types, and their defining refinements when available.
{
"path": ".../Example.java"
}
{
"aliases": [
{
"predicate": "v >= 0",
"parameterTypes": ["int"],
"parameters": ["v"],
"name": "Positive"
}
],
"ghosts": [
{
"qualifiedName": "com.example.Example.size",
"file": ".../Example.java",
"name": "size",
"parameterTypes": ["com.example.Example"],
"returnType": "int"
}
],
"states": [
{
"qualifiedName": "com.example.Example.closed",
"refinement": "state1(_) == 1",
"file": ".../Example.java",
"parameterTypes": ["com.example.Example"],
"returnType": "boolean",
"name": "closed"
},
{
"qualifiedName": "com.example.Example.open",
"refinement": "state1(_) == 0",
"file": ".../Example.java",
"parameterTypes": ["com.example.Example"],
"returnType": "boolean",
"name": "open"
}
]
}
get_contracts
Returns the method and constructor contracts registered during verification. This includes source contracts and external refinement contracts.
Input: A path to the Java source file or directory to verify. className optionally filters by an exact qualified target class name. signature optionally filters by an exact complete qualified method or constructor signature, including parameter types.
Output: Each contract includes its target class, signature, return type and refinement, refined parameters, paired state transitions, and declaration location.
{
"path": ".../Example.java",
"className": "com.example.Example",
"signature": "com.example.Example.requirePositive(int)"
}
{
"contracts": [
{
"className": "com.example.Example",
"signature": "com.example.Example.requirePositive(int)",
"returnType": "void",
"parameters": [
{"name": "input", "type": "int", "refinement": "input > 0"}
],
"returnRefinement": "true",
"stateTransitions": [],
"location": {
"file": ".../Example.java",
"startLine": 10,
"startColumn": 5,
"endLine": 11,
"endColumn": 6
}
}
]
}
get_state_machine
Parses a Java source file and returns the LiquidJava typestate protocol declared by its @StateSet and @StateRefinement annotations. The result describes the possible states, initial states, and method transitions. A transition's fromCondition and toCondition contain any non-state conditions such as cond ? state1 : state2 or cond && state1.
Input: path, an existing Java source file. Directories are not accepted because the parser returns the state machine for one source file at a time.
Output: An object containing a stateMachine value with the qualified class name, states, initial transitions, and method transitions. stateMachine is null when the file does not declare a state machine.
{
"path": ".../File.java"
}
{
"stateMachine": {
"className": "example.File",
"states": [
"open",
"closed"
],
"transitions": [
{
"from": "open",
"to": "closed",
"label": "close",
"fromCondition": null,
"toCondition": null
},
{
"from": "open",
"to": "open",
"label": "read",
"fromCondition": null,
"toCondition": null
}
],
"initialTransitions": [
{
"to": "open",
"toCondition": null
}
]
}
}
check_validity
Checks whether custom assumptions imply one conclusion using LiquidJava's solver, without verifying Java files. Declared ghost functions are translated as LiquidJava uninterpreted functions. Aliases, source constants, and implicit receiver/return/old-state bindings are not supported.
Input: variables (map of names to primitive or reference types), ghosts (map of names to uninterpreted function declarations with parameter types and a return type), assumptions (array of boolean predicate strings), and conclusion (boolean predicate string).
Output: status (valid, invalid, or unknown). Invalid results include a counterexample.
{
"variables": {"x": "int"},
"ghosts": {},
"assumptions": ["x >= 0"],
"conclusion": "x > 0"
}
{
"status": "invalid",
"counterexample": [{"variable": "x", "value": "0"}]
}
check_satisfiability
Checks whether custom constraints have a satisfying assignment using LiquidJava's solver. It returns sat, unsat, or unknown; sat results include the solver's assignment when available.
Input: variables (map of names to primitive or reference types), ghosts (map of names to uninterpreted function declarations with parameter types and a return type), and constraints (array of boolean predicate strings).
Output: status (sat, unsat, or unknown). Satisfiable results include an assignment.
{
"variables": {"x": "int"},
"ghosts": {},
"constraints": ["x > 0", "x < 2"]
}
{
"status": "sat",
"assignment": [{"variable": "x", "value": "1"}]
}
LiquidJava MCP Fragen
Welche Tools bietet LiquidJava MCP?
Er stellt 8 Tools bereit, darunter verify, get_diagnostics, get_locals, get_globals, get_contracts.
Wie installiere ich den LiquidJava MCP server?
Baue das Projekt mit mvn package und verweise deinen MCP-Client über den stdio-Transport auf die resultierende jar-Datei.
Kann ich maschinenlesbare Fehlermeldungen statt Terminal-Output erhalten?
Ja, das get_diagnostics Tool liefert strukturierte Diagnosen, einschließlich Fehlern und Warnungen in Arrays. Das erspart es den Agents, Terminal-Output manuell parsen zu müssen.
Unterstützt der Server Caching?
Ja, mehrere Tools wie verify, get_diagnostics und get_locals nutzen gecachte Analysen wieder, sofern der Input-Pfad, der Source-Hash und die Debug-Optionen übereinstimmen.
Gibt es ein Timeout für Requests?
Ja, Requests laufen nach 60 Sekunden ab; darin enthalten ist auch die Zeit, die für das Warten auf eine andere Analyse benötigt wird.