mqlite was shaped so a model can drive it without tripping: every operation is
one HTTP POST with a JSON body, there is exactly one settlement verb per outcome (no aliases
to confuse a model), GET / returns a machine-readable discovery card, and delivery
semantics are documented as testable invariants. Three ways in, strongest first.
mqlite-mcp ships in the same repo — a dependency-free stdio MCP server that turns each tool call into one HTTP POST to the broker.
Install v0.3.3 with go install github.com/mqlitehq/mqlite/cmd/mqlite-mcp@v0.3.3,
or use mqlite-mcp from a
v0.3.3 release archive,
then register the installed binary with your MCP host:
{
"mcpServers": {
"mqlite": {
"command": "/path/to/mqlite-mcp",
"env": {
"MQLITE_ENDPOINT": "https://your-broker.example.com",
"MQLITE_TOKEN": "mqk_..."
}
}
}
}
v0.3.3 provides 18 tools. The observe tool requires both the broker and MCP server at v0.3.2 or later. Key-management tools require v0.3.1 or later:
| Tool | Does |
|---|---|
list_queues | list queues / subscriptions |
create_queue | create or update a queue by name |
send | send a message (queue, body, optional message_id / group_id) |
receive | peek-lock messages → returns seq_number + lock_token |
complete / abandon / reject | settle: done / retry / dead-letter |
renew | extend a held lock before it expires — hold a message across long work |
defer / receive_deferred | set a locked message aside by seq_number, then fetch deferred messages back by seq |
peek | browse without locking (optionally by state) |
stats | queue depth by state |
observe | broker health, queue snapshots, message effects, storage and request measurements (since v0.3.2) |
redrive / purge | move dead letters back / delete them |
create_key | issue a key with id, name, permissions and optional expires_at_ms; token returned once |
list_keys | list public metadata with after_id / limit / sort, including revoked and expired keys |
revoke_key | revoke by public id; repeated revocation is safe |
Key tools require manage; both configured administrators and managed manage keys may issue new administrator keys. Give message producers send and consumers listen. A consumer may settle or delete messages; listen is not an audit-only role.
For a monitoring-only MCP connection in v0.3.3, put a configured MQLITE_MONITOR_TOKENS credential into the client's MQLITE_TOKEN. It can call observe, but cannot read message bodies, consume messages, change queues or issue keys. Use the returned collection status and availability fields; unavailable measurements are not healthy zeroes. See Observability. The observe tool works independently of the optional Prometheus switch; --metrics only enables authenticated /metrics on the API port.
Choose and retain a unique 32-character lowercase hex public ID before calling the tool:
{
"name": "create_key",
"arguments": {
"id": "e734810a9f634d75bd8a029c1f7e5062",
"name": "orders-producer",
"permissions": ["send"]
}
}
Save the returned mqk_ + 64 lowercase hex token securely; it appears once in the tool result and may be retained by the MCP host. Keep the public ID for listing and revocation. After a lost creation response, reconcile that ID and revoke a possibly-created key before issuing another; retrying the same ID cannot recover its secret. Follow next_after_id through list_keys pages. See Access keys for expiry, rotation and recovery.
Lists default to sort: "id_asc". Use sort: "created_desc" for newest-created keys first, with descending public ID for timestamp ties; keep the same sort on each page. Creation-order cursors must identify an existing key. Default ID order also accepts absent predecessor IDs for lost-response reconciliation.
Details: docs/mcp.md.
For any agent that can run curl or make HTTP calls. Fill in the two placeholders and paste this into your agent's system prompt or task context:
You have access to a message queue (an mqlite broker).
Base URL: <MQLITE_ENDPOINT> the broker's origin, including the port.
Direct: http://127.0.0.1:6754 (mqlite serves JSON-over-HTTP on TCP 6754
and terminates no TLS of its own)
Proxied: https://mq.example.com (HTTPS :443 at a reverse proxy, which
forwards to the broker's internal :6754)
Endpoint paths below are relative to this origin.
Auth: every call needs the header Authorization: Bearer <MQLITE_TOKEN>
Protocol: every operation is ONE HTTP POST with a JSON body to
/mqlite.v1.QueueService/<Method>, /mqlite.v1.AdminService/<Method>,
or /mqlite.v1.AuthService/<Method> (v0.3.1 and later).
GET / (no auth) returns a discovery card listing every endpoint.
Rules:
- Key rights: send produces/schedules/cancels; listen receives/settles/renews/peeks
and reads queue stats; manage includes both and administration/key issuance.
Rights apply across the broker. Do not retry 401 or 403; obtain a valid key
with the required permission from an administrator.
- On v0.3.2+, AdminService/Observe {} reads broker measurements using a configured
monitor credential or manage key. Check collection/availability fields; missing
measurements are not zero. Monitor credentials cannot read message bodies.
- Message bodies are BASE64 strings in JSON. Encode before sending,
decode after receiving.
- Queues never auto-create. Create first:
AdminService/CreateQueue {"name":"jobs","config":{}}
- Consume with Peek-Lock:
QueueService/Receive {"queue":"jobs","max_messages":1,"wait_time_ms":5000}
Each returned message has seq_number + lock_token. You MUST settle every
message you receive, using its lock_token:
QueueService/Complete {"queue":"jobs","seq_number":N,"lock_token":"..."} done
QueueService/Abandon {...,"delay_ms":60000} retry later (optional backoff)
QueueService/Reject {...} give up -> dead-letter queue
If you settle nothing, the lock expires (default 30s). Recovery returns the
message to active, or sends it to the DLQ at its delivery limit.
New settlements and Renew require locked_until_ms > now: the exact deadline
is already expired, even before the reaper runs. An unexpired receipt only lets
the exact request replay a previously committed settlement after expiry.
- Receive-and-Delete grants no lease: lock_token is empty and locked_until_ms
is zero (omitted in JSON), including receive-attempt replays. Do not settle it.
- Default Peek-Lock delivery is AT-LEAST-ONCE: you may see a message twice.
Make your handling idempotent (set message_id on send; check your own state
before acting).
- Long-running work: call QueueService/Renew with the lock_token to extend the
lock before it expires.
- Pub/sub: AdminService/Subscribe {"topic":"events","name":"my-sub",
"filter":{"expr":"subject == \"order\""}} — then Send to "events" fans out;
Receive from "my-sub". Filter may be omitted (match all).
- Ordered work: send with "group_id" — messages sharing a group_id are
delivered strictly in order, one in flight per group. Abandon with delay_ms > 0
parks the message in scheduled and keeps blocking its ordered group until due
(strict_fifo: the whole queue). Cancel only removes never-delivered scheduled
messages, with delivery_count = 0.
- Errors are JSON {"code","message"}: 400 invalid_argument · 401 unauthenticated ·
403 permission_denied · 404 not_found ·
409 name_conflict / already_exists / lock_lost / key_conflict ·
413 message_too_large. On 409 lock_lost, re-Receive instead of retrying
the settle.
Cheat sheet (request bodies abbreviated):
AdminService/CreateQueue {"name","config":{}}
AdminService/ListQueues {}
AdminService/Subscribe {"topic","name","filter?"}
QueueService/Send {"queue","messages":[{"body":"<base64>",
"message_id?","group_id?"}]}
QueueService/Receive {"queue","max_messages","wait_time_ms"}
QueueService/Complete {"queue","seq_number","lock_token"}
QueueService/Abandon {"queue","seq_number","lock_token","delay_ms?"}
QueueService/Reject {"queue","seq_number","lock_token"}
QueueService/Renew {"queue","seq_number","lock_token"}
QueueService/Stats {"queue"}
AuthService/CreateKey {"id","name","permissions":["send"],"expires_at_ms?"}
AuthService/ListKeys {"after_id?","limit?","sort?"}
AuthService/RevokeKey {"id"}
For CreateKey: retain a unique 32-lowercase-hex id BEFORE the call. Token is
returned once. On an uncertain result, list/revoke that id before replacing;
a repeated id returns key_conflict and never returns the secret again.
For ListKeys: sort defaults to id_asc. Use created_desc for newest first,
keep the same sort on every page, and pass next_after_id back as after_id.
Full reference: https://github.com/mqlitehq/mqlite/blob/main/docs/api-reference.md
lock_lost, never a success that quietly
kept the first call's effect. A live receipt can replay a committed settlement
after its original lease expires; it cannot authorize a new effect or revive
the lease. So a confused agent fails loud, not wrong.Machine-readable entry points on this documentation site; the full bundle is generated from source docs.
| File | Contents |
|---|---|
llms.txt | one-page summary: what mqlite is, the key facts, where everything lives |
llms-full.txt | the full docs bundle as plain markdown: concepts + internals + HTTP API + CLI + access keys + MCP + examples + operations + deployment + observability + cloud monitoring |
GET / on any broker | live discovery card: name, version, auth mode, every endpoint path |
For broker administration, start with Operations, use Deployment for configuration, and follow Observability for monitoring and alerts or Cloud monitoring to reuse an existing collector and Grafana.
message_id or your own
idempotency keys, and settle promptly. Everything else follows from
the concepts page.