Tools
An agent has thirty-one tools. Twenty only read. Eleven change data: their names begin with
create, update and delete.
metriox_filter_catalog, metriox_filter_values, metriox_get_bot_activity and
metriox_get_bot_profile exist and are available to the agent, but have no entries yet. All four
only read.
Normally the agent picks the tool itself and you do not need to know these names. The list is useful for understanding the limits and for phrasing requests more precisely.
The project comes from the token, not from a parameter. You cannot pass someone else's project into a call: there is no project id among the parameters at all.
metriox_list_bots
The project's bots.
No parameters. Returns each bot's id and name.
Almost all work starts here: the other tools need a botId, and only bots from this list are reachable
by the token.
metriox_get_project_overview
Event quota and usage for the current billing period: the limit, how many events and bytes have been used, what remains, and the period bounds.
No parameters.
Answers questions like "are we within the limit?" and "how many events are left before the period ends?".
metriox_search_events
Pages through one bot's raw events over a time range, newest first.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC, for example 2026-09-01T00:00:00Z |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
limit | no | Events per page, 1 to 100. Defaults to 50 |
cursor | no | Cursor from a previous call, for the next page |
At most 100 events come back per call. If there are more, the response carries a cursor and the agent requests the next page itself.
This is the tool for investigating specific cases, such as "show payment error events from yesterday".
For counting, use metriox_query_kpi: it aggregates server-side and does not spend the agent's context
walking events.
metriox_query_kpi
A single number for one bot over a time range.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
metric | no | What to count, see below |
Values for metric:
Events: every event in the rangeUsers: distinct users active in the rangeEventsPerUser: the ratio of the twoNewUsers: users whose first ever event falls in the range
metriox_query_series
A metric over time for one bot, bucketed by hour, day, week or month.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
metric | no | Events, Users, EventsPerUser or NewUsers. Defaults to Events |
granularity | no | Auto, Hour, Day, Week or Month. Defaults to Auto |
splitBy | no | Split into one line per dimension value: event_name, source, event_origin or event_type |
seriesLimit | no | How many lines to keep when splitBy is set, by size. Defaults to 10 |
This is the tool for "how did it change" questions and for comparing periods. Auto almost always
picks a sensible bucket on its own.
metriox_query_top
The largest values of a dimension over a range: which events fire most, which sources bring the most traffic, or the most common value of a custom property.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
metric | no | Events, Users, EventsPerUser or NewUsers. Defaults to Events |
groupBy | no | event_name, source, event_origin or event_type. Defaults to event_name |
detailKey | no | Group by a custom event property instead of a built-in dimension, for example $tg.callback_data. Takes precedence over groupBy |
limit | no | How many rows to return, 1 to 100. Defaults to 20 |
includeTotal | no | Also return the total across every value, not just the returned rows. Costs a second scan, so it is off by default |
metriox_query_funnel
Conversion through an ordered sequence of events: how many people reached each step and where they drop off.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
steps | yes | Event names in order, between 2 and 10. Discover the names with metriox_query_top grouped by event_name |
mode | no | UniqueUsers counts anyone who did each step at any point in the range; Ordered requires the steps to have happened in sequence. Defaults to UniqueUsers |
A step is an event name. More complex step conditions are not available over MCP yet.
metriox_query_retention
Retention: of the people who first appeared in each period, how many came back later.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range in which cohorts are formed, inclusive, ISO-8601 UTC |
toUtc | yes | End of the cohort range, exclusive, ISO-8601 UTC |
granularity | no | Cohort and bucket size: Day, Week or Month. Defaults to Day |
windowUnits | no | How many buckets to follow each cohort for, 1 to 90, in units of the granularity. Defaults to 30 |
Each cohort comes back with two series, and taking the wrong one produces a wrong curve with no sign anything went wrong:
returnedRateByBucketis per period: the share who came back in exactly that bucket.cumulativeReturnedRateByBucketis within N: the share who came back at least once by that bucket.
You cannot sum the first to get the second: each figure is its own distinct count, so anyone active in more than one period would be counted twice. Bucket 0 is the cohort's own period and is always the whole cohort.
Filters on the starting and returning events are not available over MCP yet: the tool measures retention across any event.
metriox_list_users
Pages through the people who used the bot in a range: how many events each has, and when they were first and last seen.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
search | no | Case-insensitive substring over the user id and their Telegram username, first name and last name. This is how you find one specific person |
sortBy | no | UserId, EventsCount, FirstSeen or LastSeen. Without it the default order applies, which is the cheapest for deep paging |
sortDirection | no | Asc or Desc when sortBy is set. Defaults to Desc |
limit | no | Users per page, 1 to 100. Defaults to 50 |
cursor | no | Cursor from a previous call |
metriox_get_conversation
The message history between the bot and one user, newest first: what the person sent, what the bot replied, which buttons were offered and which were pressed.
| Parameter | Required | Description |
|---|---|---|
botId | yes | A bot from metriox_list_bots |
platformUserId | yes | The person's numeric Telegram user id, not an @username. Take it from metriox_list_users or metriox_search_events |
fromUtc | yes | Start of the range, inclusive, ISO-8601 UTC |
toUtc | yes | End of the range, exclusive, ISO-8601 UTC |
limit | no | Items per page, 1 to 100. Defaults to 50 |
cursor | no | Cursor from a previous call, for older history |
This is the main tool for investigating a complaint: it shows what actually happened to one person.
metriox_get_dashboard
One dashboard's contents: its saved widget layout.
| Parameter | Required | Description |
|---|---|---|
dashboardId | yes | A dashboard from metriox_list_dashboards |
The shape of data is owned by the frontend rather than the server, and is not yet checked against a
schema server-side, so do not rely on it being stable.
metriox_list_campaigns
The project's broadcast campaigns, newest first, with their status and counts.
| Parameter | Required | Description |
|---|---|---|
botId | no | Only campaigns for this bot. Omit for every bot in the project |
status | no | Draft, Preparing, Prepared, Sending, Completed, Cancelling or Cancelled |
limit | no | Campaigns per page, 1 to 50. Defaults to 25 |
afterCreatedAtUtc | no | Cursor from a previous response, paired with afterId |
afterId | no | Cursor from a previous response, paired with afterCreatedAtUtc |
metriox_get_campaign
One campaign in full: status, bot, audience definition, message payload and counts.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
metriox_get_campaign_progress
How far a broadcast has got: how many recipients are pending, in flight, sent, failed or skipped.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
Returns the current numbers immediately. To follow a send, the agent calls it again rather than expecting one call to block until something changes.
metriox_list_campaign_recipients
The individual recipients of a campaign and what happened to each. This is the tool for "who did not get it, and why".
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
status | no | Only recipients in this status. Omit for all |
limit | no | Recipients per page, 1 to 200. Defaults to 50 |
afterChatId | no | Cursor: the chatId of the last row on the previous page. Only valid paired with afterIsTest |
afterIsTest | no | Cursor: the isTest flag of the last row. Defaults to false. Needed because a chat id is not unique within a campaign |
metriox_create_campaign
Create a broadcast as a draft. Nothing is sent: a draft has to be prepared and then started.
| Parameter | Required | Description |
|---|---|---|
botId | yes | Bot that will send the broadcast |
name | yes | Internal name, not shown to recipients |
text | yes | Message text |
lastDays | no | Only people active in the last N days. Mutually exclusive with allTime and with fromUtc/toUtc |
allTime | no | Everyone the bot has ever seen |
fromUtc / toUtc | no | Absolute audience bounds, only together |
parseMode | no | HTML or MarkdownV2. Omit for plain text |
buttons | no | Buttons, one per row: "label|url" for a link or "label|cb:value" for a callback |
disableWebPagePreview | no | Suppress the link preview |
disableNotification | no | Deliver silently |
The audience must be given in exactly one of the three ways. Media, text entities and multi-column keyboards are not available over MCP yet.
metriox_update_campaign
Edit a broadcast while it is still Draft. Once prepared, the payload is frozen and edits are refused.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
name | no | New internal name |
text | no | New text. Replaces the message whole, so pass buttons again to keep them |
parseMode, buttons, disableWebPagePreview, disableNotification | no | As on create |
This tool does not change the audience: who receives a broadcast is decided when it is created. Recreate the campaign to change it.
metriox_delete_campaign
Delete a campaign that is still Draft. A campaign that has been sent is a record and is never deleted.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
metriox_prepare_campaign
Freeze the draft's message and build its recipient list. Still sends nothing. Calling it again resumes rather than restarting.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
Refused if the filter matched nobody: a broadcast with zero recipients would complete instantly and look, on the progress panel, exactly like a perfect delivery.
metriox_unprepare_campaign
Withdraw a prepared campaign back to draft and discard its recipient list. Only from Prepared.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
Preparing it again rebuilds the audience, so the recipient set can differ.
metriox_test_send_campaign
Send the campaign's message to one chat, through the identical path a real broadcast uses.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
chatId | yes | Numeric chat id, not an @username |
Use a chat you control. The bot must already have a conversation with it, because Telegram does not let a bot initiate one. The campaign's status does not change.
metriox_start_campaign
Start the broadcast. The message goes to every prepared recipient. Requires admin rights.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign in Prepared |
etag | yes | The etag field from metriox_get_campaign, read immediately before starting |
The etag guards against sending on figures that have moved: if the campaign changed after the agent read
it, the start is refused. Ask a person to confirm before calling this.
metriox_cancel_campaign
Recall a broadcast: stop sending, and delete what has already gone out. Requires admin rights. Works on a completed campaign too, not only one still sending. Telegram lets a bot delete its own message for 48 hours only, counted per message — see Broadcasts.
| Parameter | Required | Description |
|---|---|---|
campaignId | yes | A campaign from metriox_list_campaigns |
metriox_list_dashboards
The project's dashboards visible to the token's user: names, ids and who created each one.
No parameters.
Returns the list only, not dashboard contents or widget layouts.
metriox_create_dashboard
Creates a dashboard from a list of cards.
| Parameter | Required | Description |
|---|---|---|
name | yes | Name, up to 120 characters |
cards | yes | Cards in order, 1 to 200. Each has a type, and optionally w, h, id |
availability | no | Everyone or DashboardCreator. Defaults to Everyone |
Card fields: type is the widget type (for example kpi, series); w is width in 12-column units,
1 to 12; h is height in row units, 1 to 60; id is your own identifier, generated when omitted.
Omitting w or h gives the card the maximum on that axis. Oversized values are clamped to the
maximum.
The set of widget types is defined by the web app rather than the server, so MCP cannot list them: call
metriox_get_dashboard on an existing dashboard to see which types are in use.
metriox_update_dashboard
Changes a name, visibility or cards. Only what you pass is changed.
| Parameter | Required | Description |
|---|---|---|
dashboardId | yes | A dashboard from metriox_list_dashboards |
name | no | New name |
cards | no | The complete new card list |
availability | no | New visibility |
cards replaces the whole list rather than adding to it. Read the dashboard with
metriox_get_dashboard first and send back the full set you want.
The server does not compare versions or return a conflict: if someone edits the same dashboard in the browser at the same time, whoever writes last wins and the other change is lost.
metriox_delete_dashboard
Deletes a dashboard. This cannot be undone.
| Parameter | Required | Description |
|---|---|---|
dashboardId | yes | A dashboard from metriox_list_dashboards |
What is not in the list
Over MCP these are not available yet:
- cohorts, histograms and heatmaps;
- user profiles and distributions over their properties;
- managing bots, project members or the plan.
Some of these will arrive in later versions. Managing bots, members and billing is unavailable by design: see the rights boundary.