QMax: best-price liquidity router and trading terminal for Qubic (QX + QSwap), with an API and x402 rails for AI agents
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
- !No standard license detected
git clone https://github.com/profitphil/qmax{
"mcpServers": {
"qmax": {
"command": "node",
"args": ["/path/to/qmax/dist/index.js"]
}
}
}MCP Servers overview
# QMax
> **About this repository.** This is the open part of QMax: the router, the HTTP API, the website, the SDK, the MCP server and the x402 helpers. Some parts of QMax's own deployment are **not** included: the Max planner, the Max pass logic, the Discord bot (apart from its QU price feed), the server deployment files and every secret. Where code here depends on a withheld part there is a small stand-in file that keeps the types and says so, so the rest builds and runs. All rights reserved: no license is granted.
QMax finds the best route to get you the max for your money on Qubic. Given `buy 5000 ASSET`, it prices the order on the QX order book and the QSwap pool (fees, price impact and transfer costs included) and routes to the cheaper venue, or splits across both.
```
npm i
npm run qmax -- buy 100000 [--snapshot file.json] [--no-split]
npm test
```
## What costs money (and what does not)
**Almost everything is free, to help adoption, since other Qubic sites are free:** the website (no pass, no per-trade fee), the HTTP API (no key, no billing), the SDK, the MCP server and agents. The one thing sold is **Max quotes for agents** (`GET /v1/max`, `API_MAX_PRICE_QU`, **100 QU a plan** on the live server): an agent pays from a prepaid key's balance or holds an x402 session, while the website's own Max and QMax's own keys never pay (below). The Discord bot's subscription exists in the code but is switched off. "Free" is not "unlimited": callers without QMax's own key are limited per IP on the market endpoints (`API_FREE_PER_MIN`, default 60 a minute) so one of them cannot swamp the Qubic node, and QMax's own key (the Discord bot) is not limited. Income is therefore the Max quotes agents buy (and any support tips), and the Discord subscriptions if they are ever switched back on, which is also what the subscribers' profit share is made from (below).
- `API_ACCESS=free` (default): everyone, no key. `billing`: the old prepaid per-call prices and x402 sessions, kept but off. `private`: only `API_KEY` gets in.
- **`API_MAX_PRICE_QU`** (default 0: Max quotes are free; 100 on the live server) sells Max plans to agents inside `API_ACCESS=free`: the meter then serves only `GET /v1/max`, and keys and top-ups work (`POST /v1/keys`, `GET /v1/topup`, `POST /v1/topup/claim`, `GET /v1/account`) but nothing else is charged. Who pays: an agent with a **prepaid key** (`x-api-key`) is charged the price **after** the plan is made, so a request that cannot be planned costs nothing (and one whose balance was spent meanwhile gets a 402, not the plan); an agent with an **x402 session** (`GET /v1/x402`, `API_SESSION_PRICE_QU` for `API_SESSION_SECONDS`) pays nothing per plan; anyone else gets a `402` that names the price and both ways to pay. **Never charged:** QMax's own keys (`API_KEY`, `ADMIN_KEY`) and requests the website's own page makes (a browser marks them `Sec-Fetch-Site: same-origin`, which a page's script cannot change, so another site's page is charged). That is a soft check, not a lock: a program outside a browser can send the same header and save the price, which is why the price is small. A per-plan payment is not offered on purpose: QPayhub keeps at least 100 QU of every payment and a payment takes about ten seconds, so a 100 QU payment per call would lose all its value to the fee. A top-up of 10,000 QU buys 100 plans for a fee of about 1%.
- The website's pass is off. Build the site with `VITE_REQUIRE_PASS=on` to ask for it again (`PAYWALL` in [src/config.ts](src/config.ts) sets its price).
- The sections below on the pass, prepaid API keys and x402 sessions describe those optional modes.
## Fee model (from qubic/core `Qx.h` and `Qswap.h`; verify before trusting)
- **QX:** trade fee 0.3% (`tradeFee` 3,000,000 / 1e9), rounded up per match (`floor(v*rate)+1`). In the contract it comes out of the seller's QU proceeds, so the buyer pays no fee (the docs say "the party holding QUBIC"; check this). No flat fee on an order (checked on-chain on 2026-10-08: a bid attaches exactly price x quantity and fills for no more, e.g. 1,303 QMINE at 3,989 sent 5,197,667 QU and cost exactly that; an ask attaches nothing). The 100 QU asset transfer fee is charged only when management rights are moved between QX and QSwap, which is a step of its own.
- **QSwap:** swap fee 0.3% (`swapFeeRate` 30 / 10,000). Buys use QuoteExactAssetOutput (fee on QU in, rounded up); sells use QuoteExactAssetInput (fee deducted from QU out). The protocol/shareholder/QX shares are paid out of that 0.3% and are not extra. A flat 100,000 QU per-operation fee plus the asset transfer fee is modeled as QSwap's fixed cost.
- Fees, rounding and fixed costs live in `QxConfig` / `QswapConfig`, so they can be changed without touching the router.
## HTTP API
Other DEX sites can call QMax over HTTP (no wallet or SDK needed): `npm run api` (env: `PORT`, `SNAPSHOT`, optional `API_KEY`).
```
GET /v1/quote?side=buy&asset=DEMO&qty=100000[&split=false]
POST /v1/quote {"side":"sell","asset":"DEMO","qty":500}
GET /v1/quotes?side=sell&asset=DEMO&qtys=1000,10000,50000 (several sizes at once; free access only)
GET /v1/assets[?category=contract|token&q=CF] GET /v1/assets/search?name=CFB
GET /v1/openapi.json GET /health
```
The quote response gives `route` (venue, qty, effective price, price impact, fees, QX depth used), `totalQu`, `fillable`, single-venue `alternatives` and `warnings`, and a plain-language `summary` (`src/quotesummary.ts`): the total, the average, where the order goes and what the split is worth, for an assistant that reads rather than computes. `GET /v1/quotes` (`src/quotesroute.ts`) prices up to 10 sizes of the same order from one reading of the markets and says how much worse each size is than the smallest (`averageVsSmallestPct`), so a bot can choose a piece size in one call; it is offered only with `API_ACCESS=free`, because a prepaid deployment bills each split quote and a batch would get around that. Every call that is limited per address carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (seconds), so a caller can slow down before it is refused with a 429 and `Retry-After`; and every error has a steady `code` (`bad_request`, `unauthorized`, `payment_required`, `not_found`, `rate_limited`, …) beside its sentence. CORS is open so browsers can call it directly; set `API_KEY` to require an `x-api-key` header.
### Asset list
`GET /v1/assets` returns every tradable asset (a QX book or a QSwap pool), most liquid first, each with `id`, `symbol`, `issuer`, `category` (`contract` = smart contract shares, `token` = everything else), `venues`, `priceQu` and `liquidityQu`. `ready` is false until the first network scan finishes; results are cached in `.cache/catalog.json` so restarts are instant.
`src/catalog.ts` builds the list: all contract shares (issued by the zero identity), the tokens named in [assets.json](assets.json), and the network's issuance list (which the RPC caps at 150 entries). A token that is not in the list can be added with `GET /v1/assets/search?name=ABC`, which looks the name up on the network, checks that it trades, and keeps it. If two issuers share a name the token gets an id like `GARTH.PHOEN`; the contract share keeps the plain symbol. Scanning is throttled (3 requests/s) and uses its own client, so it never slows a quote.
### Activity filter
Each asset in `GET /v1/assets` has `activity` (`active`, `inactive` or `unknown`) and `lastActiveAt`. `inactive` means no QX order and no pool change within two epochs (14 days). `src/activity.ts` reads QX order history from the archive Query API (`/query/v1/getTransactionsForIdentity`, order types 5 and 6, in 100,000-tick windows, splitting any window that hits the 10,000-result cap). The first scan covers 14 days in a few minutes; after that only new ticks are read, and progress is kept in `.cache/activity.json`. The response also carries `activity: { ready, progress }` while the first scan runs.
Limits: this counts orders placed on QX (including market makers' orders), not completed trades. QSwap has no cheap history, so a pool counts as active when QMax has seen its reserves change since it started watching; a pool is only called quiet after 24 hours of watching, until then it is `unknown` and is not hidden.
### Live data
`npm run api` serves live Qubic data (set `ASSETS=file` to use another seed file; it is a JSON list of token names or `{ symbol, issuer }` objects; `QUBIC_RPC_URL` to change the RPC, default `https://rpc.qubic.org`). Without that file, or with `SNAPSHOT=file` set, it serves the demo snapshot and says so on startup.
`src/live.ts` reads, per asset, through `/live/v1/querySmartContract`:
- **QX** (contract 1): `Fees` (trade fee, transfer fee) and `AssetAskOrders` / `AssetBidOrders`, paged 256 at a time with `offset` up to 2,048 orders per side (a `QX book has N+ orders` warning appears if the cap is hit).
- **QSwap** (contract 13): `Fees` (swap fee, transfer fee) and `GetPoolBasicState` for the reserves. The flat 100,000 QU per-swap fee is the contract's `QSWAP_ADDITIONAL_FEE`.
- State is cached for 5 seconds per asset, and failed reads are retried and never cached.
- Each QSwap allocation is re-checked against the contract's own `QuoteExactAssetOutput` / `QuoteExactAssetInput` and reported as `onChainCheck` (`differenceQu` should be 0).
To always include a token, add its name to `assets.json`. A snapshot-backed or custom source can be used by implementing `MarketData` in `src/data.ts`.
## Web app and wallet
`web/` is a Vite + React app (`npm run dev`). The wallet code in `web/wallet/` is ported from the connect module in [double-k-3033/QRaffle-frontend](https://github.com/double-k-3033/QRaffle-frontend), with the same four login options: MetaMask Snap, WalletConnect (including the existing WalletConnect project ID), private seed and `.qubic-vault` file, plus a fifth, the Qubic Wallet browser extension ([qubic/wallet-extension](https:What people ask about qmax
What is profitphil/qmax?
+
profitphil/qmax is mcp servers for the Claude AI ecosystem. QMax: best-price liquidity router and trading terminal for Qubic (QX + QSwap), with an API and x402 rails for AI agents It has 0 GitHub stars and its last recorded update is dated 2026-10-17.
How do I install qmax?
+
You can install qmax by cloning the repository (https://github.com/profitphil/qmax) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is profitphil/qmax safe to use?
+
Our security agent has analyzed profitphil/qmax and assigned a Trust Score of 70/100 (tier: OK). See the full breakdown of passed checks and flags on this page.
Who maintains profitphil/qmax?
+
profitphil/qmax is maintained by profitphil. The last recorded GitHub activity is dated 2026-10-17, with 1 open issues.
Are there alternatives to qmax?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy qmax to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/profitphil-qmax)<a href="https://claudewave.com/repo/profitphil-qmax"><img src="https://claudewave.com/api/badge/profitphil-qmax" alt="Featured on ClaudeWave: profitphil/qmax" width="320" height="64" /></a>More MCP Servers
Reverse engineer anything with agents, from app behavior down to native binaries.
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ A Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev