Universal Tool Calling Protocol · 1.0.1
Cloud UTCP
The same tools as the cloud MCP, but with no intermediary server: the AI agent reads the UTCP manual and calls the cloud API itself using ready request templates — with your key, directly.
UTCP or MCP
| MCP | The client talks to the cloud MCP server (…/mcp), which calls the API for it. OAuth sign-in through the cabinet — for claude.ai, Claude Desktop/Code, Cursor. See Cloud MCP. |
|---|---|
| UTCP | The client reads the manual once (/utcp, no key), then sends plain HTTP requests to the cloud API with the X-Api-Key key. No intermediary: the same addresses, responses, errors and log as the API; works in your own Python and TypeScript agents. |
Connecting
You need an account API key hwk_…: the hw-connector.ru cabinet → Cloud → Keys. For AI prefer read-only — then tools with operations answer KEY_READ_ONLY. Put the key into the client variable HW_CLOUD_API_KEY (some clients prefix variable names with the manual name — see their docs).
Python
# pip install utcp utcp-http
import asyncio
from utcp.utcp_client import UtcpClient
async def main():
client = await UtcpClient.create(config={
"manual_call_templates": [{
"name": "hw_cloud",
"call_template_type": "http",
"url": "https://cloud.hw-connector.ru/utcp",
"http_method": "GET"
}],
"variables": {"HW_CLOUD_API_KEY": "hwk_…"}
})
tools = await client.search_tools("register alerts")
print(await client.call_tool("hw_cloud.get_summary", {}))
asyncio.run(main())TypeScript
npm install @utcp/core @utcp/http
# the manual is added the same way: name hw_cloud, call_template_type http, the url below, variable HW_CLOUD_API_KEYA client example is in the UTCP docs: utcp.io.
The manual itself
curl -s https://cloud.hw-connector.ru/utcp # the manual: no key needed
curl -s 'https://cloud.hw-connector.ru/utcp?lang=en' # in EnglishEach tool's template is call_template_type: http: an address with path parameters ({id}), a method, the body — the body_field input, other inputs — the query string; the key — auth of type api_key in the X-Api-Key header. Responses and error codes — as in the Cloud API.
Tools
The same as the cloud MCP (shared descriptions): tagged read-only, changes the cloud record and operation on the register.
Account summary. The fleet state in one request: how many registers in total, online, offline and disabled; agent versions; open alerts by code and how many are critical; agent requests in the last day and how many failed. Start here.
No inputs.
Account registers. Registers (workstations with HW agent): number, name from the agent and own name (label), agent version, online now, last seen, disabled or not, open alert count.
Inputs
onlinebooleantrue — only online, false — only offlineqstringPart of the name, own name or installation idlimitintegerHow many to return (1–1000, default 100)offsetintegerHow many to skip
Register card. Everything about a register: online or not, agent version, OS, latest metric values for 7 days (shift, fiscal drive, OFD, printers), open alerts and recent events.
Inputs
idintegerrequiredRegister number from list_deviceseventsintegerHow many recent events (1–500, default 20)
Devices on workstations. The last known state of devices on workstations: enabled or not, for a fiscal register — shift open or expired, whether it answers, days to fiscal drive end, not sent to the OFD; printers — state and reasons (out of paper). From agent data every minute (fiscal registers — every 10 minutes), at — when it arrived. What a device is doing right now — call_agent GET /api/v1/operations.
Inputs
deviceIdintegerOnly this register
Rename or disable a register. Own register name (the agent does not overwrite it; an empty string — back to the agent's name) and an on/off switch: the cloud passes no commands, agent requests or receipts to a disabled register. Changes only the cloud record, not the register.
The request body is the input patch.
Inputs
idintegerrequiredRegister numberpatchobjectRequest body (JSON)patch.labelstringOwn namepatch.disabledbooleantrue — disable, false — enable
Register alerts. Alerts: FN_EXPIRING (fiscal drive ends soon), OFD_BACKLOG (documents do not reach the OFD), SHIFT_EXPIRED (shift longer than 24 h), REGISTER_UNAVAILABLE (fiscal register not answering), DEVICE_OFFLINE (register gone). They open and close by themselves; by default — open ones only.
Inputs
openbooleantrue — open only (default), false — closed toodeviceIdintegerOnly this registercodestringOnly this codeseveritystringWARNING or CRITICAL
Register events. Account register events, newest first: operation.failed (failed operation with an error code), printer (printer state), power (power supply), register.unavailable (fiscal register not answering).
Inputs
deviceIdintegerOnly this registertypestringEvent typesincestringNot earlier than this time, ISO 8601limitintegerHow many to return (1–1000, default 50)offsetintegerHow many to skip
Metric across registers. The latest value of one metric on each register for 7 days: fn.days_left (days to fiscal drive end), ofd.not_sent (not sent to the OFD), ofd.oldest_hours, shift.open, shift.expired, register.ok, agent.up, devices.active.
Inputs
namestringrequiredMetric name, e.g. fn.days_leftdeviceIdintegerOnly this register
Agent request log. Requests to agent APIs through the cloud (call_agent, proxy, commands): register, method, path, response status, cloud error (NOT_CONNECTED, TIMEOUT…), time. Bodies are not stored.
Inputs
deviceIdintegerOnly this registerfailedbooleanFailed onlylimitintegerHow many to return (default 50)offsetintegerHow many to skip
Request to the agent API on a register. Run a request to the HW agent API on a register (as locally on http://localhost:7790): e.g. GET /api/v1/devices — devices, GET /api/v1/registers/1/shift — shift, POST /api/v1/registers/1/reports/x — X-report. Operations (POST) really run on the register: printing, receipts, payments — only at the user's explicit request and with idempotency_key (a retry with the same key never runs the operation twice). Device setup (/api/v1/setup) is not available. The agent API reference — https://hw-connector.ru/docs/api/en/agent/
The request body is the input command.
Inputs
idintegerrequiredRegister numbercommandobjectrequiredRequest body (JSON)command.methodstringrequiredHTTP methodvalues:GETPOSTPUTDELETEPATCHcommand.pathstringrequiredPath in the agent API with the query string, /api/v1/...command.bodyobjectJSON bodycommand.idempotencyKeystringOperation idempotency key
Print a receipt through the cloud. A receipt on an account register with a queue: if the register is offline the receipt waits and goes out when it shows up. receipt — as in the agent API (type, items, payments…). The same idempotency_key returns the same receipt and never prints it twice. A real fiscal receipt — only at the user's explicit request.
The request body is the input request.
Inputs
requestobjectrequiredRequest body (JSON)request.idempotencyKeystringrequiredIdempotency key, e.g. the order numberrequest.receiptobjectrequiredReceipt: type, items, payments…request.deviceIdintegerRegister; none — any onlinerequest.registerintegerFiscal register number on the workstation (default 1)request.callbackUrlstringWhere to send the result (webhook)
Receipt. A receipt sent through the cloud: status (QUEUED, SENDING, DONE, FAILED, UNKNOWN, EXPIRED), FD number, fiscal sign, receipt link, error.
Inputs
idintegerrequiredReceipt number
Recent receipts. Receipts through the cloud, newest first; idempotency_key — find a receipt by your key.
Inputs
deviceIdintegerOnly this registeridempotencyKeystringIdempotency keylimitintegerHow many (default 20)
Receipt accounting for a month. How many receipts and for what sum each register printed in a month, the plan and the trial limit.
Inputs
monthstringMonth YYYY-MM; none — the current one
Safety
call_agentandcreate_receiptrun real operations on the register: printing, a fiscal receipt, a payment. The AI agent should ask for confirmation before them; a read-only key is enough to watch the fleet.- The key stays with the client (a variable, a .env file) and goes only to the cloud API. To revoke — cabinet → Cloud → Keys. Every agent request is in the log
GET /api/v1/requests; the limit is 600 requests per minute per account. - The cloud does not pass device setup (
/api/v1/setup); nothing reaches a disabled register (update_device).