Find, call and pay per call: the capability layer for agents, plus skills. One key or OAuth.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Open a developer account for the user (needs their qumge key). There is no review and no waiting: it takes effect immediately, and publish_cap works right after. Give a display name and an ISO country code; the country decides tax and payout rails later. Payout details and legal name are only needed when the user actually withdraws money.
ISO code like "US" or "CN" (a full country name also works).
The name shown on their app pages.
Required if the account has no username yet: 3–30 letters, digits, _ or -. It becomes the public page /u/<username>.
Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back.
individual (default) or company.
Up to 6 public URLs (X, GitHub, LinkedIn, their website). The kind is guessed from the domain.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Open a developer account for the user (needs their qumge key). There is no review and no waiting: it takes effect immediately, and publish_cap works right after. Give a display name and an ISO country code; the country decides tax and payout rails later. Payout details and legal name are only needed when the user actually withdraws money.
| Argument | Type | Description |
|---|---|---|
| country* | string | ISO code like "US" or "CN" (a full country name also works). |
| username | string | Required if the account has no username yet: 3–30 letters, digits, _ or -. It becomes the public page /u/<username>. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
| entity_type | string | individual (default) or company. |
| display_name* | string | The name shown on their app pages. |
| social_links | array | Up to 6 public URLs (X, GitHub, LinkedIn, their website). The kind is guessed from the domain. |
{
"type": "object",
"required": [
"display_name",
"country"
],
"properties": {
"country": {
"type": "string",
"description": "ISO code like \"US\" or \"CN\" (a full country name also works)."
},
"username": {
"type": "string",
"description": "Required if the account has no username yet: 3–30 letters, digits, _ or -. It becomes the public page /u/<username>."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
},
"entity_type": {
"enum": [
"individual",
"company"
],
"type": "string",
"description": "individual (default) or company."
},
"display_name": {
"type": "string",
"description": "The name shown on their app pages."
},
"social_links": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 6 public URLs (X, GitHub, LinkedIn, their website). The kind is guessed from the domain."
}
}
}Call a Cap on the user's behalf and return its response. Use this when you cannot make the HTTP call yourself: qumge charges the user's qumge balance and forwards the call at the same price as calling it over HTTP through Qumge. Operations and prices come from get_cap. Prefer `operation` + `input`: when the operation declares an input_schema, `input` is validated against it before anything is charged or forwarded. For managed results, pass a stable idempotency_key when retrying; asynchronous calls return a platform job_id and get_cap_job reads cached progress and the final receipt for free. Needs the user's qumge key in the Authorization header. A 5xx from the Cap is free; a 402 means the user's balance or this Cap's monthly limit stopped it. (Older clients may still call this tool as call_app — it still works.)
| Argument | Type | Description |
|---|---|---|
| body | object | string | Request body. An object is sent as JSON; a string is sent as-is. |
| path | string | The route path from get_cap, e.g. '/api/videos'. A query string may be appended or passed separately in `query`. |
| slug* | string | The Cap's slug, from search_caps. |
| input | object | Arguments for the operation. Validated against its input_schema when it has one — an invalid input is refused as a tool error (isError), and nothing is charged or forwarded. |
| query | string | Query string without the leading '?'. |
| accept | string | Optional Accept header. |
Check one of the developer's own capabilities: its status (draft / review / live / suspended) and how far the publishing checklist has got. Needs the developer's Qumge key. (Older clients may still call this tool as app_status.)
| Argument | Type | Description |
|---|---|---|
| slug* | string | The Cap's slug. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The Cap's slug."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}The user's Qumge balance, plus what each Cap has spent this month against its monthly limit. Call this before a paid call when the user asks whether they can afford it, and after a 402 that says the balance or a limit stopped the call — it returns the top-up link to hand to the user. Needs the user's qumge key.
| Argument | Type | Description |
|---|---|---|
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [],
"properties": {
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}Fetch one Cap's operations, prices and how to call it, by the slug returned from search_caps. Call this before using a Cap: it lists each operation (by name), its input and output schema when the developer provided one, which routes are billable, the per-call maximum, when the call settles, and the error codes the caller may see. If the request carries the user's Qumge key, it also reports that user's monthly limit for this Cap. (Older clients may still call this tool as get_app — it still works.)
| Argument | Type | Description |
|---|---|---|
| slug* | string | The Cap's slug, e.g. 'autowhisper'. Comes from search_caps. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The Cap's slug, e.g. 'autowhisper'. Comes from search_caps."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}Read your managed Cap job's cached progress, complete result and receipt for free. Use the platform job_id returned by call_cap. Ordinary reads do not invoke the provider. Set refresh_result: true to explicitly request free renewal of declared result URLs after success; the optional private provider command does not generate new work or change the receipt. Existing orders remain readable after Cap revocation.
| Argument | Type | Description |
|---|---|---|
| job_id* | string | Platform job_id from call_cap, starting with ac_. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
| refresh_result | boolean | Optional explicit free renewal of result URLs, when the original Cap declares support; default false. |
{
"type": "object",
"required": [
"job_id"
],
"properties": {
"job_id": {
"type": "string",
"description": "Platform job_id from call_cap, starting with ac_."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
},
"refresh_result": {
"type": "boolean",
"description": "Optional explicit free renewal of result URLs, when the original Cap declares support; default false."
}
}
}What a developer has earned and what is payable: the amount still inside the 30-day holdback, the amount sitting in their wallet (income from Caps — the only part that can be withdrawn), and what has already been paid out, with the most recent entries. Matured purchase amounts move into the wallet automatically. Needs the developer's Qumge key.
| Argument | Type | Description |
|---|---|---|
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [],
"properties": {
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}Fetch the full SKILL.md content of one skill, by the slug returned from search_skills. Write the returned markdown to .claude/skills/<name>/SKILL.md (or the equivalent for the user's agent). If the reply says the skill ships more files (REFERENCE.md, scripts/…), call again with include_files: true to get them and write each next to SKILL.md.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The skill's slug, e.g. 'AgriciDaniel/claude-seo/seo-google'. Comes from search_skills. |
| include_files | boolean | Also return the full text of the other files in the skill's folder. Off by default — they can be hundreds of KB. Use it when installing. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The skill's slug, e.g. 'AgriciDaniel/claude-seo/seo-google'. Comes from search_skills."
},
"include_files": {
"type": "boolean",
"description": "Also return the full text of the other files in the skill's folder. Off by default — they can be hundreds of KB. Use it when installing."
}
}
}List the developer's own Caps with their status (draft / live / suspended) and slug. Use it before publishing to see what already exists, and after to check what went live. Needs the developer's qumge key. (Older clients may still call this tool as list_apps.)
| Argument | Type | Description |
|---|---|---|
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [],
"properties": {
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}List the skill categories and how many skills are in each. Useful when the user is browsing rather than looking for something specific.
No arguments.
{
"type": "object",
"properties": {}
}List the models this gateway can route to, best first. Every one is reachable with the same Qumge key — no per-vendor signup. Only tool-calling models are listed: an agent cannot use the others.
| Argument | Type | Description |
|---|---|---|
| limit | integer | How many to return. Default 20, max 60. |
| query | string | Optional. Filter by name or vendor, e.g. 'claude', 'gemini'. |
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"maximum": 60,
"minimum": 1,
"description": "How many to return. Default 20, max 60."
},
"query": {
"type": "string",
"description": "Optional. Filter by name or vendor, e.g. 'claude', 'gemini'."
}
}
}What agents searched for on Qumge and found nothing: the demand side of the store, in the searchers' own words, with how often each was searched in the last 7 and 30 days. Useful before building or publishing a Cap — it tells you what people already want. Only the search text is stored; no user and no IP.
| Argument | Type | Description |
|---|---|---|
| limit | integer | How many to return. Default 20, max 50. |
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "How many to return. Default 20, max 50."
}
}
}Create or update a DRAFT Cap on the developer's behalf (requires the developer's Qumge key). Prefer manifest v2: pass manifest_url for the project's public qumge.json, and slug to select a Cap when needed. The file supplies the name, connection, operations and suggested prices; do not repeat name or override file fields. Without manifest_url, give name and either connection_config, connection_id, base_url or mcp_url, plus the priced operations. Every billed operation must deliver one complete result for one clear input (e.g. product URL in → finished video out); helper steps such as job status are free, and a result that needs several calls is wrapped into one endpoint — never sell partial steps. Managed execution reserves a fixed price and charges only after valid complete delivery; queued acceptance is not delivery, and failed or expired orders cost nothing. Reuse existing tasks and durable request_id deduplication; providers need no Qumge-specific buyer, order, ledger or usage-reporting tables. Prefer execution.identity: order with self-contained inputs. Use trusted request_id to isolate tasks and private results. For buyer-owned state, explicitly choose identity: buyer and authorize the trusted buyer_key; a shared service account alone does not isolate buyers. Use connection_config or connection_id to share private credentials across Caps. Read https://qumge.com/en/docs/caps/managed.md for the complete contract. Legacy per-response and advanced usage-based fields remain supported for existing integrations; the signing/usage guide applies to those modes, not managed execution. A new signing secret is returned once when applicable. Legacy non-managed integrations may also return a usage key; managed execution does not use it. Nothing is charged while it is a draft. Confirm manifest prices with the developer. There is no human review: after test_cap passes, submit_cap takes the Cap live immediately, and qumge spot-checks it afterwards (a spot check can suspend it). (Older clients may still call this tool as publish_app.)
| Argument | Type | Description |
|---|---|---|
| name | string | Store name. Required only without manifest_url; manifest publication reads it from the file and ignores this duplicate field. |
Ask for a payout of the developer's payable balance (Cap income only — topped-up money cannot be withdrawn). Call it once without `confirmed` to get the estimate (amount, channel fee, withholding tax, what actually lands), show that to the user, and only then call again with confirmed: true. Needs the developer's Qumge key.
| Argument | Type | Description |
|---|---|---|
| confirmed | boolean | Set true only after the user has seen the estimate and agreed. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
| amount_usd* | number | How much to withdraw, in US dollars. |
{
"type": "object",
"required": [
"amount_usd"
],
"properties": {
"confirmed": {
"type": "boolean",
"description": "Set true only after the user has seen the estimate and agreed."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
},
"amount_usd": {
"type": "number",
"description": "How much to withdraw, in US dollars."
}
}
}Search Qumge's Caps — paid services an agent can call, billed per call from the user's Qumge balance. A Cap (short for capability) is one finished job: somebody's API or MCP server with a price list; to you it is a set of operations. Use this when the user wants something done rather than a skill to install: 'make a promo video', 'transcribe this call'. Returns the best few with pricing, measured success rate and latency, and the slug to pass to get_cap. (Older clients may still call this tool as search_apps — it still works.)
| Argument | Type | Description |
|---|---|---|
| limit | integer | How many to return. Default 5, max 10. |
| query | string | What the user wants done, in their own words. Omit to browse the most-used Caps. |
| max_price_usd | number | Optional ceiling: drop Caps whose per-call price is above this, in US dollars. |
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"maximum": 10,
"minimum": 1,
"description": "How many to return. Default 5, max 10."
},
"query": {
"type": "string",
"description": "What the user wants done, in their own words. Omit to browse the most-used Caps."
},
"max_price_usd": {
"type": "number",
"description": "Optional ceiling: drop Caps whose per-call price is above this, in US dollars."
}
}
}Search Qumge's curated catalog of agent skills (SKILL.md files) by what the user wants to accomplish. Use this whenever the user asks for a skill, tool, or Cap — e.g. 'find me a skill for social media automation', 'is there a skill for SEO audits'. Returns the best few, ranked by how useful they actually are (an LLM read each one), with a one-line summary and the exact slug to pass to get_skill.
| Argument | Type | Description |
|---|---|---|
| limit | integer | How many to return. Default 5, max 10. |
| query | string | What the user wants to do, in their own words. e.g. 'automate posting to social media', 'extract tables from PDFs'. Omit it to browse the top-ranked skills instead. |
| offset | integer | Skip this many results — for paging through a long list. |
| category | string | Optional. Narrow to one category. Call list_categories to see them. |
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"maximum": 10,
"minimum": 1,
"description": "How many to return. Default 5, max 10."
},
"query": {
"type": "string",
"description": "What the user wants to do, in their own words. e.g. 'automate posting to social media', 'extract tables from PDFs'. Omit it to browse the top-ranked skills instead."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Skip this many results — for paging through a long list."
},
"category": {
"enum": [
"automation-workflow",
"api-integration",
"ai-agent-dev",
"design-frontend",
"data-analytics",
"code-review-debug",
"content-writing",
"code-write-refactor",
"marketing-growth",
"testing",
"documentation",
"devops-security",
"database",
"personal-productivity",
"files-spreadsheets",
"other"
],
"type": "string",
"description": "Optional. Narrow to one category. Call list_categories to see them."
}
}
}Take one of the developer's Caps live. Nothing is reviewed before launch and nobody approves it: when the applicable connection/operation checks and price book pass, with complete billed-operation docs, this publishes the Cap immediately and agents can call it — and be charged — from then on. Run test_cap first (legacy checklist keys remain signature and end_to_end; the price book is recorded when it saves). Passing native connection checks or isolated fixtures does not verify real delivery. Qumge spot-checks docs and support afterwards and can suspend the Cap. Needs the developer's Qumge key. (Older clients may still call this tool as submit_app_review.)
| Argument | Type | Description |
|---|---|---|
| slug* | string | The Cap's slug. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The Cap's slug."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}Run the applicable publication checks after publish_cap, before submit_cap. Managed qumge wrapper operations use authenticated isolated fixture hooks and validate the complete fixture result. Native managed API/MCP operations check HTTP OPTIONS or MCP tools/list for connection/schema evidence without invoking generation. The verification array distinguishes connection, fixture and real_delivery scopes; real delivery is not tested. Legacy integrations may call one free and one billable route, or each published MCP tool, directly with probe inputs; Qumge does not charge for these probes, but the developer may incur provider costs. Signed wrapper/legacy APIs also test /qumge/ping with valid, forged and stale signatures; legacy usage-reporting routes must report probe usage. Missing billed-operation docs block publishing. Needs the developer's Qumge key. (Older clients may still call this tool as test_app.)
| Argument | Type | Description |
|---|---|---|
| slug* | string | The Cap's slug. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The Cap's slug."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}Prove the developer owns the domain of their MCP server or API. Going live does not need it: an unverified Cap is live and charges callers, but the developer's earnings from it stay frozen until this passes — verifying releases them. Call with the service's https url: if the domain (or a parent domain) is already verified it says so; otherwise it returns a one-line file to serve at /.well-known/qumge-verify.txt on that host (or a DNS TXT record with the same line). Put the file into the project so it ships with the next deploy, then call again with check: true. Needs the developer's Qumge key.
| Argument | Type | Description |
|---|---|---|
| url* | string | The service's https url, e.g. https://api.example.com/mcp |
| check | boolean | true = look for the line now (after the user deployed it). |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "The service's https url, e.g. https://api.example.com/mcp"
},
"check": {
"type": "boolean",
"description": "true = look for the line now (after the user deployed it)."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
}
}
}| method | string | HTTP method. Default GET — the routes and their methods are in get_cap. |
| operation | string | Operation name from get_cap (a route's `name`). Use with `input`; takes precedence over `path`/`method` when both are given. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
| content_type | string | Only needed when `body` is a string and the app expects a specific type. |
| idempotency_key | string | Stable key for retries of the same operation and input. Replays the original managed order; changed input is rejected. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"body": {
"type": [
"object",
"string"
],
"description": "Request body. An object is sent as JSON; a string is sent as-is."
},
"path": {
"type": "string",
"description": "The route path from get_cap, e.g. '/api/videos'. A query string may be appended or passed separately in `query`."
},
"slug": {
"type": "string",
"description": "The Cap's slug, from search_caps."
},
"input": {
"type": "object",
"description": "Arguments for the operation. Validated against its input_schema when it has one — an invalid input is refused as a tool error (isError), and nothing is charged or forwarded."
},
"query": {
"type": "string",
"description": "Query string without the leading '?'."
},
"accept": {
"type": "string",
"description": "Optional Accept header."
},
"method": {
"enum": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE",
"HEAD",
"OPTIONS"
],
"type": "string",
"description": "HTTP method. Default GET — the routes and their methods are in get_cap."
},
"operation": {
"type": "string",
"description": "Operation name from get_cap (a route's `name`). Use with `input`; takes precedence over `path`/`method` when both are given."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
},
"content_type": {
"type": "string",
"description": "Only needed when `body` is a string and the app expects a specific type."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Stable key for retries of the same operation and input. Replays the original managed order; changed input is rejected."
}
}
}| slug |
| string |
| Optional URL slug. Derived from the name when omitted. With manifest_url: picks which Cap in the file to publish. |
| events | array | Manual price book. unit_price_usd is USD, e.g. 0.10. A managed operation uses one fixed-price event; advanced usage-based events belong to legacy integrations. |
| routes | array | Manual HTTP operations. Managed routes include execution and input/output schemas; the referenced event supplies the fixed price. Legacy routes use hold_usd as a per-call ceiling. |
| mcp_url | string | Optional: publish an existing remote MCP server instead of an HTTP API. Must be https. The domain does not need to be verified to go live, but earnings stay frozen until verify_domain passes for it. Qumge calls tools/list to discover the tools, and every tool you price with `mcp_tools` becomes one operation. Managed execution charges only after a valid complete result, not queued acceptance. Legacy tools without a managed connection or execution use per-response pricing: successful non-error replies are charged; non-2xx, timeouts, isError: true and JSON-RPC errors are free. |
| summary | string | One line describing what it does. |
| base_url | string | Where the API lives. Must be https. For manual publication without manifest_url, connection_config, connection_id or mcp_url. Any path in it (https://host/v2) is part of what your server receives and is covered by the signature. |
| keywords | array | Other names for the same thing, any language, up to 20. Agents search with a request like "scrape trending TikTok videos" — the keywords are what makes that find this app. |
| metering | string | Legacy usage-based mode only: reported (provider reports usage) or balance_delta (Qumge reads its balance). Managed execution needs neither usage reporting nor a usage key. |
| auth_mode | string | Manual service authentication; named connections declare it through connection_config.auth instead. signature (default) verifies signed requests; managed wrappers use trusted context, while legacy signed integrations also answer GET /qumge/ping. api_key sends upstream_token as the developer's Bearer key. Legacy api_key routes require exact paths and meter: platform; managed routes declare execution. |
| mcp_tools | array | Prices for the MCP tools you want listed. Include execution and result schemas for managed complete-result delivery. Tools you leave out are not published and are reported back to you. |
| qumge_key | string | Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back. |
| unit_name | string | What users buy, e.g. credit. |
| skill_slug | string | Optional. Attach an existing skill from the catalog to this app (its documentation then shows on the app page). Ignored if the slug is unknown. |
| support_url | string | Where users ask for help. Shown on the app page. |
| balance_path | string | Only for balance_delta: where we read the balance. |
| manifest_url | string | Optional: publish from the project's qumge.json instead of passing everything by hand. Give https://<domain>/.well-known/qumge.json (or the service address). Its prices are suggestions: confirm them with the developer before submit_cap. The file supplies name, connection and operations; do not repeat name. Prefer manifest v2 for managed complete results. With several Caps in the file, pass `slug` to pick one (one call per Cap). Spec: https://qumge.com/docs/caps/manifest |
| social_links | array | Up to 6 public URLs for the developer (X, GitHub, LinkedIn, their website). Shown on every app page. The kind is guessed from the domain. |
| connection_id | string | Existing connection_id returned by publish_cap, belonging to this developer. Use instead of connection_config. |
| upstream_token | string | The developer's own service key. Required for a new api_key or authenticated MCP connection, and legacy balance_delta. With manifest_url, provide it when the selected connection needs api_key authentication and has no stored key. Reusable connections retain their credentials. Stored encrypted; sent as Authorization: Bearer. |
| balance_json_path | string | Only for balance_delta: where in that response. |
| connection_config | object | Reusable private service connection. Repeating the same developer/name reuses credentials when endpoint and authentication agree. |
| refund_policy_url | string | Their refund policy, if they have one. |
{
"type": "object",
"$defs": {
"usd": {
"type": "number",
"maximum": 50,
"minimum": 0.001
},
"link": {
"type": "string",
"pattern": "^(https://|mailto:)\\S+$",
"maxLength": 2000
},
"text": {
"type": "string",
"maxLength": 2000,
"minLength": 1
},
"pointer": {
"type": "string",
"pattern": "^(?:|/(?:[^~\\s]|~[01])*)$",
"maxLength": 500
},
"endpoint": {
"type": "object",
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "api"
}
}
},
"then": {
"not": {
"required": [
"mcp_url"
]
},
"required": [
"base_url"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "mcp"
}
}
},
"then": {
"not": {
"required": [
"base_url"
]
},
"required": [
"mcp_url"
]
}
}
],
"required": [
"type",
"auth"
],
"properties": {
"auth": {
"enum": [
"api_key",
"signed"
]
},
"type": {
"enum": [
"api",
"mcp"
]
},
"mcp_url": {
"$ref": "#/$defs/https_url"
},
"base_url": {
"$ref": "#/$defs/https_url"
}
},
"additionalProperties": false
},
"execution": {
"type": "object",
"allOf": [
{
"if": {
"required": [
"protocol"
],
"properties": {
"protocol": {
"const": "qumge"
}
}
},
"then": {
"not": {
"required": [
"deadline_field"
]
}
}
}
],
"properties": {
"mode": {
"enum": [
"sync",
"async"
]
},
"cancel": {
"$ref": "#/$defs/state_operation"
},
"status": {
"$ref": "#/$defs/state_operation"
},
"mapping": {
"type": "object",
"properties": {
"error": {
"$ref": "#/$defs/pointer"
},
"job_id": {
"$ref": "#/$defs/pointer"
},
"result": {
"$ref": "#/$defs/pointer"
},
"states": {
"type": "object",
"maxProperties": 50,
"propertyNames": {
"maxLength": 100,
"minLength": 1
},
"additionalProperties": {
"enum": [
"queued",
"running",
"succeeded",
"failed"
]
}
},
"status": {
"$ref": "#/$defs/pointer"
}
},
"additionalProperties": false
},
"delivery": {
"type": "object",
"properties": {
"refresh": {
"$ref": "#/$defs/state_operation"
},
"url_fields": {
"type": "array",
"items": {
"$ref": "#/$defs/pointer",
"minLength": 1
},
"maxItems": 20,
"minItems": 1,
"uniqueItems": true
},
"retention_seconds": {
"type": "integer",
"maximum": 31536000,
"minimum": 1
}
},
"dependentRequired": {
"refresh": [
"retention_seconds",
"url_fields"
]
},
"additionalProperties": false
},
"identity": {
"enum": [
"order",
"buyer"
]
},
"protocol": {
"enum": [
"native",
"qumge"
]
},
"idempotency": {
"type": "object",
"required": [
"mode"
],
"properties": {
"mode": {
"enum": [
"none",
"native",
"lookup"
]
},
"lookup": {
"$ref": "#/$defs/state_operation"
},
"request_id_field": {
"$ref": "#/$defs/pointer",
"minLength": 1
},
"request_id_header": {
"type": "string",
"pattern": "^[A-Za-z0-9-]+$",
"maxLength": 100,
"minLength": 1
}
},
"additionalProperties": false
},
"deadline_field": {
"$ref": "#/$defs/pointer",
"minLength": 1
},
"buyer_key_field": {
"$ref": "#/$defs/pointer",
"minLength": 1
},
"completion_timeout_seconds": {
"type": "integer",
"maximum": 86400,
"minimum": 1
}
},
"additionalProperties": false
},
"https_url": {
"type": "string",
"pattern": "^https://[A-Za-z0-9.-]+(:[0-9]{1,5})?(/[^\\s?#]*)?$",
"maxLength": 2000
},
"operation": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[A-Za-z0-9_.-]{1,60}$"
},
"path": {
"type": "string",
"pattern": "^/[^*{}\\s?#]{0,499}$"
},
"tool": {
"type": "string",
"maxLength": 100,
"minLength": 1
},
"title": {
"$ref": "#/$defs/text"
},
"method": {
"enum": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
]
},
"execution": {
"$ref": "#/$defs/execution"
},
"price_usd": {
"$ref": "#/$defs/usd"
},
"free_calls": {
"type": "integer",
"maximum": 100,
"minimum": 0
},
"description": {
"$ref": "#/$defs/text"
},
"limitations": {
"$ref": "#/$defs/text"
},
"when_to_use": {
"$ref": "#/$defs/text"
},
"input_schema": {
"type": "object"
},
"example_input": {},
"output_schema": {
"type": "object"
}
},
"additionalProperties": false
},
"capability": {
"type": "object",
"required": [
"name",
"summary",
"connection",
"operations"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"minLength": 1
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{0,59}$"
},
"summary": {
"type": "string",
"maxLength": 500,
"minLength": 1
},
"keywords": {
"type": "array",
"items": {
"type": "string",
"maxLength": 40,
"minLength": 1
},
"maxItems": 20
},
"unit_name": {
"type": "string",
"pattern": "^[a-z][a-z0-9_ -]{0,29}$"
},
"connection": {
"type": "string",
"pattern": "^[A-Za-z0-9_.-]{1,60}$"
},
"operations": {
"type": "array",
"items": {
"$ref": "#/$defs/operation"
},
"maxItems": 50,
"minItems": 1
},
"price_hints": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"typical_units"
],
"properties": {
"label": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"typical_units": {
"type": "integer",
"minimum": 1
}
},
"additionalProperties": false
},
"maxItems": 4
},
"support_url": {
"$ref": "#/$defs/link"
},
"refund_policy_url": {
"$ref": "#/$defs/link"
}
},
"additionalProperties": false
},
"template_value": {
"anyOf": [
{
"type": "string",
"pattern": "^(?:[^{}]|\\{(?:job_id|request_id)\\})*$",
"maxLength": 500
},
{
"type": [
"number",
"boolean",
"null"
]
}
]
},
"state_operation": {
"oneOf": [
{
"type": "object",
"required": [
"method",
"path"
],
"properties": {
"body": {
"$ref": "#/$defs/template_object"
},
"path": {
"type": "string",
"pattern": "^/(?:[^*{}\\s?#]|\\{(?:job_id|request_id)\\})*$",
"maxLength": 500
},
"query": {
"$ref": "#/$defs/template_object"
},
"method": {
"enum": [
"GET",
"POST"
]
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"tool"
],
"properties": {
"tool": {
"type": "string",
"maxLength": 100,
"minLength": 1
},
"arguments": {
"$ref": "#/$defs/template_object"
}
},
"additionalProperties": false
}
]
},
"template_object": {
"type": "object",
"maxProperties": 50,
"additionalProperties": {
"$ref": "#/$defs/template_value"
}
}
},
"anyOf": [
{
"required": [
"manifest_url"
]
},
{
"required": [
"name"
]
}
],
"properties": {
"name": {
"type": "string",
"description": "Store name. Required only without manifest_url; manifest publication reads it from the file and ignores this duplicate field."
},
"slug": {
"type": "string",
"description": "Optional URL slug. Derived from the name when omitted. With manifest_url: picks which Cap in the file to publish."
},
"events": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"unit_price_usd"
],
"properties": {
"key": {
"type": "string"
},
"label": {
"type": "string"
},
"unit_price_usd": {
"type": "number"
}
}
},
"description": "Manual price book. unit_price_usd is USD, e.g. 0.10. A managed operation uses one fixed-price event; advanced usage-based events belong to legacy integrations."
},
"routes": {
"type": "array",
"items": {
"type": "object",
"required": [
"pattern"
],
"properties": {
"doc": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"limitations": {
"type": "string"
},
"when_to_use": {
"type": "string"
},
"input_schema": {
"type": "object",
"description": "JSON Schema 2020-12."
},
"example_input": {
"type": "object"
},
"output_schema": {
"type": "object",
"description": "JSON Schema 2020-12."
}
},
"description": "What this operation does and what it takes, for agents. Optional, but without it an agent can only guess the input shape (call_cap validates `input` against doc.input_schema)."
},
"lane": {
"enum": [
"standard",
"micro"
],
"type": "string",
"description": "standard (default: one ledger row per call) or micro — for routes priced below $0.001. A micro route must settle on_response, its per-call ceiling must be at most $0.01, and calls settle in per-minute buckets instead of one row each."
},
"name": {
"type": "string"
},
"event": {
"type": "string",
"description": "Which price-book event this route bills. Defaults to the first event."
},
"meter": {
"enum": [
"app",
"platform"
],
"type": "string",
"description": "Managed execution requires platform: Qumge settles one fixed-price unit only on complete delivery, with no usage report. For legacy routes without a managed connection or execution, app (default) requires provider usage reports; platform charges one unit per successful response."
},
"method": {
"type": "string"
},
"settle": {
"enum": [
"on_response",
"on_final",
"on_result"
],
"type": "string"
},
"pattern": {
"type": "string"
},
"billable": {
"type": "boolean"
},
"hold_usd": {
"type": "number"
},
"execution": {
"$ref": "#/$defs/execution",
"description": "Managed fixed result: sync/async invocation, internal status/recovery mapping and order (default) or buyer identity."
},
"rate_limit_per_min": {
"type": "integer",
"maximum": 3000,
"minimum": 60,
"description": "Micro lanes only: calls per minute per key (default 600)."
}
}
},
"description": "Manual HTTP operations. Managed routes include execution and input/output schemas; the referenced event supplies the fixed price. Legacy routes use hold_usd as a per-call ceiling."
},
"mcp_url": {
"type": "string",
"description": "Optional: publish an existing remote MCP server instead of an HTTP API. Must be https. The domain does not need to be verified to go live, but earnings stay frozen until verify_domain passes for it. Qumge calls tools/list to discover the tools, and every tool you price with `mcp_tools` becomes one operation. Managed execution charges only after a valid complete result, not queued acceptance. Legacy tools without a managed connection or execution use per-response pricing: successful non-error replies are charged; non-2xx, timeouts, isError: true and JSON-RPC errors are free."
},
"summary": {
"type": "string",
"description": "One line describing what it does."
},
"base_url": {
"type": "string",
"description": "Where the API lives. Must be https. For manual publication without manifest_url, connection_config, connection_id or mcp_url. Any path in it (https://host/v2) is part of what your server receives and is covered by the signature."
},
"keywords": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other names for the same thing, any language, up to 20. Agents search with a request like \"scrape trending TikTok videos\" — the keywords are what makes that find this app."
},
"metering": {
"enum": [
"reported",
"balance_delta"
],
"type": "string",
"description": "Legacy usage-based mode only: reported (provider reports usage) or balance_delta (Qumge reads its balance). Managed execution needs neither usage reporting nor a usage key."
},
"auth_mode": {
"enum": [
"signature",
"api_key"
],
"type": "string",
"description": "Manual service authentication; named connections declare it through connection_config.auth instead. signature (default) verifies signed requests; managed wrappers use trusted context, while legacy signed integrations also answer GET /qumge/ping. api_key sends upstream_token as the developer's Bearer key. Legacy api_key routes require exact paths and meter: platform; managed routes declare execution."
},
"mcp_tools": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"unit_price_usd"
],
"properties": {
"doc": {
"type": "object",
"description": "Optional input_schema/output_schema overriding tools/list for this result operation."
},
"name": {
"type": "string",
"description": "Tool name, exactly as tools/list returns it."
},
"execution": {
"$ref": "#/$defs/execution"
},
"unit_price_usd": {
"type": "number",
"description": "Price per complete result, in USD."
}
}
},
"description": "Prices for the MCP tools you want listed. Include execution and result schemas for managed complete-result delivery. Tools you leave out are not published and are reported back to you."
},
"qumge_key": {
"type": "string",
"description": "Optional: your Qumge API key, for clients that cannot set an Authorization header. Takes precedence over the header. Never echoed back."
},
"unit_name": {
"type": "string",
"description": "What users buy, e.g. credit."
},
"skill_slug": {
"type": "string",
"description": "Optional. Attach an existing skill from the catalog to this app (its documentation then shows on the app page). Ignored if the slug is unknown."
},
"support_url": {
"type": "string",
"description": "Where users ask for help. Shown on the app page."
},
"balance_path": {
"type": "string",
"description": "Only for balance_delta: where we read the balance."
},
"manifest_url": {
"type": "string",
"description": "Optional: publish from the project's qumge.json instead of passing everything by hand. Give https://<domain>/.well-known/qumge.json (or the service address). Its prices are suggestions: confirm them with the developer before submit_cap. The file supplies name, connection and operations; do not repeat name. Prefer manifest v2 for managed complete results. With several Caps in the file, pass `slug` to pick one (one call per Cap). Spec: https://qumge.com/docs/caps/manifest"
},
"social_links": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 6 public URLs for the developer (X, GitHub, LinkedIn, their website). Shown on every app page. The kind is guessed from the domain."
},
"connection_id": {
"type": "string",
"description": "Existing connection_id returned by publish_cap, belonging to this developer. Use instead of connection_config."
},
"upstream_token": {
"type": "string",
"description": "The developer's own service key. Required for a new api_key or authenticated MCP connection, and legacy balance_delta. With manifest_url, provide it when the selected connection needs api_key authentication and has no stored key. Reusable connections retain their credentials. Stored encrypted; sent as Authorization: Bearer."
},
"balance_json_path": {
"type": "string",
"description": "Only for balance_delta: where in that response."
},
"connection_config": {
"type": "object",
"required": [
"name",
"type",
"auth"
],
"properties": {
"auth": {
"enum": [
"signed",
"api_key"
]
},
"name": {
"type": "string"
},
"type": {
"enum": [
"api",
"mcp"
]
},
"mcp_url": {
"type": "string"
},
"base_url": {
"type": "string"
}
},
"description": "Reusable private service connection. Repeating the same developer/name reuses credentials when endpoint and authentication agree.",
"additionalProperties": false
},
"refund_policy_url": {
"type": "string",
"description": "Their refund policy, if they have one."
}
}
}