These docs track main · source v0.3.3. The latest release is v0.3.3 (default port 6754); installation examples pin that release. Use the v0.3.3 docs for the versioned reference, and follow the upgrade procedure when moving from v0.2.0 (port 8080, schema token 2) to v0.3.0 or later (schema token 5).

# mqlite for AI agents

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.

# 1 · MCP server (recommended)

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:

ToolDoes
list_queueslist queues / subscriptions
create_queuecreate or update a queue by name
sendsend a message (queue, body, optional message_id / group_id)
receivepeek-lock messages → returns seq_number + lock_token
complete / abandon / rejectsettle: done / retry / dead-letter
renewextend a held lock before it expires — hold a message across long work
defer / receive_deferredset a locked message aside by seq_number, then fetch deferred messages back by seq
peekbrowse without locking (optionally by state)
statsqueue depth by state
observebroker health, queue snapshots, message effects, storage and request measurements (since v0.3.2)
redrive / purgemove dead letters back / delete them
create_keyissue a key with id, name, permissions and optional expires_at_ms; token returned once
list_keyslist public metadata with after_id / limit / sort, including revoked and expired keys
revoke_keyrevoke 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.

Create a producer key

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.

# 2 · raw HTTP — a prompt you can paste

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
Why this works well for models: there is no connection state to manage, no binary protocol, no SDK to install — every step is a self-contained POST whose response tells the model exactly what token to use next. A settle whose response you lost can be retried safely while its receipt is unexpired — by resending the same request: same queue, message, lock token, verb and effect-changing arguments. Change that identity and you get 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.

# 3 · for models reading the web

Machine-readable entry points on this documentation site; the full bundle is generated from source docs.

FileContents
llms.txtone-page summary: what mqlite is, the key facts, where everything lives
llms-full.txtthe full docs bundle as plain markdown: concepts + internals + HTTP API + CLI + access keys + MCP + examples + operations + deployment + observability + cloud monitoring
GET / on any brokerlive 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.

# the one rule that matters

mqlite is honestly at-least-once. No queue that survives crashes can promise your handler runs exactly once — mqlite doesn't pretend to. Design agent workflows so that doing a message twice is harmless: key side effects on message_id or your own idempotency keys, and settle promptly. Everything else follows from the concepts page.