Exposing a tool turns one tool of a registered MCP server into something agents can call through the Gateway. While you expose it, you decide three things that policies and delegations depend on: the name agents call it by, the K-Block action it counts as, and, for tools that move money, where the call's amount and currency are.
You need a registered server with discovered tools first; see Connect an MCP server. For the concepts, see Tools and MCP servers and Actions.
Who can do what
| Task | Owner, admin | Developer (and tools:write API keys) |
|---|---|---|
| Expose a tool | Yes, enabled at once | Yes, saved as a disabled draft |
| Enable a tool | Yes | No (403 ADMIN_REQUIRED) |
| Change the action, exposed name, amount mapping or description of an enabled tool | Yes | No; disable it first |
| Change a disabled draft | Yes | Yes |
| Disable a tool | Yes | Yes |
| Authorize or re-authorize a tool's binding | Yes (signed in, not with an API key) | No |
Approvers and viewers can see tools but not change them. The rule exists because the action, the exposed name and the amount mapping are inputs to every policy decision: like activating a policy, putting them into service needs an owner's or admin's consent.
Expose a discovered tool
Open the server and discover its tools
In Tools & MCP servers, open the server under MCP servers, then select Discover tools.
Choose the tool
Next to the tool, select Expose…. A form opens with two groups of fields, Policy inputs and Shown to agents, described below.
Fill in the policy inputs and the agent-facing fields
Enter the Action yourself; the placeholder is only a suggestion derived from the upstream tool's name. Add an amount mapping if the tool moves money.
Save
Owners and admins select Expose tool; the tool is enabled unless you untick Enabled (callable through the gateway). Developers select Save as disabled draft; an owner or admin enables it later.
The page confirms what happened, for example "Saved … as a disabled draft. Agents cannot call it until an owner or admin enables it." The tool's input schema is taken from the discovery.
The number of tools per organization depends on your plan (402 PLAN_LIMIT_EXCEEDED over the limit).
Fields
Policy inputs
| Field | Rules | What it does |
|---|---|---|
| Action | Dot-separated segments of a–z, 0–9, _, -, for example payments.refund. No wildcard; the kblock. namespace is reserved. | The permission that policies and delegations refer to. A policy rule's actions and a delegation's permissions must cover it. |
| Amount pointer (optional) | A JSON Pointer (RFC 6901) to one member of the call's arguments, for example /amount. | Where the Gateway reads the call's amount. |
| Currency | A three-letter ISO 4217 code, for example USD. Required with an amount pointer. | The currency of the amount. |
| Currency pointer (optional) | A JSON Pointer to the argument that names the currency, for example /currency. Needs an amount pointer and must not overlap it. | Makes the Gateway check the call's currency. See below. |
Shown to agents
| Field | Rules | What it does |
|---|---|---|
| Exposed name | 1 to 128 characters of A–Z a–z 0–9 _ . -, unique in the organization (409 NAME_TAKEN otherwise). | The tool name agents see in tools/list and call. |
| Description | At most 4,000 characters. Defaults to the upstream's description. | Shown to agents with the tool. Agents act on it, so keep it accurate. |
The upstream tool name is fixed when the tool is created. The tool's input schema is what agents receive in tools/list; it must be an MCP object schema of at most 64 KiB. The dashboard takes it from discovery when you expose the tool and never changes it afterwards: Discover again does not update it. The Cloud API accepts a new one in a tool update, which makes an enabled tool stale (see Re-pinning after a change). The Gateway does not check a call's arguments against this schema; the upstream server validates its own input.
Map the amount
Policies decide on amounts only when the tool tells the Gateway where the amount is. With an amount mapping, the Gateway reads the value at the amount pointer from each call and signs it into the call's terms; policy rules with amount conditions and delegations with a spending limit use it. See Rules, amounts and currencies.
The value at the pointer must be a non-negative decimal string (for example "250.00", up to 18 digits before and after the point) or a non-negative whole JSON number. Anything else, such as a negative number, a fraction written as a JSON number, or null, makes the call a recorded denial with INVALID_AMOUNT, and nothing runs. So does an argument object on the pointer's path that also has a member whose name differs only by case (for example both amount and Amount), because an upstream might read the other one.
If the pointer finds nothing in a call, the call has no amount. Then rules with an amount condition that deny or require approval still match (they fail closed), and allow rules with an amount condition do not.
Fixed currency or currency pointer
| Configuration | Behaviour |
|---|---|
| Amount pointer and Currency, no currency pointer | Every amount is taken to be in that currency (shown as "fixed"). Use this when the upstream always works in one currency. |
| Amount pointer, Currency and Currency pointer | Each call must name exactly that currency at the currency pointer. A call in another currency, or without one, is a recorded denial with INVALID_AMOUNT. Use this when the upstream executes in whatever currency the call names, so an amount is never priced in one currency and paid in another. |
Drafts and enabling
A disabled tool is a draft: agents do not see it and cannot call it. Tools that developers or tools:write API keys create always start as drafts. The tool table lists how many tools are disabled, so owners and admins can find drafts waiting for review.
To enable a draft, an owner or admin opens Tools & MCP servers, selects Edit on the tool, reviews the action, exposed name and amount mapping, ticks Enabled (callable through the gateway) and selects Save tool. The form explains: Enabling authorizes the upstream binding. If the tool's binding changed after the page loaded it, nothing is enabled and the save fails with 409 BINDING_CHANGED; review the tool again.
The dashboard does not let you enable a tool in the same save that changes its action or amount mapping (Save the changes first). Save the changes with the tool disabled, review, then enable.
When agents see a tool
An agent sees a tool in tools/list, and can call it, only when all of these hold:
- The tool is enabled.
- Its MCP server is active (not disabled).
- Its binding is authorized (see The tool binding).
- The server's URL can be signed (no query, fragment or credentials).
- A valid delegation of this agent, signed by the organization's current principal, grants
kblock.taskand the tool's action.
The policy then decides each call. Agents call a tool by its exposed name; a call to a name that is not an enabled tool on an active server gets invalid_request / UNKNOWN_TOOL, and nothing is recorded.
The tool binding
A tool's binding is everything that decides where its calls go and how policies see them:
- the MCP server, and the server's URL, server KID and credential version;
- the upstream tool name;
- the action;
- the amount pointer, currency and currency pointer;
- the input schema (its digest).
The exposed name, the description, the tool's enabled state and the server's status are not part of the binding.
When an owner or admin enables a tool (or exposes it enabled), K-Block pins the binding as it is at that moment. The tool table shows the state:
| Badge | Meaning |
|---|---|
| enabled | Enabled, and the binding is the authorized one. Agents can call it. |
| disabled | A draft or a disabled tool. |
| re-authorization required | A bound field changed after the tool was authorized. |
| not authorized | No owner or admin has authorized this binding. |
| server disabled | The tool's MCP server is disabled. |
Re-pinning after a change
Any change of a bound field, by anyone, owners and admins included, makes an enabled tool stale. That includes changing the action or amount mapping, a new input schema, and changing the server's URL, server KID or credential. A stale tool:
- disappears from agents'
tools/list; - is refused at call time with
TOOL_REAUTHORIZATION_REQUIRED, without anything being recorded or run; - stays stale even if you change the field back.
To put it back into service, an owner or admin selects Review & re-authorize on the tool, checks the upstream (server URL, server KID, authorization header, upstream tool), the policy inputs (action, amount, input schema) and the binding digests, and selects Re-authorize this binding. If the binding changed again in the meantime, nothing is authorized (BINDING_CHANGED). Disabling the tool and enabling it again also pins the binding as it is then.
Changing the exposed name of an enabled tool needs an owner or admin but does not make it stale. Agents must then use the new name; calls to the old name get UNKNOWN_TOOL. A call the policy allowed under the old name is decided again on its next identical call.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
The agent's tools/list does not show the tool | The tool is disabled, stale or not authorized; the server is disabled; or no delegation grants its action | Check the tool's badge; check the agent's delegations on its page (Set up an agent). |
UNKNOWN_TOOL | The agent used a name that is not an enabled tool on an active server (renamed, disabled, or a typo) | Use the exposed name exactly as tools/list shows it. |
TOOL_REAUTHORIZATION_REQUIRED | A bound field of the tool or its server changed | An owner or admin re-authorizes the tool. |
UPSTREAM_CHANGED | The tool was re-authorized after the call was decided | The agent calls again for a new decision. |
INVALID_AMOUNT | The value at the amount pointer is not a valid amount, or the currency at the currency pointer is missing or different | Fix the agent's arguments, or the tool's mapping. |
INVALID_TOOL_CONFIGURATION | The tool's stored configuration is invalid, for example a server URL stored with a query before that was refused | Fix the server URL or the tool's mapping. |
403 ADMIN_REQUIRED when saving | A developer tried to enable a tool or change a policy input of an enabled tool | Disable the tool first, or ask an owner or admin. |
409 BINDING_CHANGED | Someone changed the tool or its server after you loaded the page | Reload, review the tool as it is now, and try again. |
409 NAME_TAKEN | Another tool already uses this exposed name | Choose another name. |
More in Gateway and tools troubleshooting.