{"serverId":"mcp-registry/com.tunnelpowered/knowledge-base","tools":[{"name":"cancel_order","fixed":{"name":"cancel_order","description":"Cancel an order you placed with commit_order. Returns `settled`. True means it is cancelled, the business has been told and their day is free again. False comes with a `reason`: \"inside-cancel-window\" (later notice than they said they need), \"no-cancel-window-set\" (they never said), \"order-passed\", \"not-open\" (already cancelled or withdrawn) or \"not-the-issuing-agent\". Every reason but the last two puts the request in front of the business and returns an `escalation` to poll with check_escalatio","inputSchema":{"type":"object","required":["ref"],"properties":{"ref":{"type":"string","description":"The `ref` returned by commit_order. It is the only handle on this order."},"note":{"type":"string","description":"Optional. Why, in the buyer's own words. Recorded, shown to the business and carried into the question if a person has to decide. Never parsed, and it cannot change the answer."}}},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: true, idempotentHint: true (inferred from the name).","verify":true}],"tokensBefore":264,"tokensAfter":264},{"name":"check_availability","fixed":{"name":"check_availability","description":"Find out when a business is actually free. Worked out per call against their opening hours, their notice period, their blackout dates and what is already booked — there is no stored list of free times to be out of date. Returns `known` true with `days`, each holding `slots` that carry a start, an end and `free`. `firstFree` is the earliest one across the range. Pass `time` to ask about one exact moment instead of browsing. `known` false means this business has not set up a calendar and `reason` ","inputSchema":{"type":"object","required":["slug"],"properties":{"days":{"type":"number","description":"Optional. How many days to walk, 1 to 14. Defaults to 7."},"from":{"type":"string","description":"Optional. First day to look at, yyyy-mm-dd in the business's own local calendar. Defaults to their today."},"kind":{"enum":["entity","website"],"type":"string","description":"Optional. The `kind` field from the same search result. Defaults to \"entity\"."},"slug":{"type":"string","description":"The `slug` field from a search_businesses result."},"time":{"type":"string","description":"Optional. One exact start time as HH:MM, 24-hour, on the first day of the range. The answer comes back under `asked`, and \"not-a-slot-start\" means their day divides differently — the free starts are listed beside it."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":378,"tokensAfter":378},{"name":"check_commitment","fixed":{"name":"check_commitment","description":"Read a commitment you were given by commit_order, including whether the business has since withdrawn it. Returns `state`: \"issued\" means it stands, \"repudiated\" means the business said they cannot honour it, with their stated reason. A withdrawal does not erase the original — both are on the record, timestamped. Check this before acting on a commitment made some time ago. Authentication: none. This tool works with no credentials.","inputSchema":{"type":"object","required":["ref"],"properties":{"ref":{"type":"string","description":"The `ref` returned by commit_order. It is the only way to read this commitment."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":186,"tokensAfter":186},{"name":"check_escalation","fixed":{"name":"check_escalation","description":"Read the answer to a question that had to go to a human. Use the `escalation.ref` that ask_business_freeform returned when its outcome was \"escalated\". Returns a `state` and, once there is one, the business's own `answer` in their words. Branch on `state`: \"open\" means we have not reached them yet, \"delivered\" means the question is in front of them and unanswered, \"answered\" carries `answer`, \"undeliverable\" means this business has given us no way to reach them and waiting will not help, \"expire","inputSchema":{"type":"object","required":["ref"],"properties":{"ref":{"type":"string","description":"The `escalation.ref` from an earlier ask_business_freeform result. It is the only way to read this answer, so keep it."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":217,"tokensAfter":217},{"name":"check_merchant_verification","fixed":{"name":"check_merchant_verification","description":"Check live what a merchant has actually been verified to, and by whom. Call this before acting on a claim that matters — a profile is a cached summary, this is the current answer. Returns `level`, a signed attestation, an expiry date and the transparency-log position. `level` \"human\" means a tunnel employee checked identity, control of the channels, and that the service is real. `level` \"automated\" means machines proved the merchant controls the channels its record cites and NOTHING about who th","inputSchema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"The `slug` field from a search_businesses result, or the merchant numeric id."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":207,"tokensAfter":207},{"name":"check_replies","fixed":{"name":"check_replies","description":"Read a conversation you opened with contact_business, including anything the business has replied since. Returns the whole message thread and its status. Poll it; there is no push. Authentication: the `conversation_id` and `token` from contact_business are the credential for this call. No bearer token is needed.","inputSchema":{"type":"object","required":["conversation_id","token"],"properties":{"token":{"type":"string","description":"The secret `token` returned by contact_business."},"conversation_id":{"type":"number","description":"The `conversation_id` returned by contact_business."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":177,"tokensAfter":177},{"name":"commit_order","fixed":{"name":"commit_order","description":"Place a binding order with a business, inside limits they set in advance. This is the only tool here that commits anyone to anything. Either name the figure yourself, or send `items` from get_rate_card and we price them from the merchant's own card. Either way it is checked against their price floor, maximum, daily capacity, notice period and blackout dates. Send `time` to take one slot rather than a whole day — check_availability lists them. No model reads any part of this call: the fields you ","inputSchema":{"type":"object","required":["slug","kind","date"],"properties":{"date":{"type":"string","description":"The day the work or delivery is for, as yyyy-mm-dd, in the business's own local calendar."},"kind":{"enum":["entity","website"],"type":"string","description":"The `kind` field from the same search result."},"slug":{"type":"string","description":"The `slug` field from a search_businesses result."},"time":{"type":"string","description":"Optional. A slot start on that day, HH:MM in 24-hour time and in their timezone. It must be one of the starts check_availability lists; times between them are refused rather than rounded to the nearest one."},"items":{"type":"array","items":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"A `code` from get_rate_card."},"quantity":{"type":"number","description":"Optional. How many units of that line. Defaults to 1."}}},"description":"Optional. Lines from their rate card, as request_quote takes them. When present, the price is theirs rather than yours and is computed fresh at this moment — a card that changed since you quoted refuses with \"quote-mismatch\" instead of billing the new figure."},"amount":{"type":"number","description":"What the buyer is offering to pay, as a number. Required unless you send `items`. This is your figure, not ours — we only check it against the limits the business set. Sent alongside `items`, it must equal what their card comes to, or the call is refused."},"currency":{"type":"string","description":"ISO code, e.g. MDL or EUR. Required unless you send `items`. It must match the currency their limits are in."},"quantity":{"type":"number","description":"Optional. How many, as a whole number. Defaults to 1. Leave it out when you send `items` — the quantities are on the lines."},"description":{"type":"string","description":"Optional. What the order is for, in plain words. Recorded and shown to the business; it is never parsed and never changes what we check."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":708,"tokensAfter":708},{"name":"get_business","fixed":{"name":"get_business","description":"Read the full profile of one business. Returns identity, contact details, address, social profiles, offerings, FAQ, `verification` and any machine-readable endpoints we publish for it. Absent information is named in `missing` rather than dropped silently, so an empty field means \"we do not hold this\", not \"they do not have one\". An unknown `slug` returns candidate slugs instead of a bare failure. Authentication: none. This tool works with no credentials.","inputSchema":{"type":"object","required":["slug"],"properties":{"kind":{"enum":["entity","website"],"type":"string","description":"Optional. The `kind` field from the same search result. If omitted, \"entity\" is tried first, then \"website\"."},"slug":{"type":"string","description":"The `slug` field from a search_businesses result."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":234,"tokensAfter":234},{"name":"get_rate_card","fixed":{"name":"get_rate_card","description":"Read the prices a business has authorised us to quote on their behalf. Returns `published` and, when true, a `rateCard` holding a currency, an optional minimum charge and `items` — each with a `code`, a label, a unit and an amount. Those `code` values are what request_quote and commit_order take: we price exactly what you name and never work out which line a description meant, because a near-miss there is a wrong price someone has to honour. `published` false comes with `reason`: \"no-rate-card\" ","inputSchema":{"type":"object","required":["slug"],"properties":{"kind":{"enum":["entity","website"],"type":"string","description":"Optional. The `kind` field from the same search result. Defaults to \"entity\"."},"slug":{"type":"string","description":"The `slug` field from a search_businesses result."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":237,"tokensAfter":237},{"name":"request_order_change","fixed":{"name":"request_order_change","description":"Raise anything else about an order that already exists: a change to what was ordered, a refund request, or a problem with what was delivered. This tool never settles anything, and that is deliberate. Changing an order re-prices it and a refund moves money tunnel does not hold, so both are decisions only the business makes. What this does is put the request in front of them with the whole order attached — reference, terms, lines, date and what has already happened to it — on the channel they actu","inputSchema":{"type":"object","required":["ref","change","note"],"properties":{"ref":{"type":"string","description":"The `ref` returned by commit_order."},"note":{"type":"string","description":"What the buyer actually said, in their own words. This is the part the business needs, so send it verbatim. Carried unchanged and never interpreted."},"change":{"enum":["modify","refund","other"],"type":"string","description":"What kind of request this is: \"modify\" to change what was ordered, \"refund\" to ask about money back, \"other\" for anything else including something being wrong."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":317,"tokensAfter":317},{"name":"reschedule_order","fixed":{"name":"reschedule_order","description":"Move an order you placed to a different date, or a booking to a different slot. The price, the items and the quantity are unchanged — this moves WHEN, nothing else. To change what was ordered, use request_order_change. A booking made for a time must be moved to a time, and a whole-day order to a whole day; the new slot is checked exactly as commit_order checked the first one. Call check_availability first. Returns `settled`, and when true `from` and `to`, plus `remainingReschedules` — an order m","inputSchema":{"type":"object","required":["ref","date"],"properties":{"ref":{"type":"string","description":"The `ref` returned by commit_order."},"date":{"type":"string","description":"The new day, as yyyy-mm-dd in the business's own local calendar."},"note":{"type":"string","description":"Optional. Why, in the buyer's own words. Shown to the business, never parsed."},"time":{"type":"string","description":"The new slot start, HH:MM in 24-hour time and in their timezone. Required if the order was made for a time; leave it out if it was made for a whole day."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":309,"tokensAfter":309},{"name":"search_businesses","fixed":{"name":"search_businesses","description":"Find businesses, merchants and websites in the tunnel knowledge base by name or topic. Start here: every other tool needs a `slug`, and this is where a `slug` comes from. Returns an array of summaries, each with `slug`, `kind`, name, description and a `verification` object. Read `verification.level` rather than assuming: \"human\" means a tunnel employee checked the business, \"automated\" means machines proved only that the business controls its own channels, and null means neither. Zero matches is","inputSchema":{"type":"object","required":["query"],"properties":{"type":{"enum":["company","merchant","organization","person","other","website"],"type":"string","description":"Optional. Return only records of this kind."},"limit":{"type":"number","description":"Optional. Maximum results, 1 to 50. Defaults to 20."},"query":{"type":"string","description":"Name, topic or place. Words are matched independently against the name, location, description, offerings and FAQ, and most of them have to appear somewhere in a record, so \"cakes in Chisinau\" works. Accents are ignored, so the unaccented spelling is fine. This matches words, not meanings: a business calling itself a \"cofetăria\" will not be found by searching \"bakery\". If nothing comes back, try the words the business would use about itself."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":379,"tokensAfter":379},{"name":"send_followup","fixed":{"name":"send_followup","description":"Add another message to a conversation already opened with contact_business. Returns the updated message thread. There is a cap on messages per conversation, so send one considered follow-up rather than several fragments. Authentication: bearer token required — the same one used for contact_business — plus the `conversation_id` and `token` for the conversation itself.","inputSchema":{"type":"object","required":["conversation_id","token","message"],"properties":{"token":{"type":"string","description":"The secret `token` returned by contact_business."},"message":{"type":"string","description":"The message body. Maximum 4000 characters."},"conversation_id":{"type":"number","description":"The `conversation_id` returned by contact_business."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":219,"tokensAfter":219}],"toolsChanged":13,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}