Tools
Every tool of the Dashly MCP server, its arguments and what it does.
The server exposes twelve generic tools in three groups. Each one takes the resource as an argument, so the same tools cover every collection of the REST API.
| Group | Tools |
|---|---|
| Discovery | list_resources, describe_resource, list_fields, get_account |
| Records | list_records, get_record, create_record, update_record, delete_record |
| Actions | list_actions, run_action, read_action |
tools/list answers without a credential, so a client can show the tools before the user
connects. Every tools/call needs one (see Connect a client).
Calling a tool
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_record",
"arguments": { "resource": "clients", "id": "hsbftmp3f5" }
}
}{
"jsonrpc": "2.0",
"id": 7,
"result": {
"isError": false,
"content": [{ "type": "text", "text": "{\n \"data\": {\n \"id\": \"hsbftmp3f5\", ..." }],
"structuredContent": {
"data": { "id": "hsbftmp3f5", "name": "Acme Studio", "status": "active" }
}
}
}The result carries the API's response body twice: as structuredContent for clients that
parse it, and as a JSON text block for clients that do not.
Errors are tool results, not protocol errors. When the API refuses a call (validation,
missing scope, not found…), the result has isError: true and the API's
error envelope as its content, so the model can read the message and correct
itself. A missing required argument is reported the same way, naming the argument. Only an
unknown tool name or a malformed request is a JSON-RPC error.
Arguments declared as objects (data, input, filters) may also be sent as a string
holding a JSON object; some clients serialize nested objects that way. Anything that is not
a JSON object is refused with a message naming the argument.
Each tool declares behavior hints (readOnlyHint, destructiveHint, idempotentHint) so
your client can decide what to confirm with the user and what it may retry.
Discovery
list_resources
Lists every resource the API exposes and, for each, the HTTP methods it accepts, its
fields, filters, sorts, relations and required scopes. The map of the territory: call it
first, or read the dashly://catalog resource, which holds the same thing.
Arguments: none.
describe_resource
Describes one resource: readable fields, writable fields, accepted filters, available sorts, relations, required scopes, and the names of its actions. Call it before writing so you are not guessing field names.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name, as returned by list_resources (e.g. clients, deals, tickets). |
An unknown name returns an error listing the available resources.
list_fields
The field registry for an entity: the built-in fields plus the agency's own custom fields,
with their key, type and options. This is what tells you how to fill customFields.
| Argument | Type | Required | Description |
|---|---|---|---|
entity | account | deal | lead | ticket | no | Omit to get all four. |
get_account
Which agency the credential belongs to, its scopes, and how much of the monthly token
allowance is left. Read it when a call comes back 403 (usually a scope the key was not
given) or before a long run.
Arguments: none.
Records
list_records
Lists a resource's records, paginated, with optional search, filters and sort. An undeclared filter or sort comes back as an error naming the accepted ones.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
page | number | no | Page number, from 1. Defaults to 1. |
perPage | number | no | Defaults to 50, maximum 200. |
q | string | no | Full-text search over the resource's searchable fields. |
sort | string | no | A field the resource declares as sortable. A leading - also means descending. |
direction | asc | desc | no | Applies to sort. Defaults to the resource's own order. |
filters | object | no | Field → value pairs, e.g. { "status": "active" }. Values are strings. |
{ "resource": "tickets", "filters": { "clientId": "hsbftmp3f5" }, "sort": "createdAt", "direction": "desc" }get_record
Reads one record by its public id. An internal UUID is never a valid address, and a record
from another agency answers 404 rather than 403.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
id | string | yes | The record's public id. |
create_record
Creates a record.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
data | object | yes | The record's writable fields. |
- Links (
clientId,projectId,stageId,assigneeId…) take the target's public id. customFieldstakes the agency's custom fields by their key (seelist_fields). A field that does not exist yet is created through thefield-definitionsresource.- For an import,
data.createdAt(ISO 8601, in the past) records the record at the date it actually happened.list_resourcessays which resources accept it.
{ "resource": "tickets", "data": { "title": "Update the pricing page", "clientId": "hsbftmp3f5", "priority": "high" } }update_record
Updates a record. Only the fields present in data change, which is also how you move
something: a deal changes stage with { "stageId": "…" }, a ticket changes status with
{ "status": "…" }. Read dashly://conventions first to use a status or stage that exists
in this agency.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
id | string | yes | The record's public id. |
data | object | yes | Only the fields to change. |
customFields is replaced, not merged. Every other field in data is merged into the
record, but customFields replaces the whole object: any custom field you leave out is
cleared. Read the record, merge your change into its customFields, then write the full
object back. See Custom fields.
delete_record
Deletes a record. Irreversible; where a resource offers archiving, that is the reversible
answer. Not every resource allows deletion: describe_resource lists DELETE among its
methods only when it does.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
id | string | yes | The record's public id. |
Actions
Much of the product is not a field edit: converting a lead, merging two deals, duplicating a project, freezing a deck, inviting someone, importing a CSV. These are actions. An item action targets one record; a collection action targets the resource as a whole.
list_actions
Lists the actions (verbs) available beyond create, read, update and delete.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | no | Name a resource to get its actions with the JSON Schema of each body. Omit it to get every action of every resource at once, without schemas. |
Without a resource, each entry gives resource, action, target (item or
collection), readOnly, summary and description. Call it once with no argument to see
what the product can do, then with a resource for the exact body of the one you pick.
run_action
Runs an action returned by list_actions.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
action | string | yes | The action's name, as returned by list_actions. |
id | string | no | The record's public id, for an item action. Omit for a collection action. |
input | object | no | The action's body, matching the schema list_actions gave. |
The id is resolved inside your agency before the action runs, so an id from another agency
is a 404. An action can change a lot (archive, merge, convert), so clients should confirm
before calling it and must not retry it blindly. Actions that accept an idempotency key
document it in their schema; see Idempotency.
{ "resource": "leads", "action": "convert", "id": "k3n8q2w7xa", "input": { "dealName": "Acme redesign" } }read_action
Runs a read action, one that list_actions marks readOnly: computed figures that no
single record holds. Examples: the agency's dashboard overview (agency-settings,
overview), the calling member's day (members, my-day), a client's site statistics
(clients, site-statistics) or its AI visibility (clients, ai-visibility). It
changes nothing; the API refuses any action that is not a read.
| Argument | Type | Required | Description |
|---|---|---|---|
resource | string | yes | Resource name. |
action | string | yes | The read action's name, as returned by list_actions. |
id | string | no | The record's public id, for an item action. |
input | object | no | The action's parameters, matching the schema list_actions gave. |
{ "resource": "clients", "action": "site-statistics", "id": "hsbftmp3f5" }Timeouts
Each tool call makes one or more API calls; any single API call that takes longer than 20 seconds is abandoned and reported as a tool error.