DoclightDocs
Tool reference

Write tools

Inputs, outputs, permissions, idempotency and quota behaviour for create_project, add_prompt and trigger_run.

Write tools are registered only when the configured key has write scope (and, for create_project, is authorised for a workspace). They are annotated readOnlyHint=false, destructiveHint=false and idempotentHint=true; their descriptions begin with MUTATION. None of them deletes or overwrites anything. Every create, replay and rejected duplicate is audited.

Only one tool spends money

create_project and add_prompt never start a measurement and never spend provider quota. trigger_run does, see below.

create_project

Creates a project (brand) in the key's workspace. Counts against the plan's project limit. Needs a write credential authorised for a workspace; a credential limited to specific brands is refused.

ArgumentTypeNotes
domainstring, 1–253 charsThe brand's website domain, e.g. acme.com. Required.
namestring, ≤255Display name.
target_languagesstring[]Language codes, e.g. ["en"]. Sent exactly as given; omitted means unspecified.
target_countriesstring[]ISO 3166-1 alpha-2, e.g. ["US"].
idempotency_keystringOptional; see below.
Call
{ "domain": "acme.com", "name": "Acme", "target_languages": ["en"], "target_countries": ["US"] }
Result
{
  "id": 12,
  "name": "Acme",
  "domain": "acme.com",
  "replayed": false,
  "idempotency_key": "mcp-create_project-3f2a..."
}

Repeating the same call returns the same project with replayed: true. A project that already exists for the domain is a "duplicate" error, and a reached plan limit is a "project limit" error.

add_prompt

Adds a tracked question to a project. Counts against the plan's prompt limit. Needs write scope and admin access to the project.

ArgumentTypeNotes
brand_idintegerFrom list_brands. Required.
contentstring, 1–2000 charsThe question to track. Required.
languagestring2–3 letter code. Omitted: the project's first target language.
target_countrystringISO 3166-1 alpha-2. Omitted: the project's first target country.
providersstring[]Provider ids to measure with. Omitted: all live providers.
title, categorystringOptional labels.
statuspaused (default) or activepaused never runs by itself; active joins scheduled runs.
idempotency_keystringOptional; see below.
Call
{ "brand_id": 12, "content": "Best CRM for startups?", "language": "en", "target_country": "US", "providers": ["openai"] }
Result
{
  "id": 101,
  "brand_id": 12,
  "content": "Best CRM for startups?",
  "language": "en",
  "target_country": "US",
  "status": "paused",
  "cadence": "daily",
  "providers": ["openai"],
  "replayed": false,
  "idempotency_key": "mcp-add_prompt-9c1e..."
}

A question is created paused, so nothing runs until you set it active (in the dashboard) or start a run with trigger_run. A question that is already tracked is a "duplicate" error; a reached prompt limit is a "prompt limit" error.

trigger_run

Starts a measurement run for explicit questions. This may consume quota and makes paid provider calls. Only call it when a run is wanted: no read tool ever starts one, and the tool description tells the model to run only when you asked.

ArgumentTypeNotes
brand_idintegerRequired.
question_idsinteger[], 1–25Existing, non-archived questions from list_questions. Required.
providersstring[]Narrows each question's own providers; never widens them. Omitted: each question's own providers.
idempotency_keystringOptional; see below.

Needs write scope, admin access to the project, and active paid access.

Call
{ "brand_id": 12, "question_ids": [101, 102], "providers": ["openai"] }
Result
{
  "status": "queued",
  "run_id": 57,
  "brand_id": 12,
  "run_status": "pending",
  "dispatch_state": "queued",
  "replayed": false,
  "idempotency_key": "mcp-trigger_run-de97...",
  "question_ids": [101, 102],
  "providers": ["openai"],
  "max_provider_calls": 2
}

Cost and quota

  • Each dispatch uses one of the plan's daily manual-run allowance and makes up to questions × providers paid provider calls. max_provider_calls reports that bound only when you narrowed providers; otherwise it is null because each question's own provider list applies.
  • The quota is checked and reserved before anything is queued. If it is used up, the result is status: "rejected" with reason: "report_quota_reached" and daily_run_limit when known.
  • If a run for the project is already in progress, the result is status: "rejected" with reason: "run_in_flight" and the in-flight run_id when reported. Nothing is reserved.
  • The tool does not wait. It returns queued with a run_id; poll get_run_status.
  • Execution is at-most-once per dispatch, not exactly-once: a provider call that timed out may still have been processed and billed.

Retrying safely

If you omit idempotency_key, one is derived from the brand, the questions, the providers and today's UTC date. A retry of the same call that day returns the existing run (replayed: true) without using more quota. To run the same questions again on the same day, pass a new idempotency_key. If the queue refused a run (dispatch_failed), retrying with the same key queues that same run again without using more quota.

Idempotency keys (all write tools)

SituationResult
Same key, same argumentsThe original object, replayed: true. Nothing new is created or charged.
Same key, different argumentsConflict: use a new key, or repeat the original arguments.
Concurrent duplicatesExactly one object is created.
Refused create (validation, limit, duplicate)Nothing is stored; the key can be reused.

Keys are scoped to the credential and the operation. When the server derives a key, it is returned as idempotency_key so you can reuse it.