CLI¶
Medha ships a medha command for inspecting and maintaining a cache without writing a script — warming a collection from a file, expiring stale entries, exporting for analysis, or probing connectivity from a container healthcheck.
Installation¶
To also use medha search and medha warm, which need a real embedder:
Verify the install:
Configuration¶
The CLI takes no connection flags. It builds its Settings from MEDHA_* environment variables or a .env file in the working directory, exactly like the library — so a shell that can run your application can run medha:
| Variable | Default | Description |
|---|---|---|
MEDHA_BACKEND_TYPE |
memory |
Which backend to connect to |
MEDHA_COLLECTION |
default |
Collection name for all commands |
MEDHA_EMBEDDER_TYPE |
_noop |
Embedder used by search and warm |
MEDHA_FASTEMBED_MODEL |
BAAI/bge-small-en-v1.5 |
FastEmbed model identifier |
Backend connection variables (MEDHA_QDRANT_URL, MEDHA_PG_DSN, …) follow the same pattern as the Python API. See Configuration for the full reference.
Quick-start .env for Qdrant¶
MEDHA_BACKEND_TYPE=qdrant
MEDHA_QDRANT_URL=https://xyz.qdrant.tech
MEDHA_QDRANT_API_KEY=your-api-key
MEDHA_COLLECTION=prod_cache
MEDHA_EMBEDDER_TYPE=fastembed
Embedder selection¶
MEDHA_EMBEDDER_TYPE picks the adapter:
| Value | Requires |
|---|---|
_noop (default) |
nothing — a placeholder that cannot embed |
fastembed |
medha-archai[fastembed], optional MEDHA_FASTEMBED_MODEL |
openai |
medha-archai[openai], OPENAI_API_KEY |
cohere |
medha-archai[cohere], COHERE_API_KEY |
gemini |
medha-archai[gemini], GOOGLE_API_KEY |
openai-compatible |
medha-archai[openai], MEDHA_OAI_COMPAT_BASE_URL |
mistral |
medha-archai[mistral], MEDHA_MISTRAL_API_KEY |
The default is deliberately _noop: most maintenance commands never embed anything, so they should not pay for loading a model. Only search and warm need a real embedder — search exits with code 1 and a message telling you what to set if it finds _noop.
Commands¶
medha stats¶
Report collection name, backend, entry counts, and — since 0.5.0 — hit rate and per-strategy breakdown read from the snapshot Medha persists into the backend.
Collection : default
Backend : LanceDBBackend (lancedb)
Entries : 128 (main) 4 (templates)
Requests : 2400
Hit rate : 71.3%
By strategy:
L1 : 900
Template : 120
Exact : 640
Semantic : 52
Fuzzy : 0
Before any snapshot exists the counters are replaced by a single line:
Latency percentiles are still per-process
Entry counts and hit-rate counters come from the backend, so a fresh CLI invocation can report them. Latency percentiles are sampled per process and are deliberately not persisted — use stats() from inside your application for those. With --json, total_requests, hit_rate and hits_by_strategy are null until the first snapshot is written.
medha search QUESTION¶
Look up a question and print the best match. Requires a real embedder.
Strategy : semantic_match
Score : 0.9214
Query : SELECT * FROM customers ORDER BY revenue DESC LIMIT 5
Prints No cache hit. when nothing matches. Useful for answering "why did this question hit the wrong entry?" without instrumenting your application.
medha health¶
Probe backend connectivity and embedder availability.
Each component reports OK, ERROR or SKIPPED, and the command exits 1 if either fails — so it drops straight into a container healthcheck or a CI gate. The embedder probe reports SKIPPED when MEDHA_EMBEDDER_TYPE=_noop, and a skipped probe does not fail the check.
medha warm FILE¶
Bulk-load entries from a JSON or JSONL file. Requires a real embedder — every entry is embedded on the way in.
MEDHA_EMBEDDER_TYPE=fastembed medha warm entries.jsonl
MEDHA_EMBEDDER_TYPE=fastembed medha warm entries.jsonl --collection sql_cache --ttl 86400
Each record needs at least question and generated_query; response_summary is optional.
{"question": "How many users?", "generated_query": "SELECT COUNT(*) FROM users"}
{"question": "List active orders", "generated_query": "SELECT * FROM orders WHERE active = 1"}
--ttl applies the same expiry to all entries; --batch-size controls the upsert chunk size. File loading honours MEDHA_ALLOWED_FILE_DIR and MEDHA_MAX_FILE_SIZE_MB when set.
medha expire¶
Delete all entries whose TTL has elapsed.
Use this with a scheduler (cron, APScheduler) if enable_background_cleanup is disabled, or when you need immediate cleanup from outside the running process.
medha dedup¶
Remove entries sharing the same query_hash (derived from the generated query string), keeping the most recently stored entry per hash. Requires pandas.
medha invalidate QUESTION¶
Remove the entry whose normalised question matches the argument.
Prints Removed., or Not found. if no entry matches. Uses a plain text lookup — no embedder required.
medha invalidate-collection¶
Delete every entry in the collection.
The --yes flag is mandatory — without it the command refuses to run.
medha export¶
Dump all entries to CSV (default) or JSON. Requires pandas.
medha export # CSV to stdout
medha export --format csv --output cache.csv
medha export --format json --output cache.json
medha feedback QUESTION¶
Record a correct or incorrect signal for a cached entry.
medha feedback "How many users are registered?" --correct
medha feedback "How many users are registered?" --incorrect
Prints Feedback recorded., or Entry not found. if no entry matches. Works with the default _noop embedder, because it locates entries by exact normalised-question match rather than vector search. See Feedback Loop for the auto-invalidation behaviour.
medha logo¶
Print the Medha lotus logo.
Global Options¶
| Option | Description |
|---|---|
--collection TEXT |
Override the collection name (default: MEDHA_COLLECTION, or default). Accepted by every command that targets a collection; search and health also accept the short form -c. |
--json |
Machine-readable output. Available on stats, search and health. |
--help |
Show help for any command |
Scripting¶
--json produces output for jq:
# fail a deploy gate if the cache is suspiciously empty
count=$(medha stats --json | jq '.entries')
[ "$count" -gt 100 ] || { echo "cache underpopulated"; exit 1; }
# alert when the hit rate drops (null until the first snapshot is persisted)
medha stats --json | jq -e '.hit_rate != null and .hit_rate > 0.5' >/dev/null \
|| echo "hit rate below target"
# nightly maintenance
medha expire && medha dedup
Commands exit non-zero on failure, so && chaining and set -e behave as expected.
See Also¶
- Configuration — full
MEDHA_*variable reference - Feedback Loop —
feedback_incorrect_thresholdand auto-invalidation - Observability — in-process metrics the CLI cannot see
- Batch Operations — the library equivalents of
warm,dedupandexport - Demo 26 — CLI