mcp-mistral-queue
An MCP (Model Context Protocol) server and CLI tool that coordinates local and multi-process / multi-client calls to the Mistral free tier (~1 request / 30 seconds) via a shared SQLite queue. It uses SQLite (WAL mode) and async queueing with a single in-flight task to space request starts. This is best-effort traffic control, not an official SLA.
Package: mcp-mistral-queue on PyPI · console script: mmq (not the package name) · current release: 0.1.1
Features
- Automatic rate-limit coordination: Shared ~31s start interval; on 429, shared backoff then re-enter the gate. Resets to the base interval on success.
- Multi-process & priority control: Multiple processes/tasks can enqueue work. Priority (1–3) plus single in-flight processing order the queue.
- Flexible model & message options: Any Mistral chat model name (defaults to
mistral-small-latest; e.g.mistral-large-latest,codestral-latest), plus full conversation history via amessagesarray. - Streaming & cancel handling: Streams the Mistral API response internally (tool returns the full text); on client cancel (
CancelledError) updates task status in the DB. - Local control DB: Temp DB under a per-user directory with mode
0700(path overridable viaMMQ_TEMP_DB_PATH). - PyPI / uvx: Install once or run ephemerally; entry point is
mmq. - Mistral Vibe / Grok / Claude Desktop: Register as an MCP server (
mmq --mcp). Do not usevibe mmq.py "..."— that runs Vibe’s agent CLI, not this tool. - Good free-tier fit: Occasional jobs (e.g. translating docs) that can wait ~31s between calls without burning a dedicated rate-limit stack.
Prerequisites
- Python 3.10+
- uv recommended (
uvx/uv run);pipalso works - A Mistral API key (
MISTRAL_API_KEY)
export MISTRAL_API_KEY="your-mistral-api-key"
Install (PyPI)
Published and verified on PyPI.
# One-shot (no permanent install) — recommended for MCP hosts
uvx --from mcp-mistral-queue mmq --help
# Or install into an environment
uv pip install mcp-mistral-queue
# pip install mcp-mistral-queue
mmq --help
Quick smoke (needs MISTRAL_API_KEY; counts against free-tier quota):
uvx --from mcp-mistral-queue mmq "Reply with pong only."
Notes:
- Console script name is
mmq. Wrong:uvx mcp-mistral-queue --mcp. Right:uvx --from mcp-mistral-queue mmq --mcp. - Dependencies:
mcp[cli]>=1.0.0,<2,mistralai>=1.0.0,<2(pulled in by the package).
Usage
1. CLI mode
After PyPI install / via uvx, invoke mmq.
From a git checkout you can still use uv run mmq.py ... (PEP 723).
# Basic run (default model: mistral-small-latest)
uvx --from mcp-mistral-queue mmq "Explain Python list comprehensions briefly"
# or: mmq "Explain Python list comprehensions briefly"
# Choose a model (e.g. mistral-large-latest, codestral-latest)
mmq -m mistral-large-latest "Explain a complex algorithm"
# Custom system prompt
mmq -s "You are an AI that speaks casually." "How is the weather today?"
# Priority (1: high, 2: normal, 3: low)
mmq --priority 1 "Urgent question"
# Full conversation context as a messages JSON array
# (specify either prompt or --messages, not both)
mmq --messages '[{"role":"system","content":"Strict programmer"},{"role":"user","content":"What is ownership in Rust?"}]'
# Emergency brake: cancel queued / stuck work (no API call)
mmq --purge # cancel all pending
mmq --purge-all # cancel pending + processing
mmq --purge-id 42 # cancel one task by ID
2. MCP server mode (Vibe / Grok / Claude Desktop / …)
Expose ask_mistral and get_queue_status to MCP hosts.
Separate path from CLI prompts.
PyPI / uvx (recommended)
{
"mcpServers": {
"mistral-queue": {
"command": "uvx",
"args": ["--from", "mcp-mistral-queue", "mmq", "--mcp"],
"env": {
"MISTRAL_API_KEY": "your-mistral-api-key"
}
}
}
}
If mmq is already on PATH (venv / uv pip install):
{
"mcpServers": {
"mistral-queue": {
"command": "mmq",
"args": ["--mcp"],
"env": {
"MISTRAL_API_KEY": "your-mistral-api-key"
}
}
}
}
Local checkout (development)
{
"mcpServers": {
"mistral-queue": {
"command": "uv",
"args": [
"run",
"--with", "mcp[cli]>=1.0.0,<2",
"--with", "mistralai>=1.0.0,<2",
"--no-project",
"/absolute/path/to/mmq.py",
"--mcp"
],
"env": {
"MISTRAL_API_KEY": "your-mistral-api-key"
}
}
}
}
After changing config, restart the client. Manual Vibe checklist: docs/SMOKE_VIBE.md.
3. Environment variables (optional)
| Variable | Default | Purpose |
|---|---|---|
MISTRAL_API_KEY |
(required) | Mistral API key |
MMQ_TEMP_DB_PATH |
per-user under tempdir | Shared queue DB file path |
MMQ_BASE_WAIT_TIME |
31 |
Seconds between starts (free-tier pacing) |
MMQ_DEFAULT_MODEL |
mistral-small-latest |
Default model name |
MMQ_FAKE_API |
off | Offline / e2e: fake client (1/true) |
Other knobs (MMQ_MAX_WAIT_TIME, MMQ_MAX_RETRIES, …) exist for tuning; see mmq.py.
MCP tools
When the server is running, clients can use the following tools:
ask_mistral
| Argument | Type | Default | Description |
|---|---|---|---|
| prompt | string | null | Single-shot user prompt text |
| messages | array | null | Conversation history ([{"role": "...", "content": "..."}]) |
| model | string | "mistral-small-latest" |
Mistral model name |
| system_prompt | string | null | Custom system prompt (only when using prompt) |
| priority | number | 2 | Task priority (1: high, 2: normal, 3: low) |
get_queue_status
Returns current shared queue / rate-limit status as JSON:
| Field | Type | Description |
|---|---|---|
| pending | number | Tasks waiting in the queue |
| processing | number | Tasks currently claimed / running |
| seconds_until_next_slot | number | Seconds until the shared API gate opens |
| current_wait_interval | number | Active shared wait interval (seconds) |
| in_flight | boolean | Whether any task is currently processing |
Control data location
The coordination temp DB is stored in a per-user directory created with mode 0700:
- Default:
<tempdir>/mcp_mistral_queue_<USER>/mcp_mistral_flow_control.db
(tempfile.gettempdir(), often/tmpon Linux) - Override: set
MMQ_TEMP_DB_PATHto a full file path (parent dir is created with0700)
Tests
# Unit + e2e (fake API; no network required)
uv run --with 'mcp[cli]>=1.0.0,<2' --with 'mistralai>=1.0.0,<2' \
--with pytest --with pytest-asyncio --no-project \
python -m pytest tests/ -v -m "not live"
# e2e only
uv run --with 'mcp[cli]>=1.0.0,<2' --with 'mistralai>=1.0.0,<2' \
--with pytest --with pytest-asyncio --no-project \
python -m pytest tests/e2e -v -m "not live"
# Live API (optional; consumes free-tier quota)
export MISTRAL_API_KEY=...
uv run --with 'mcp[cli]>=1.0.0,<2' --with 'mistralai>=1.0.0,<2' \
--with pytest --with pytest-asyncio --no-project \
python -m pytest tests/e2e/test_live_api.py -v -m live
e2e uses MMQ_FAKE_API=1 and a short MMQ_BASE_WAIT_TIME to exercise process boundaries (CLI / MCP stdio).
For a manual Vibe UI check, see docs/SMOKE_VIBE.md.
Example: batch-style use of mmq (scripts/translate_readme.py)
Besides the CLI and MCP server, you can call the queue from Python. This repo ships a small sample:
scripts/translate_readme.py — regenerate locale READMEs from the English source via the same free-tier queue as mmq / ask_mistral.
| Idea | Why it fits mmq |
|---|---|
| Occasional job | Docs change far less often than chat traffic |
| Can wait ~31s | ja then fr each take a gated slot |
| Shared DB | Does not bypass other free-tier clients on the machine |
| Programmatic API | Uses execute_mistral_queue_async + MistralRequest |
Locales workflow: edit README.md (English) only; do not hand-maintain README.ja.md / README.fr.md.
export MISTRAL_API_KEY=...
# optional: TRANSLATE_MODEL=mistral-small-latest
# From a git checkout (imports mmq.py on PYTHONPATH via the script)
python scripts/translate_readme.py # → README.ja.md + README.fr.md
python scripts/translate_readme.py --lang ja # one language
python scripts/translate_readme.py --dry-run # preview, no write
What the sample does:
- Protects fenced code blocks (line FSM) and inline
codewith placeholders - Enqueues one translation job per language through
execute_mistral_queue_async - Restores placeholders, fixes the language switcher, validates (e.g. balanced fences)
- Writes outputs atomically
Use it as a template for other infrequent batch jobs (summaries, structured extraction) that should share the free-tier gate.
Further docs
- docs/SMOKE_VIBE.md — Vibe / MCP manual smoke
- docs/SEARCH_POSITIONING.md — where web search belongs (outside mmq base)
- docs/tasks.md — backlog
- docs/NOTES.md — design notes
License
MIT License
Copyright (c) 2026 utenadev
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_mistral_queue-0.1.1.tar.gz.
File metadata
- Download URL: mcp_mistral_queue-0.1.1.tar.gz
- Upload date:
- Size: 21.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
851691600e35f5da7d040638dcf568b9ee3ca84df867b7c69e1b3b77d996496d
|
|
| MD5 |
d4917de9fce9d7eb4d3e33511e8ce975
|
|
| BLAKE2b-256 |
8e0edd3e30c977786705a4499f0f1660154338e8eabc2c5db0beb07357091fde
|
File details
Details for the file mcp_mistral_queue-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mcp_mistral_queue-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5de6a38bb7dbefce4bda35afbd549603fb5f06cab8c0b2a0eb777cc3c0ea15fd
|
|
| MD5 |
838ac9f031ff938e79af56c2b7c2707b
|
|
| BLAKE2b-256 |
6c2b3b205406ecf5a1cd8c02ea006818ea9c677e44c26baa629b87e1cdd967e0
|