gapit for agents¶
gapit is built to be driven by programs. Every output is machine-readable by design, the whole contract is discoverable from the binary itself, and failures are typed JSON instead of prose. This page is the contract; you should not need any other documentation to integrate.
Discovery without docs¶
Three commands answer "what can this thing do" without reading a manual.
Version, as one JSON line:
$ gapit --version --json
{"schema":"gapit.version/1","name":"gapit","version":"0.5.6"}
Output schemas. Eleven documents are introspectable: report, typing_result, reads,
reads2, cluster, summary, error, version, plus the database-side
documents features, typing, and floors. Each prints its full JSON Schema:
$ gapit schema report # gapit.report/1 (contig screening)
$ gapit schema typing_result # gapit.typing_result/1 (gapit typing designation)
$ gapit schema reads # gapit.reads/1 (FASTQ screening)
$ gapit schema reads2 # gapit.reads/2 (filtered FASTQ screening)
$ gapit schema cluster # gapit.cluster/1 (cluster-database screening)
$ gapit schema summary # gapit.summary/1
$ gapit schema error # gapit.error/1
$ gapit schema version # gapit.version/1
$ gapit schema features # gapit.features/1 (cluster db feature table)
$ gapit schema typing # gapit.typing/2 (db scoring spec; /1 still reads)
$ gapit schema floors # gapit.floors/1 (per-gene identity floors, reads mode)
For example, gapit schema version (real output):
{
"description": "gapit.version/1 \u2014 compact one-line self-description.",
"properties": {
"schema": {
"const": "gapit.version/1",
"default": "gapit.version/1",
"title": "Schema",
"type": "string"
},
"name": {
"default": "gapit",
"title": "Name",
"type": "string"
},
"version": {
"title": "Version",
"type": "string"
}
},
"required": ["version"],
"title": "VersionDocument",
"type": "object"
}
Databases: the database catalog and install state (gapit db list --json; real output,
first two of twenty-two shown, trimmed):
$ gapit db list --json
{
"schema": "gapit.dblist/1",
"providers": [
{
"name": "argannot",
"vendor": "IHU Méditerranée-Infection",
"description": "ARG-ANNOT acquired resistance genes",
"dbtype": "nucl",
"installed": true,
"records": 2224
},
{
"name": "bacmet2",
"vendor": "University of Gothenburg",
"description": "BacMet2 experimentally confirmed biocide/resistance genes (protein)",
"dbtype": "prot",
"installed": true,
"records": 746
}
]
}
Deterministic outputs¶
Same input, same bytes. That holds because:
- Sort orders are fixed and documented (
./screen.md,./summary.md). - No wall-clock timestamps inside data payloads. The only time field is
document metadata (
created_at). - LF line endings, UTF-8, stable key order per schema.
- stdout purity: data on stdout, diagnostics on stderr, always. Redirect stdout to a file and you get exactly the document, nothing else.
Exit codes as control flow¶
The integer on exit tells you the failure class before you read a byte of stderr.
| Exit code | Meaning |
|---|---|
| 0 | success |
| 1 | unexpected error |
| 2 | usage error |
| 3 | missing dependency |
| 4 | database error |
| 5 | input error |
Envelope details and error codes: ./outputs.md.
JSON stability policy¶
- Every document self-identifies with a version string:
gapit.report/1,gapit.reads/1,gapit.cluster/1,gapit.summary/1,gapit.error/1,gapit.version/1. Checkschemafirst, dispatch on it. - Schemas follow semver. A minor bump never renames or retypes an existing field; new fields may appear, so ignore unknown keys rather than rejecting them.
- Keys are snake_case with explicit units (
identity_pct,coverage_pct). - The authoritative machine contract is the schema itself:
gapit schema <doc>is always current, this page may lag.
Error envelope parsing¶
Any failure prints exactly one JSON line to stderr:
{"schema":"gapit.error/1","code":"...","message":"...","context":{...}}
Real example, screening against a database that does not exist (exit 4):
{"schema":"gapit.error/1","code":"DATABASE_NOT_FOUND","message":"Database nosuchdb is not in /tmp/gapit-mcp-demo/datadir. Available: tinyamr","context":{"db":"nosuchdb","datadir":"/tmp/gapit-mcp-demo/datadir"}}
And a missing external binary (exit 3):
{"schema":"gapit.error/1","code":"MISSING_DEPENDENCY","message":"required binary not found on PATH: blastn","context":{"binary":"blastn"}}
Parsing guidance:
- Progress diagnostics (for example
Processing: sampleA.fa) also go to stderr. The envelope is the one stderr line that parses as JSON with"schema":"gapit.error/1". codeis a stable string enum (USAGE_ERROR,MISSING_DEPENDENCY,DATABASE_NOT_FOUND,INPUT_NOT_FOUND, ...). Branch oncode, not onmessage.contextcarries machine-readable details (file paths, db name), safe to log or surface.
Recommended workflow¶
Discover, screen, parse, summarize. Session below run against the repo's test
fixture datadir (setup recipe in ./mcp.md).
-
Discover available databases (
gapit db list --json, or thedb_listMCP tool), pick adbname. -
Screen each sample as JSON and parse hits straight out of the document:
console
$ gapit screen sampleA.fa --db tinyamr --format json > sampleA.json
$ gapit screen sampleB.fa --db tinyamr --format json > sampleB.json
```python import json
for path in ("sampleA.json", "sampleB.json"): doc = json.load(open(path)) assert doc["schema"] == "gapit.report/1" for f in doc["files"]: for hit in f["hits"]: print(f["file"], hit["gene"], hit["identity_pct"], hit["coverage_pct"]) ```
Real output:
text
sampleA.fa tetA 100.0 100.0
- For a cross-sample matrix, keep the default TSV reports and feed them to
gapit summary:
console
$ gapit screen sampleA.fa --db tinyamr > sampleA.tsv
$ gapit screen sampleB.fa --db tinyamr > sampleB.tsv
$ gapit summary sampleA.tsv sampleB.tsv
#FILE NUM_FOUND tetA
sampleA.tsv 1 100.00
sampleB.tsv 0 .
Screening options: ./screen.md. Summary semantics: ./summary.md.
Tool-runtime integration¶
If your runtime speaks MCP, register gapit as a server and call screen,
screen_reads, summary, schema, and db_list as tools instead of
subprocesses: ./mcp.md. The server also exposes the db commands
(db_fetch, db_build, db_search, db_outdated), so an agent can
provision the database it needs and screen against it in one session.