Simba MCP Server
OfficialThis server is an MCP interface to the Simba Bayesian Marketing Mix Modeling platform, letting AI assistants upload data, build MMM/VAR models, inspect results, and run budget optimizations and scenarios through natural-language tools.
Data management: get the canonical CSV schema, upload CSV data (by content or local path), list and inspect uploads and their column schemas.
Model lifecycle: create and fit MMM models with channels, controls, priors, saturation, link, seasonality, and sampler settings; create long-term VAR models; poll fitting status; rename, save/unsave, and delete failed models.
Model discovery and organization: list models and projects, create and rename projects, fetch full model configuration echoes.
Results and diagnostics: retrieve channel summaries, contributions, coefficients, response/marginal curves, saturation, mROI summaries, model stats, actual-vs-model, posterior summaries, financials, cohort ledger, and more, with section/channel/grid-point filtering.
VAR linking: link/unlink VAR models to MMMs and include long-run rollup effects, with optional channel maps for group-level VARs.
Contribution grouping: persist and read dashboard contribution-view driver groupings.
Budget optimization: run async budget optimizers with bounds, laydown weights, period CPMs, profit/revenue objectives, group bounds, and retrieve specific or latest run results.
Scenario planning: generate forward-period templates, run what-if scenario predictions, and fetch scenario results with optional holdout evaluation and proxy channels.
Run history and curation: list saved optimizer/scenario runs, rename/annotate runs, and pin/unpin them.
Advanced study workflows: validate recipes, manage quality policies, evaluate study runs, assess validation pairs, and read champion/resolution/access metadata where the backend supports them.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Simba MCP ServerShow me the channel contributions and ROI for my latest model"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Simba MCP Server
Simba is a Bayesian Marketing Mix Modeling (MMM) platform. This Marketing Mix Modeling MCP server lets AI assistants interact with your models directly — upload data, build models, check results, and run budget optimizations through natural language in Claude, Cursor, or Claude Code.
Installation
pip install simba-mcpOr run directly without installing:
uvx simba-mcpRelated MCP server: Ads MCP
Quick Start
Cursor IDE
Add to your Cursor MCP settings (.cursor/mcp.json in the workspace or global settings):
{
"mcpServers": {
"simba": {
"command": "uvx",
"args": ["simba-mcp"],
"env": {
"SIMBA_API_URL": "https://demo.simba-mmm.com",
"SIMBA_API_KEY": "simba_sk_..."
}
}
}
}Claude Code
Add to your Claude Code MCP config:
{
"mcpServers": {
"simba": {
"command": "uvx",
"args": ["simba-mcp"],
"env": {
"SIMBA_API_URL": "https://demo.simba-mmm.com",
"SIMBA_API_KEY": "simba_sk_..."
}
}
}
}Claude API (MCP Connector)
Use the remote Streamable HTTP transport with the Anthropic MCP connector:
import anthropic
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "List my Simba models"}],
mcp_servers=[
{
"type": "url",
"url": "https://demo.simba-mmm.com/mcp",
"name": "simba",
"authorization_token": "simba_sk_...",
}
],
tools=[{"type": "mcp_toolset", "mcp_server_name": "simba"}],
betas=["mcp-client-2025-11-20"],
)Available Tools
Tool | Description |
| Get the canonical CSV schema for MMM input files |
| Inspect authoring drafts and complete versioned snapshots on supporting backends |
| Save complete draft state with retry identity and optimistic concurrency; no publication or fit |
| Upload a CSV dataset to Simba |
| List previously uploaded datasets |
| One upload's details, including its column schema |
| List all models with their status |
| Configure and start fitting a new MMM model |
| Model metadata + config echo — works for any status, incl. failed |
| Permanently delete a FAILED model (409 for any other status) |
| Rename a model without saving it |
| File a model into a project (makes it visible to default |
| Release a saved model's slot (non-destructive inverse of |
| List the projects (model folders) you can file models into |
| Create a named project, optionally team-shared |
| Rename a project you own |
| Poll fitting progress and optional heartbeat/stall-threshold metadata |
| Get results (ROI, contributions, response curves, diagnostics, and more) |
| Fit a long-term (VAR) model |
| Attach/detach a VAR model to an MMM for the |
| Persist/read the contributions-view driver groupings |
| Run budget optimization on a completed model |
| Get optimizer status and results (latest, or a specific |
| Generate a forward-period template for scenario planning |
| Run a "what-if" scenario prediction |
| Get scenario results (latest, or a specific |
| List a model's saved optimizer/scenario run history |
| Rename/annotate a saved run (notes, tags) |
| Pin/unpin a saved run |
Example Prompts
Try these with any connected AI assistant:
Explore your models:
"List my Simba models and show me the channel ROI summary for the most recent complete model."
Build a model:
"Upload this CSV data to Simba and create a new MMM model with TV, Search, and Social as media channels. Use 'revenue' as the KPI and 'date' as the date column."
Check progress:
"What's the fitting status of model a1b2c3d4?"
Get results:
"Show me the model diagnostics and channel contributions for model a1b2c3d4."
Optimize budget:
"Run a budget optimization on model a1b2c3d4 with $1M total budget over 12 months. Set TV bounds to 5-40% and Search to 10-50%. Use uniform laydown weights."
Response curves:
"Show me the response curves for model a1b2c3d4. At what spend level does TV hit diminishing returns?"
Scenario planning:
"Get a scenario template for model a1b2c3d4 for the next 12 weeks. Then run a scenario where I increase TV by 20% and cut Search by 10%. What happens to revenue?"
Full workflow:
"I have marketing data I want to analyze. First get the schema so I know what format is needed, then upload my data, create a model, and once it's done show me the ROI by channel."
Agent Skills
The skills/ directory ships workflow skills in the
Agent Skills format (SKILL.md per skill) —
install them into any skills-aware agent (e.g. Claude Code) alongside this
MCP server:
Skill | Covers |
Upload → create → poll → reading results correctly (section semantics, channel naming, attribution/Overlap rules, context-size controls) | |
Optimizer payload conventions, revenue vs profit, polling by run_id, decision- vs comparison-column semantics, run curation | |
Prior-override payloads: smart-default merging, strict rejection, the half-saturation / half-marginal / half-life anchor families | |
Long-term (VAR) modeling: create → poll → link → long_run_rollup |
The skills are documentation artifacts — they ride the repo, not the wire protocol.
Gotchas & Tips
Things that commonly trip up both AI agents and humans:
Hosted server: your bearer token IS your login
On HTTP deployments each request is authenticated with the caller's own
Authorization: Bearer simba_sk_... token — there is no server-side shared
key. If tool calls return "No API key on this request", your MCP client
isn't sending the token (check the authorization_token / headers setting
in its config).
Channel names are exact-match
Model results are keyed by the channel's activity column name (e.g. "search_activity", "TV_impressions"), not by the channels[].name you passed to create_model. Keys can contain spaces and matching is case-sensitive and space-sensitive — the optimizer and scenario tools use them as dictionary keys.
Always call get_model_results with sections="channel_summary" first to see exact channel keys, then use those verbatim in optimizer/scenario payloads.
Results sections
get_model_results serves these sections (request only what you need via sections=):
channel_summary, contributions (KPI/unit space — multiplier not applied), coefficients (per-period per-channel revenue table), params, decay_curves, response_curves, marginal_curves, saturation, mroi_summary (marginal ROI at current spend with 94% HDI; post-#591 fits add the allperiods_unweighted / spendweighted_active convention scalars, and post-#629 fits add a *_mean beside every *_median — the median is displayed, the mean is what reconciles with the marginal-revenue curve), mroi_periods (opt-in only — the per-period marginal ROI series; never in the default payload, request it by name), model_stats, actual_vs_model, long_run_rollup, optimizer, predictions, posterior, financials, model_config. The response's sections_available field is authoritative if the server is newer than these docs.
Models are identified by model_hash
All model endpoints use the string model_hash (e.g. "f835671a25") returned by create_model and list_models.
API-key management is deliberately not exposed
The /api/v1/keys endpoints (create/list/revoke API keys) are session-auth only and have no MCP tools by design: a server holding one key must not be able to mint or revoke keys. Manage keys in the Simba UI (Profile → API Keys).
Optimizer arrays, not scalars
laydown_weights and period_cpm must be objects of arrays, each array having exactly num_periods elements:
// Wrong
"period_cpm": {"TV": 10}
// Correct
"period_cpm": {"TV": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]}The same channel keys must appear in bounds, laydown_weights, and period_cpm. Bounds values are percentages (0-100) of total_budget, not currency amounts.
Clean NaN from scenario templates
The template from get_scenario_template may contain NaN/null for channels without historical data. Replace them with 0 before passing to run_scenario:
import math
for row in scenario_data:
for key, val in row.items():
if val is None or (isinstance(val, float) and math.isnan(val)):
row[key] = 0Three endpoints are async
These return 202 and require polling:
Action | Start | Poll |
Fit model |
|
|
Optimize |
|
|
Scenario |
|
|
Poll every 5-10 seconds. Check the status field for "complete" or "failed".
Data upload requirements
CSV only (not Excel). Maximum 10 MB (API-enforced).
Row minimum: check
get_data_schema→x-simba-constraints.min_rows; the upload response'swarningsfield is authoritative. More rows = tighter posteriors (104+ weekly rows recommended).Media columns:
{channel}_activityand{channel}_spendper channel.Use
0for inactive periods, not blank or NA.Large file? Pass
csv_path(a local file path) instead ofcsv_content— the server reads it directly instead of the CSV going through the conversation. Local (stdio) servers only; disabled on HTTP/SSE deployments unlessSIMBA_MCP_ALLOW_LOCAL_FILES=1.
Common Errors
Error | Cause | Fix |
| No API key or expired key | Check |
| Key doesn't have the needed scope | Create a key with all scopes |
| Payload missing required keys | Check the tool's parameter list |
| Model still fitting or failed | Poll |
| Scalar instead of array, or wrong length | Use arrays matching |
| Zero or negative CPM | All CPM values must be > 0 |
| Mismatched channel names | Same keys in bounds, laydown_weights, and period_cpm |
| Column name typo | Check CSV headers match exactly |
| CSV too large | Reduce file size or aggregate data |
Direct API Access
The MCP server wraps the Simba REST API. For scripting, CI/CD, or environments without MCP, you can call the API directly.
When to use MCP vs direct API
MCP (via AI assistant) | Direct API (curl / Python) | |
Best for | Exploratory analysis, conversational workflows | Automated pipelines, scheduled jobs, scripts |
Async polling | Assistant handles it automatically | You implement poll-until-complete logic |
Data cleaning | Assistant cleans NaN/null, builds payloads | You write the data prep code |
Reproducibility | Conversational | Scriptable, version-controlled |
Both use the same API keys with the same scopes.
Quick start (Python)
import requests, time
BASE = "https://demo.simba-mmm.com"
HEADERS = {"Authorization": "Bearer simba_sk_..."}
# Upload data
with open("marketing_data.csv", "rb") as f:
r = requests.post(f"{BASE}/api/v1/ingest",
headers={**HEADERS, "Content-Type": "text/csv"},
data=f.read(), params={"name": "q1_data"})
file_id = r.json()["id"]
# Create model
r = requests.post(f"{BASE}/api/v1/models", headers=HEADERS, json={
"data_source": {"uploaded_file_id": file_id},
"date_column": "date",
"kpi_column": "revenue",
"hierarchy_column": "brand",
"channels": [
{"name": "TV", "activity_column": "tv_grps", "spend_column": "tv_spend"},
{"name": "Search", "activity_column": "search_impressions", "spend_column": "search_spend"},
],
"total_media_effect": "Retail",
})
model_hash = r.json()["model_hash"]
# Poll until complete
while True:
status = requests.get(f"{BASE}/api/v1/models/{model_hash}/status",
headers=HEADERS).json()
if status["status"] in ("complete", "failed"):
break
print(f"Fitting... {status.get('progress', '?')}%")
time.sleep(10)
# Get results
results = requests.get(f"{BASE}/api/v1/models/{model_hash}/results",
headers=HEADERS,
params={"sections": "channel_summary,model_stats"}).json()
for ch in results["results"]["channel_summary"]:
print(f"{ch['Channel']}: ROI {ch['ROI']:.1f}")Quick start (curl)
API_KEY="simba_sk_..."
BASE="https://demo.simba-mmm.com"
# Upload data
curl -X POST "$BASE/api/v1/ingest?name=q1_data" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: text/csv" \
--data-binary @marketing_data.csv
# Create model (replace uploaded_file_id with id from upload)
curl -X POST "$BASE/api/v1/models" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"data_source": {"uploaded_file_id": 1}, "date_column": "date", "kpi_column": "revenue", "hierarchy_column": "brand", "channels": [{"name": "TV", "activity_column": "tv_grps", "spend_column": "tv_spend"}]}'
# Poll status (replace MODEL_HASH)
curl "$BASE/api/v1/models/MODEL_HASH/status" -H "Authorization: Bearer $API_KEY"
# Get results
curl "$BASE/api/v1/models/MODEL_HASH/results?sections=channel_summary,model_stats" \
-H "Authorization: Bearer $API_KEY"API Key Setup
The MCP server authenticates with the same API keys used by the Simba REST API. Create a key with the required scopes:
Go to Profile > API Keys in the Simba UI
Click Create Key
Set scopes:
ingest,read:models,read:results,create:models,optimize,scenarioCopy the key (shown only once)
How the key is supplied depends on where the server runs:
Local (stdio — Cursor, Claude Code): set it as the
SIMBA_API_KEYenvironment variable in your MCP config (the examples above).Hosted (
https://demo.simba-mmm.com/mcp): send it as the HTTPAuthorization: Bearerheader — theauthorization_tokenfield in the Claude MCP connector config. Every caller uses their own key (v0.2.2+): the server never shares an identity between callers, a request without a key gets a structured 401 with guidance, and you only ever see your own account's models.
Configuration
Environment Variable | Description | Default |
| Simba API base URL |
|
| Your Simba API key (stdio mode only — HTTP callers send their own key as the bearer token) | (required for stdio) |
Transport Modes
The server supports all MCP transport modes:
# stdio (default) — for Cursor, Claude Code
simba-mcp
# Streamable HTTP — for remote deployment
simba-mcp --transport streamable-http --port 8100
# SSE — legacy transport
simba-mcp --transport sse --port 8100
# Or via uvicorn directly
uvicorn simba_mcp.server:app --host 0.0.0.0 --port 8100License
MIT
Fit heartbeat visibility
On backends that support it, get_model_status also returns fit_liveness.
The MCP server passes the response through unchanged; older backends may omit
this field. With available: true, heartbeat_age_seconds,
stall_timeout_seconds, and seconds_until_stall_threshold are in seconds;
last_heartbeat_at is a Unix timestamp in seconds. stall_threshold_exceeded
reports whether heartbeat age is strictly greater than the configured threshold.
The countdown is to a stale-heartbeat threshold, not completion ETA or an exact
termination time: the watchdog runs periodically. It does not change status.
With available: false, reason is heartbeat_unavailable (including unavailable
heartbeat storage) or not_fitting. Missing or unavailable metadata is unknown,
not evidence that a fit is healthy or stalled. Continue polling with backoff and
use the reported model status; do not automatically restart or duplicate a fit.
Explicit control priors and transforms
Use control_columns to include controls and optional control_priors to
configure them. Overrides select an exact column via control; media priors
continue to select a channel via channel.
{"control_columns": ["price", "discount_depth"], "control_priors": [
{"control": "price", "transform": "LOG", "distribution": "normal", "mean": -1, "sd": 0.5},
{"control": "discount_depth", "transform": "N", "distribution": "normal", "mean": 1, "sd": 0.5}
]}These are illustrative coefficients, not fitted estimates or recommended priors. Native transforms: N = x; DM = x/mean(x); STA = x/sample_sd(x) without centering; DDM = x/mean(KPI); LOG = log(x/mean(x)), requiring positive x. Under a log link, a LOG coefficient is an elasticity; N is a semi-elasticity. Changing a transform does not convert prior units: explicitly choose suitable coefficient priors. Normal and inversegamma use mean/sd (positive mean for inversegamma); truncatednormal also requires ordered lower/upper bounds; halfnormal uses only sd. Unused fields, unknown keys, null field values and nonselected/duplicate controls are rejected. Omitted fields preserve applicable smart defaults; changing family clears inapplicable bounds/mean.
Nonempty overrides preflight get_data_schema for
x-simba-model-capabilities.control_priors version 1 and all five transforms.
Unsupported, malformed or unavailable capability checks stop before creation;
never retry by removing requested settings. Omitted/None/empty overrides keep
legacy calls unchanged. Backend support must be deployed before using this
option. Direct REST clients must perform the same capability check and put
control_priors at the request root. Check get_model's resolved priors and
overridden_fields after creation. Prediction uses existing fit-time constants;
this feature does not change preprocessing split order or fit a model for you.
Study workflows
The study tools require a Simba backend with the workflow API deployed. Studies belong to projects and provide a shared record for analysts and agents:
Create/read/update studies with declared questions, attempt limits and concurrency limits.
Validate, save and inspect immutable recipe revisions; list recipes captured by the wizard.
Launch a revision with a declared quality policy and caller-generated submission key.
Inspect progress, request cancellation, evaluate saved evidence and compare candidates.
Preview/import existing models and record recommendations with a rationale.
Reuse the same submission key when retrying an uncertain launch; changing the recipe or policy requires a new key. Workflow writes are sent once, without automatic HTTP retries. A study does not autonomously launch its budget of fits. Its runs use the existing models, workers and progress records.
Project sharing permits reading studies; mutations require ownership. The MCP can recommend but cannot record analyst acceptance. Imported historical recipes are review-only where original provenance is incomplete. Wizard-captured recipes can be inspected and launched; changing a captured wizard configuration requires another wizard capture or a separately validated API recipe.
Quality reports distinguish failed checks, missing evidence and required analyst review. Current saved-window error metrics and R-hat are not held-out validation or proof of business validity. No tool automatically promotes a winning model.
Discovery and reliable Studies workflows
Start with get_backend_capabilities to read the connected backend's model,
transform/prior and workflow advertisements. Missing fields mean unknown;
installing this package does not upgrade the backend. All tool annotations are
informational hints, never permission checks.
For Studies: inspect the project/study budget, validate a recipe, freeze a revision,
declare a quality policy, then launch with an explicit submission key. Preserve
that key and the exact inputs after an uncertain response. Poll the shared run;
requested cancellation is not confirmed completion. Reload and reconcile on 412;
revalidate on an input-hash conflict. Optional expected_content_hash on recipe
create/revise binds the validated effective inputs. Evaluate existing evidence and
recommend with limitations; analyst acceptance remains in the frontend. Missing
evidence never passes, and fitted-window metrics are not holdout validation.
Writes are sent once, without automatic retries. Reconcile uncertain mutations
before repeating them. Reads retain bounded transient retries. Existing error
objects retain error / _status_code, with additive _error_code and
_next_action guidance. Backend additive fields remain intact in structured output.
For bounded results, request sections="channel_summary,model_stats" first and use
channels / max_grid_points where appropriate. Optional max_response_bytes
returns an actionable 413 instead of partial evidence when the filtered JSON
payload is too large. It bounds payload serialization, not backend download or MCP
envelope overhead. Existing defaults remain unchanged.
See architecture and compatibility for ownership, transport/authentication boundaries, known limits and validation.
Draft authoring discovery: get_recipe_draft_template(family="mmm" | "var") returns complete defaults generated by the shared wizard, a template hash and the draft envelope schema. Start new drafts from this snapshot and preserve unedited fields. Defaults are not validated models; check publication capabilities before publishing. Requires the corresponding backend capability and read:models.
Pass either uploaded_file_id or pipeline_version_id to get_recipe_draft_template to copy an owned uploaded dataset or saved pipeline output version into the new authoring snapshot and populate its bounded preview. Optional source origin is verified by the backend against exact bytes; detail responses include a source manifest. Reopening uses frozen data even if the original upload disappears. This does not enable publication or model fitting.
Draft publication: publish_recipe_draft freezes a saved MMM or VAR draft as an atomic batch, using expected version and caller UUID recovery; it never launches a fit. get_recipe_revision_authoring retrieves the immutable authoring snapshot for copying to a new draft. Check backend publication capabilities. When publication_constraints.automatic_prior_resolution is freeze_at_publication, automatic MMM priors are resolved once and replayed without rebuilding. Original authoring choices remain recoverable for editing a new draft. This applies to draft publication; legacy api_mmm recipe resolution still requires fixed priors. VAR preserves its raw input and engine manifest; MMM quality policies cannot establish VAR acceptance.
Calibration: check the backend calibration capability. MMM draft publication validates active likelihood observations and returns their count, units, channels and hash in recipe provenance. Enabled invalid or unapplied observations fail explicitly; VAR calibration is unsupported. Preserve disabled authoring rows when editing. Imported wizard JSON is retained as editable rows; multipart wizard CSV capture retains its original bytes. No new MCP route is needed.
Pipeline sources retain the exact version ID, pipeline ID, version number and verified content hash. No pipeline is executed. Existing exported uploads are not assigned inferred pipeline lineage.
Draft source.history preserves up to 100 recorded column transformations/removals with parameters and before/after data hashes. The backend checks chain continuity and the terminal data hash. These are client-reported authoring records, not independently replayed operations or quality evidence. Edited data must omit an unchanged source origin. Unknown nested fields remain preserved.
Optional calibration_import retains an original JSON file (1 MB maximum) in the authorized authoring snapshot. Preserve it independently of current editable observations. The backend verifies its bytes/hash; published provenance includes filename/hash and explicitly states current observations may differ. Ordinary recipe responses omit the raw attachment. This reference is not scientific validation.
Custom numeric quality checks: create_quality_policy accepts checks such as
{"metric":"custom:benchmark_deviation","name":"Benchmark deviation","units":"%","operator":"lte","maximum":10,"required":true}.
Use gte with minimum, or between with both inclusive bounds. Read backend capability discovery before using this additive contract.
For externally calculated metrics, call evaluate_study_run(run_id, policy_id) first and retain report.basis_hash. Calculate from that run's saved outputs, then call the same tool with expected_basis_hash and external_evidence=[{"metric":"custom:benchmark_deviation","value":8,"method":"Absolute deviation as percentage of benchmark","source_reference":"Versioned model export and benchmark"}]. An optional source_sha256 records a reported source digest. The backend determines pass/fail and rejects stale output bases. Every submission creates a new assessment and must supply all intended custom values; omitted values remain unevaluated. Source references and calculations are submitter-reported, not independently verified. This numeric MMM contract does not execute agent code, accept a model, support VAR acceptance, or designate a champion.
Boolean checks use kind: "boolean", operator: "equals" and strict boolean expected. Submit a JSON boolean in external_evidence.value; numeric or string substitutes are rejected. Manual checks use kind: "manual", operator: "equals", expected: true. MCP can define these rules and read evidence, but API keys cannot submit manual sign-off: a signed-in reviewer must supply confirmation, rationale and source through the frontend. Missing answers stay unevaluated; sign-off is not automatic model acceptance or champion selection.
get_study_champion(study_id) reads the incumbent, accepted candidates/eligibility blockers and immutable selection/replacement/revocation history. The backend requires migration workflow_champion_001. Writes require the project owner's frontend session; MCP cannot promote or revoke. Stale evidence retains the incumbent with review_required. Validation references are reviewer-declared and decision_grade_ready remains false until scientific protocol qualification is implemented. Champion designation does not deploy or fit a model.
Native prediction-window gates are available as prediction_mae, prediction_rmse and prediction_wape (WAPE is a fraction). They use the existing create_quality_policy/evaluate_study_run tools. The backend reads saved actual/prediction rows, requires unique prediction dates after the saved training window and leaves missing/malformed evidence unevaluated. Both windows are bound into the assessment hash. This does not prove untouched holdout provenance, leakage-free preprocessing or full sampling intent; decision-grade champion qualification remains separate.
create_quality_policy(..., validation_protocol=...) can declare a temporal holdout before launching both runs. Required protocol fields are training_end, prediction_start/end, min_draws, min_tune, min_chains, max_r_hat and max_prediction_wape. Use kind: "temporal_holdout"; dates are ISO and WAPE a fraction. No defaults are recommended. Both runs must launch under that exact policy.
assess_study_validation_pair(study_id, full_run_id, validation_run_id, policy_id) assesses saved evidence without fitting or writing a model decision; serving available prediction evidence appends an access audit event. It checks distinct completed MMM tasks, launch binding, matching frozen files/settings/runtime, configured sampling minima, R-hat, prediction-window WAPE/dates and full-date coverage. Missing evidence blocks. The response fingerprint identifies the assessed records. Passing compatibility does not verify retained draws/ESS/divergences, preprocessing or untouched holdout history, and decision_grade_ready remains false.
Validation-pair responses include sampling_evidence for the full and validation runs: retained chain/draw counts, bulk/tail ESS minima and divergences when saved by the fitting engine. Missing or partial records are explicit. These values are not yet checked against acceptance limits and do not certify scientific readiness.
Protocols may now opt into retained_sampling: {min_ess_bulk, min_ess_tail, max_divergences} before launching both models. All limits are explicit, with positive ESS minima and a nonnegative integer divergence maximum. Pair assessments also apply declared chain/draw minima to retained counts. Missing/partial native records block; sampling_qualification distinguishes pass, blocked and not_declared. Business validity and holdout provenance still prevent scientific certification.
Set validation_protocol.require_policy_review before launching to require current analyst acceptance of each latest launch-policy assessment in pair checks. Stale evidence, subsequent rejection, missing acceptance or ambiguous ordering blocks. This reuses required policy gates; external business calculations remain reported evidence. MCP can declare and read these requirements but cannot supply analyst acceptance.
Pair responses expose holdout_provenance separately from compatibility. Version 1 full-input preprocessing records remain blocked. Version 2 records identify training-only transformation/scaling and report review_required with preprocessing_status: training_only. Missing or unsupported records are unavailable; no record is silently certified. Prior-source independence and holdout access/reuse evidence remain required; decision_grade_ready stays false. Existing routes and tool arguments are unchanged.
Pair responses also expose prior_provenance: native frozen automatic-prior source windows are checked against the declared training end and bound to recipe input hashes. A later source window or mismatched hashes is blocked; missing historical/uploaded provenance is unavailable. A valid window still requires review of assumptions, external calibration and holdout reuse. This does not record access history or certify independence. No tool arguments or routes changed.
get_study_prediction_access(run_id) reads partial Studies prediction-access history (totals and latest 20 events). Pair responses include prediction_access with the same partial-coverage summary, independent of the assessment hash. Assessment creation/history reads, comparison and pair checks append audit events when serving available prediction evidence. The three previously read-only inspection tools are now annotated non-destructive/additive and non-idempotent. Reading access metadata itself does not add events.
History is scoped to the study and matching recorded dataset/windows. Older activity, other results routes/exports, other studies and offline work are not covered. Repeated serving does not prove retuning; zero events never proves an untouched holdout. The backend requires its additive prediction-access migration; scientific qualification remains incomplete.
get_model_results(model_hash, sections="prediction_window") explicitly exports saved prediction-window actuals/model values in JSON or CSV; it is omitted from default exports and distinct from scenario predictions. Serving it for a study-linked model appends a native access event, so this tool is conservatively annotated additive/non-destructive. Dashboard results now record access to the same saved window. Filters do not truncate or channel-filter prediction evidence. This broadens instrumentation without certifying untouched holdout status; other routes, source files, earlier activity and offline work remain outside coverage.
declare_study_holdout_use(run_id, declaration_id, source_access_id, disposition, reason, affected_revision_id=None) appends a reported evidence-use declaration with project-owner credentials and create:models. Read access history first and select an event from that run. Use review_only, informed_revision (requires a same-study published revision) or uncertain. Reuse the same UUID/content on retry; conflicting content is rejected. Declarations retain submitting interface and do not certify independence, accept or promote models.
Access/pair responses include holdout_use; reported revision influence retains fresh_validation_required for affected revisions even after later review-only notes. Other declarations remain review_required, and no declarations means not_recorded. Declaration history changes the pair fingerprint; additional viewing alone does not. The backend requires its additive holdout-use migration. Champion reads expose candidate-specific holdout_use: an informed-revision declaration blocks selection of that named revision and marks an existing champion review_required. Ordinary access, review-only notes and unrelated revisions do not block. Later acceptance or review-only notes cannot clear an earlier influence report. This applies to named revisions and their recorded descendants, including ordered recipe predecessors and source-revision ancestry; current analyst-reviewed validation resolutions may clear the exact accepted run; changed or revoked evidence reblocks it. No report is not proof of an untouched holdout.
Replacement holdout preflight: assess_study_validation_pair returns fresh_validation for reports naming the full-model revision. It checks that a replacement policy follows the influence declarations, precedes both runs, and uses prediction dates strictly after the used holdouts. Recorded same-study access overlapping the new dates before policy creation blocks preflight, conservatively across dataset versions. Complete retained sampling, accepted policy evidence and supported training-only preprocessing/prior records are required. Status is not_required, blocked, or review_required; resolves_champion_block is always false. This is not a durable resolution or proof of offline independence. No extra tool or request field is needed.
Reviewed resolutions and recipe ancestry
get_study_validation_resolutions(study_id) returns append-only analyst resolutions and revocations with re-evaluated current, stale or revoked status. The backend requires migration workflow_resolution_001. API keys cannot sign off independence or revoke reviews: the signed-in owner uses the UI, which binds the exact pair fingerprint and requires a rationale plus an explicit independence review. Current resolution clears only the exact accepted full run; new outputs, declarations or reviews invalidate it. Champion reads expose resolved_by_review and the resolution identity. No automatic scientific certification or promotion is performed.
When creating a derived recipe or draft, supply source_revision_id from the same study. create_recipe_draft, create_study_recipe and revise_study_recipe forward this optional field. Draft source linkage is immutable and survives full-editor publication; previous versions of a recipe inherit influence automatically. Unrecorded/off-platform copies remain outside recorded ancestry. Resolution does not transfer to new runs or descendants.
Release note: these tools require the corresponding MCP package release and updated backend. Draft-branch tests do not establish package publication or application deployment.
Available Tools
63 toolsadopt_model_into_studyAdopt Model Into StudyB
Preview an owned completed model and provenance gaps. Set confirm only to attach it to study history; adoption does not refit.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| confirm | No | ||
| study_id | Yes | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that without confirm it is a read-only preview, and with confirm it attaches to study history. It also states that adoption does not refit, which is a behavioral trait not covered by annotations. Given annotations already indicate non-read-only and non-destructive, this adds useful context about the two-phase behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary action (preview), and immediately follows with the conditional confirmation behavior. There is no fluff or redundancy, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values. It covers the preview/attach duality and the non-refit behavior, but it omits the purpose of 'reason' and the meaning of 'provenance gaps', and does not clarify ownership or prerequisites. It is adequate but not fully complete for a tool with 4 parameters and no schema descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for missing parameter explanations. It only clarifies the 'confirm' parameter ('Set confirm only to attach it to study history'). It does not explain 'reason', 'study_id', or 'model_hash' beyond their names, leaving a significant gap for a tool with 4 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: preview an owned completed model and provenance gaps, then optionally attach it to study history via the confirm flag. The verb and resource are implicit but discernible ('attach it to study history'), and it distinguishes itself from siblings by the unique action of adoption. It lacks an explicit 'adopt' verb but the intent is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. It does imply that without confirm it's a preview, but it doesn't mention any other tools or conditions for selection. No exclusions or comparisons to sibling tools are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assess_study_validation_pairAssess Study Validation PairA
Assess a validation pair and append a prediction-access audit event when evidence is available. Checks distinct completed MMM runs launched under the declared protocol, frozen inputs/settings/runtime, configured sampling, saved R-hat, declared prediction windows/WAPE and date coverage. Returns blockers and an evidence hash; does not fit, accept or promote. Includes saved retained chain/draw, ESS and divergence records when available, with null for older models. Optional prelaunch retained_sampling limits require complete native records and check chain/draw minima, bulk/tail ESS minima and maximum divergences; otherwise sampling_qualification is not_declared. Optional require_policy_review checks current signed-in analyst acceptance of each latest same-policy assessment, including freshness and rejection blockers. The holdout_provenance report distinguishes missing evidence, blocked version 1 full-input preprocessing and version 2 training-only preprocessing requiring further provenance review. The prior_provenance report checks recorded automatic-prior source dates and frozen input hashes; missing legacy/uploaded provenance remains unavailable, and recorded inputs after the declared training end are blocked. fresh_validation provides replacement-window preflight for influence reports naming the full-model revision: later windows, replacement policy chronology, recorded prior exposure, retained diagnostics and provenance/review requirements. It never clears champion blocks. External business calculations and untouched holdout history remain unverified; decision_grade_ready stays false.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes | ||
| policy_id | Yes | ||
| full_run_id | Yes | ||
| validation_run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations, detailing side effects (appends an audit event), output specifics (returns blockers, evidence hash, includes diagnostics when available), and limitations (external calculations unverified, decision_grade_ready false). It also clarifies it never clears champion blocks. This is consistent with annotations (readOnly=false, so writes are allowed; destructive=false, so non-destructive) and adds substantial behavioral context that an agent would otherwise not know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is verbose and runs several paragraphs, packing many technical clauses without clear section breaks or bullet points. While it front-loads the main purpose, the density and jargon (e.g., 'retained_sampling limits', 'holdout_provenance report', 'fresh_validation') make it hard to scan. It would benefit from restructuring to highlight key behaviors and parameter roles.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description is quite comprehensive. It covers the checks performed, optional behaviors, return values, and limitations. It mentions what is not verified and that decision_grade_ready remains false. It does not elaborate on error conditions or when the tool might fail, but the output schema and annotations cover the expected response, and the description provides sufficient operational context for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it does not clearly map each parameter to its meaning. It references 'full-model revision' and 'validation pair' which hint at full_run_id and validation_run_id, but it does not explicitly explain study_id, policy_id, or how the IDs relate to the checks described. The description is dense but lacks a clear parameter-to-purpose mapping, leaving agents to infer from context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource ('Assess a validation pair and append a prediction-access audit event') and lists the checks performed. It also clarifies what it does NOT do ('does not fit, accept or promote') and mentions 'never clears champion blocks', distinguishing it from promotion/acceptance tools. However, it doesn't explicitly name sibling tools like evaluate_study_run or validate_study_recipe, so differentiation is implicit rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides rich context about when checks apply (e.g., 'when evidence is available', 'Optional prelaunch retained_sampling limits require complete native records', 'Optional require_policy_review checks...') and exclusions ('does not fit, accept or promote', 'decision_grade_ready stays false'). It implies usage scenarios but does not explicitly say 'use this when you need X instead of Y'. The alternative tools are not named, so the guidance is contextual rather than comparative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_study_runCancel Study RunBDestructive
Request cancellation. Requested and confirmed stopped are distinct states.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey that this is destructive and non-idempotent. The description adds valuable behavioral nuance by clarifying that cancellation is a request and that 'requested' and 'confirmed stopped' are distinct states, implying an asynchronous or multi-step lifecycle. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two short sentences, with the key action upfront and the important state distinction immediately after. There is no filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with an output schema and rich annotations, the description is mostly adequate. However, it does not explain the cancellation flow, how to confirm the eventual stopped state, or what side effects occur. The state distinction is a useful start but could be more actionable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention run_id at all. The parameter name is self-explanatory to a degree, but the description does not compensate for the lack of schema documentation by explaining what run_id refers to, how it should be obtained, or any constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('request') and a clear resource ('cancellation' of a study run), and it distinguishes the requested state from a confirmed stopped state. It does not explicitly differentiate it from sibling tools like update_run or get_study_run, but the core intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives such as launch_study_run, get_study_run, or update_run. The state distinction hints at usage context but does not explain prerequisites, follow-up steps, or which sibling handles confirmed stopping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_study_runsCompare Study RunsA
Compare 2-20 candidates against one quality policy. Serving prediction evidence appends access audit events. Different datasets are flagged, not ranked. Does not fit or promote models.
| Name | Required | Description | Default |
|---|---|---|---|
| run_ids | Yes | ||
| study_id | Yes | ||
| policy_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnlyHint=false and destructiveHint=false. The description goes further by disclosing a concrete side effect: 'Serving prediction evidence appends access audit events,' plus behavioral nuances like 'flagged, not ranked' and no model fitting/promotion. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: main purpose first, side-effect disclosure second, exclusions third. No redundant phrasing or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a comparison tool with an output schema and three simple params, the description covers the core operation, constraints, side effects, and exclusions. Return-value details are presumably covered by the output schema, so nothing essential is missing for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds useful constraints: run_ids are '2-20 candidates' and policy_id maps to 'one quality policy.' However, it does not explicitly define study_id or provide parameter-level semantics such as id formats or relationships, so compensation is partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: compare 2-20 candidates against one quality policy. The closing sentence adds exclusions ('Does not fit or promote models'), which clearly differentiates it from model-lifecycle siblings like adopt_model_into_study and create_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool (multi-candidate comparison against a quality policy) and states what it does not do (fit/promote models, rank different datasets). It does not explicitly name a sibling alternative or give an exact 'use X instead' condition, but the boundary is clear enough for routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_modelCreate ModelA
Create and start fitting a new Bayesian Marketing Mix Model.
This queues an async model fit and returns immediately with a model_hash. Use get_model_status to poll for progress until status is 'complete'.
Priors are calculated automatically using smart defaults based on cost shares, industry benchmarks, and channel-type detection. You can override individual channels via the priors parameter.
Args:
uploaded_file_id: The file ID returned by upload_data.
date_column: Name of the date column in the CSV.
kpi_column: Name of the KPI/dependent variable column.
hierarchy_column: Name of the brand/segment column (must have exactly 1 unique value).
channels: List of channel definitions, each with keys: name, activity_column, spend_column.
Example: [{"name": "TV", "activity_column": "tv_grps", "spend_column": "tv_spend"}]
multiplier_column: Column to convert KPI to revenue. Defaults to kpi_column.
control_columns: Non-media control variable column names (e.g. ["price", "distribution"]).
total_media_effect: Controls prior strength. Either an industry name for a benchmark
("FMCG"=6%, "Retail"=9%, "TelCo"=30%, "Financial Services"=19%,
"E-Commerce"=22%, "Other"=12%) or a custom decimal like "0.15"
meaning "I believe all media drives 15% of my KPI". Default "Other".
priors: Optional per-channel prior overrides. Each dict should have "channel" matching
a channels[].name, plus any fields to override: distribution, mean, sd, lower,
upper, transform, adstock_type, effect_period.
Only specified fields are overridden; the rest use smart defaults.
Adstock-kernel fields: half_life_lower/half_life_upper (carryover half-life
bounds in periods — preferred over the legacy decay_lower/decay_upper),
theta_mean/theta_sd (peak-lag prior, adstock_type="delayed" only),
dual_weight_mean/dual_weight_sd (long-term/slow-component share prior,
adstock_type="dual_geometric" only).
SATURATION ANCHOR — state it ONCE, in exactly one of three
mutually exclusive forms (two in one override -> 400 "state
the saturation prior once"):
(1) half_marginal_mean/half_marginal_sd — CANONICAL for
saturation_type="generalized_log" (rejected on other
families): the activity level where MARGINAL returns have
halved, finite at every curvature (#632).
sat_shape_mean MUST accompany the pair in the same override
(#672) — the fold pairs your coefficient with the
stated curvature, so omitting it is a 400, never a silent
default.
(2) half_saturation_mean/half_saturation_sd — the
50%-of-maximum point in activity units, for the
single-parameter families (tanh/michaelis_menten/
negative_exponential). Do NOT use it for generalized_log
near-log work: it overflows below sat_shape_mean 0.00097657
and is rejected with a 400 — precisely the regime that
family exists for.
(3) alpha_sd + scalars — legacy internal coordinates,
accepted for backward compat.
Curvature (generalized_log only): sat_shape_mean/sat_shape_sd
— small values are near-logarithmic, 1.0 is michaelis_menten.
COEFFICIENT in a human coordinate (generalized_log only,
#671): effect_at_avg_mean/effect_at_avg_sd — the
effect share at the channel's AVERAGE activity, as FRACTIONS
(mean in (0, 0.95], sd > 0; 0.2 means 20%). Folded
server-side into mean/sd at the row's operating point with
the same arithmetic as the dashboard. Requires sat_shape_mean
in the same override; cannot be combined with mean/sd
("state the coefficient prior once") or with
half_saturation_*. Stating half_marginal_* + effect_at_avg_*
+ sat_shape_mean together is the full (x*, E, k) triple —
the recommended generalized_log elicitation, since only
beta*k is identified and raw beta spans orders of magnitude.
VERIFY what was applied via get_model's
model_config.priors_resolved: rows carry the FOLDED
mean/sd/scalars/alpha_sd, and overridden_fields lists the
field names you sent.
UNKNOWN KEYS ARE REJECTED with a 400 naming the field
(#630); they used to be dropped silently, fitting a
hybrid of the override and the smart defaults. Common misses:
"beta"/"beta_mean" -> mean, "beta_sd" -> sd, "sat_shape" ->
sat_shape_mean. "name" and "parameter" are rejected too — they
identify the smart-prior row the override merges onto.
trend: Enable dynamic baseline trend component.
seasonality: Enable automatic seasonality detection. The prior sigma on
the Fourier coefficients is chosen for the link (#534):
0.5 under link="log", 10 under "identity". The coefficients
live on the link's scale, so the additive default would
admit e^10x seasonal amplitude on a multiplicative model.
likelihood: Likelihood function: "normal" (default), "lognormal", "logit",
"studentt", "poisson", "negativebinomial", or "quantile".
saturation_type: Diminishing-returns curve family applied to media:
"tanh" (default), "michaelis_menten", "negative_exponential",
or "generalized_log" (two-parameter Box-Cox/power-log family
1 - (1+x/K)^(-shape); tune per channel via the
sat_shape_mean/sat_shape_sd prior fields).
transform_order: "adstock_first" (default: carryover accumulates, then
saturates) or "saturation_first" (each period's spend
saturates, then the effect spreads over time through the
normalized adstock kernel).
link: Model Form. "identity" (default) fits an additive model — components
add on the outcome scale. "log" fits a multiplicative model —
components add on the log scale and media effects are percentage
lifts. Under the removal_lift attribution convention (the API
default), contributions then include an Overlap reconciliation
column; the other conventions (aumann_shapley — the dashboard
default for multiplicative models since #509 —
shapley, and proportional_normalized) allocate the interaction
across components and close exactly WITHOUT an Overlap column
(see get_model_results).
channel_groups: Optional adstock groups: [{"name": ..., "channels":
[...], "share_saturation": bool}]. Member channels tie
their carryover parameters (decay/theta/dual-weight —
plus saturation when share_saturation is true) to one
shared value, e.g. grouping channels into shared
"Long"/"Short" carryover classes. Members are
channels[].name values; each group needs >= 2 members;
groups must be disjoint; and tied members must have
identical adstock_type/effect_period/bound overrides
(the API rejects divergent groups at request time).
control_reference: Control attribution reference points (#452),
multiplicative models (link="log") only: maps control
column names (plus optional "default") to
"auto" | "absent" | "average" | "lowest" | "highest" —
which counterfactual "remove this control" means in
the contributions. "absent" measures against the
variable at zero (legacy behavior; honest only when
zero is observed). "average"/"lowest"/"highest"
reference the control at its observed mean/min/max —
use for controls that never approach zero (price
indices, distribution levels), where a zero
counterfactual produces unbounded contributions and a
negative Base. "auto" detects per control whether
zero is inside the observed data range. Example:
{"default": "auto", "relative_price": "average",
"promo_flag": "absent"}. Omit entirely to keep every
control at "absent" (byte-identical legacy output).
Unknown control names/modes are rejected at request
time; any value other than "absent" requires
link="log". The fit reports the resolution in
model_config.control_references (see
get_model_results).
name: Display name for the created model, honoured verbatim (#575).
Falls back to a generated API_MMM{brand}{hash} string when
omitted. Either way the model starts unsaved — invisible to
list_models unless include_unsaved=true — until save_model
files it into a project.
operating_margin: Scalar operating margin as a decimal fraction in
(0, 1], e.g. 0.18 = 18%. Mutually exclusive with
operating_margin_column (the API 400s when both are given).
Storing a margin unlocks the financials results section and
lets run_optimizer(objective="profit") use it automatically
instead of requiring forward_margin on every call.
operating_margin_column: Name of a column in the uploaded CSV holding
a per-date margin series. The column may be uniformly in
fractions (0, 1] OR uniformly in percentages (1, 100] — the
API detects the unit and normalizes percentages; mixed units
are rejected. Same unlocks as operating_margin; the column
must exist in the uploaded file. CAUTION: the API reads the
margin keys from the REQUEST ROOT — a margin placed inside a
config dict is silently ignored (no error), and the model fits
marginless.
attribution: Attribution convention for the contribution decomposition,
resolved at fit time: "removal_lift" (the API default;
one-at-a-time removal — multiplicative models then emit the
Overlap column), "aumann_shapley" (the dashboard default for
multiplicative models since #509), "shapley", or
"proportional_normalized". Any value other than "removal_lift"
requires link="log" (the API rejects it on additive models).
The non-removal conventions allocate the interaction across
components and close exactly WITHOUT an Overlap column. To
reconcile with a dashboard-built multiplicative model, use
"aumann_shapley".
annual_discount_rate: Annual discount rate (decimal >= 0, e.g. 0.08)
used by the display-time financial bridge and cohort ledger PV
discounting. Display-time only — does not change the fit.
sampler: MCMC sampler overrides, e.g. {"n_samples": 2000,
"tune": 1500, "chains": 4, "cores": 2, "target_accept": 0.95}.
STRICTLY validated: unknown keys inside sampler are rejected
with a 400 naming the field; cores must be 1-8. Only the keys
you send are overridden.
reporting_kernel: Reporting-kernel class override (#450) for
the cohort_ledger section's forward allocation. Shape:
{"classes": {...}, "channel_classes": {...}} — ONLY those two
top-level keys are accepted (anything else, e.g. "mode", 400s
with the unknown key named). channel_classes names channels by
channels[].name or activity_column, validated at request time.
Affects only how the cohort_ledger allocates effects over the
horizon — not the fit, and not the contributions /
channel_summary decompositions. (The related "complete" /
"in_window" choice is a separate cohort_horizon QUERY parameter
on the results endpoint, not part of this config.)
control_priors: Optional root-level control slope overrides. Each entry names a selected control_columns column with "control", plus transform (N, DM, STA, DDM, LOG), distribution (normal, inversegamma, truncatednormal, halfnormal), mean/sd/lower/upper as applicable. LOG is log(x/mean(x)); STA divides by sample sd without centering. Priors are in transformed units; changing transform does not convert coefficients. Nonempty overrides require backend capability version 1; unsupported or unavailable checks stop before creating a model.
Returns the model_hash for status polling.
| Name | Required | Description | Default |
|---|---|---|---|
| link | No | identity | |
| name | No | ||
| trend | No | ||
| priors | No | ||
| sampler | No | ||
| channels | Yes | ||
| kpi_column | Yes | ||
| likelihood | No | normal | |
| attribution | No | ||
| date_column | Yes | ||
| seasonality | No | ||
| channel_groups | No | ||
| control_priors | No | ||
| control_columns | No | ||
| saturation_type | No | tanh | |
| transform_order | No | adstock_first | |
| hierarchy_column | Yes | ||
| operating_margin | No | ||
| reporting_kernel | No | ||
| uploaded_file_id | Yes | ||
| control_reference | No | ||
| multiplier_column | No | ||
| total_media_effect | No | Other | |
| annual_discount_rate | No | ||
| operating_margin_column | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate a non-read-only, non-idempotent mutation, so the description carries the burden and exceeds it. It discloses the async queue behavior, immediate model_hash return, unsaved-model visibility ('invisible to list_models unless include_unsaved=true'), strict unknown-key rejection with 400s, and even a silent-ignore footgun for operating_margin_column placed inside a config dict.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long, but the complexity (25 parameters, many with nested constraints and 400-level edge cases) justifies most of the length. It is front-loaded with a concise summary and then structured as an Args list with bolded field names and examples. Some sections are dense enough to be slightly hard to parse, but no sentence feels wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 25 parameters, zero schema-level descriptions, no enums, and no sibling differentiation, the description is exceptionally complete. It covers inputs, defaults, validation rules, return value ('Returns the model_hash for status polling'), and points to the correct follow-up tools for status and results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully compensate, and it does. Every parameter including priors, control_reference, reporting_kernel, sampler, and operating_margin_column is explained with defaults, constraints, examples, and validation behavior — far beyond the bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource statement: 'Create and start fitting a new Bayesian Marketing Mix Model.' It clearly distinguishes this from siblings like create_var_model and run_optimizer by specifying it creates a model, queues an async fit, and returns a model_hash.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it explicitly says the fit is async, returns immediately, and instructs the agent to 'Use get_model_status to poll for progress until status is "complete"' and later references get_model_results and save_model. It doesn't explicitly contrast with create_var_model or other model-creation siblings, but the async polling guidance is actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_projectCreate ProjectA
Create a named project (model folder) to file models into.
Names are sanitized the same way model names are (non-empty after HTML sanitization).
Args: name: Display name for the new project. team_id: Optional team to share the project with; must be a team you belong to (403 otherwise, 404 for an unknown team).
Returns the created project (201) including its id — pass that to save_model(project_id=...).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| team_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond annotations: name sanitization rules, team membership requirements with distinct 403/404 errors, and the 201 response including the created project id. Annotations already indicate a mutating, non-idempotent operation, and the description is consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the core purpose, and organized into clear sections: purpose, sanitization note, Args, and Returns. Every sentence adds distinct value with no repetition of schema or annotation information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter creation tool with an output schema present, the description covers the essential behavior: display name, sanitation, team-sharing constraints, return status, and how the result connects to save_model. No critical calling information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description fully compensates by explaining both parameters: 'name' as a display name and 'team_id' as optional sharing with an owned team, including error semantics. This adds real meaning beyond the bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Create a named project (model folder) to file models into.' This clearly distinguishes create_project from sibling tools like create_model and create_recipe_draft by establishing that a project is a container for models.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: projects are for filing models into, and the returned id is meant to be passed to save_model(project_id=...). It does not explicitly name alternatives or when-not-to-use conditions, but the workflow hint is strong enough to guide appropriate invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_quality_policyCreate Quality PolicyA
Save project-specific checks. Built-in checks have metric (r_hat_max, mae, rmse, wape, prediction_mae, prediction_rmse, prediction_wape), maximum and required. Custom numeric checks use metric custom:, name, units, operator (lte/gte/between), applicable minimum/maximum and required. Boolean checks use kind=boolean, operator=equals and expected=true/false. Manual checks use kind=manual, equals, expected=true; agents can define these but cannot submit manual sign-off. Custom bounds may be negative. WAPE is a fraction. Prediction-window checks require saved finite actuals/predictions at unique dates after the saved training window; this does not certify untouched holdout provenance. No default thresholds are assumed. Declare at least one required check, use each metric once, and set maximum R-hat at least 1. Optional validation_protocol declares a temporal holdout split, configured sampling minima, R-hat and prediction WAPE limits before both runs launch under this policy. The backend validates policy rules.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| checks | Yes | ||
| study_id | Yes | ||
| rationale | Yes | ||
| validation_protocol | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing important behavioral constraints: no default thresholds, required-check rules, uniqueness of metrics, the R-hat minimum, prediction-window requirements, the holdout provenance caveat, and the fact that agents cannot submit manual sign-off. This gives an agent realistic expectations about what the backend will enforce.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and packs many distinct, useful constraints into a dense paragraph. It is efficient but could be improved with light structural separation between check types, validation protocol behavior, and validation rules.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's high complexity, the description is remarkably complete: it covers all check kinds, parameter relationships, validation-protocol semantics, and important caveats. Since an output schema exists, not explaining return values is acceptable, and the behavioral detail is sufficient for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description carries the full burden, and it succeeds. It explains core parameter semantics for built-in, custom, boolean, and manual checks, details the validation_protocol object, and clarifies edge cases such as negative custom bounds and WAPE being a fraction.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Save project-specific checks.' It clearly differentiates this from the sibling list_quality_policies by describing creation-side behavior and enumerating the distinct check types the tool supports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description thoroughly explains what the tool can do and the constraints on its use, but it never explicitly states when to choose this tool over alternatives or when not to use it. The intended usage is implied rather than directly framed against sibling tools like list_quality_policies or update_study.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_recipe_draftCreate Recipe DraftAIdempotent
Save an encrypted authoring draft without publishing, fitting or consuming an attempt. Supply a UUID draft_id and reuse it with identical content after an uncertain response. Start from get_recipe_draft_template for a new draft, or preserve the complete snapshot from get_recipe_draft when editing. When copying a published recipe, supply its source_revision_id from this study; the immutable link carries inherited influence through publication. Backend validates version and size.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| draft_id | Yes | ||
| snapshot | Yes | Lossless editor authoring state. Backend is authoritative; preserve unknown nested fields. Source bytes are copied into encrypted draft storage (10 MB source limit); metadata limit is 5 MB. No local filesystem paths or executable code. | |
| study_id | Yes | ||
| source_revision_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotent, open-world, non-destructive, and read-write behavior. The description adds valuable context: encryption, validation of version and size, and the immutable link carrying influence through publication. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads the core purpose and then addresses usage scenarios. Each sentence adds value, though the density makes it somewhat packed. It is appropriately sized for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with a nested schema and five parameters, the description covers the main usage paths, idempotency behavior, and validation. The existence of an output schema (not provided) likely covers return values, so missing return details are acceptable. It could be more explicit about study_id semantics but is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 20%, so the description must compensate. It explains draft_id (reuse for idempotency) and source_revision_id (for copying published recipes), but leaves study_id and name without additional meaning. The nested snapshot fields are partially described within the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Save') and resource ('an encrypted authoring draft') and explicitly distinguishes it from publishing, fitting, or consuming an attempt. It also clarifies the tool's role relative to siblings like publish_recipe_draft and update_recipe_draft by describing creation scenarios.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage scenarios: starting from get_recipe_draft_template for new drafts, preserving the snapshot from get_recipe_draft when editing, and supplying source_revision_id when copying a published recipe. It also mentions reusing draft_id for idempotent retries. It does not explicitly contrast with update_recipe_draft, but the create/update distinction is implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_studyCreate StudyA
Create a study owned by an existing project. Does not launch models.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| question | Yes | ||
| project_id | Yes | ||
| max_attempts | No | ||
| max_concurrent | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a non-read-only, non-idempotent, non-destructive mutation. The description adds useful behavioral context beyond annotations: the study is created in an existing project and no models are launched, helping the agent avoid assuming side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The main purpose is front-loaded, and the clarifying non-launch behavior is placed at the end where it serves as a useful qualifier without distraction.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a straightforward creation tool, the description covers the key contextual requirement (existing project) and the most likely confusion (model launching). With annotations and an output schema present, the remaining omissions are mostly parameter semantics, which are partially compensated by clear parameter names.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain any of the five parameters. Parameter names like name, question, project_id, max_attempts, and max_concurrent are somewhat self-explanatory, but the description adds zero meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Create a study') and adds the scoping condition 'owned by an existing project.' The explicit note 'Does not launch models' helps distinguish this from launch_study_run or run_optimizer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies the appropriate use context: creating a study under an existing project rather than executing or launching anything. The negative statement 'Does not launch models' provides a clear when-not signal, though it does not name an alternative tool explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_study_recipeCreate Study RecipeA
Freeze a recipe without fitting. Supply source_revision_id when deriving from a published same-study recipe to retain influence ancestry. Optional expected_content_hash binds the validated effective inputs; a mismatch returns 409 and requires a fresh preview. Specification kind api_mmm has request containing create_model API fields; model_snapshot has model_hash and is review-only.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| reason | Yes | ||
| study_id | Yes | ||
| specification | Yes | Backend recipe envelope. api_mmm requires request; model_snapshot requires model_hash and is review-only. Unknown fields are forwarded for backend validation. | |
| source_revision_id | No | ||
| expected_content_hash | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses non-obvious behavior beyond the annotations: a content-hash mismatch returns 409 and requires a fresh preview, model_snapshot specifications are review-only, and source_revision_id preserves influence ancestry. These details materially improve an agent's ability to anticipate side effects and error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three dense sentences with no filler. It front-loads the primary action, then groups optional parameters and specification variants logically so each sentence adds unique information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with nested objects and an output schema, the description covers the key behavioral and parameter nuances. It could be more complete by referencing when a draft vs. a frozen recipe is appropriate, but the available annotations and output schema cover much of the remaining context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is low (17%), but the description compensates by explaining why source_revision_id and expected_content_hash are used and by clarifying the two specification kinds (api_mmm vs. model_snapshot). The remaining required parameters (study_id, name, reason) are left self-evident from their names, which is acceptable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific action and object ('Freeze a recipe') and the qualifier 'without fitting' communicates the core purpose. However, it does not explicitly distinguish this tool from its close siblings such as create_recipe_draft or revise_study_recipe, so an agent has to infer which one to choose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear conditional guidance for source_revision_id ('when deriving from a published same-study recipe') and explains the consequence of a mismatched expected_content_hash. There is no explicit 'when to use this vs. alternatives' statement, and with siblings like create_recipe_draft in the same domain, that is a meaningful gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_var_modelCreate Var ModelA
Create and start fitting a long-term (VAR) model (#569).
VAR models capture the joint dynamics of several series (e.g. sales and
brand-equity metrics) and produce the long-run elasticity bridge behind
the MMM's long_run_rollup results section. Fit one, then link it to an
MMM with link_var_model.
Args: uploaded_file_id: Dataset id from upload_data (must contain every named column). date_column: Date column name. Cannot also be a series. endogenous_vars: At least two column names — the jointly-modeled series. exogenous_vars: Optional outside drivers; must not overlap the endogenous set. lags: VAR order (>= 1). The dataset needs at least lags + 10 rows with no missing values across the modeled columns. forecast_horizon: Periods forecast for diagnostics (default 12). base_variable: The outcome series (must be endogenous) long-run multipliers are measured against. Required for long-run effects. equity_variables: Endogenous columns (excluding the base) whose long-run IRF multipliers are estimated. Required for long-run effects. lre_horizon: Long-run effects horizon in periods (default 156). lre_ci: Credible-interval mass for the effects table, in (0, 1). var_priors: Advanced prior overrides (lag_coefs / alpha / coefs / noise_chol); unknown keys are rejected. name: Display name for the created model, honoured verbatim (#575). Falls back to a generated API_VAR_* string when omitted.
Returns 202-style payload with model_hash; poll get_model_status.
| Name | Required | Description | Default |
|---|---|---|---|
| lags | No | ||
| name | No | ||
| lre_ci | No | ||
| var_priors | No | ||
| date_column | Yes | ||
| lre_horizon | No | ||
| base_variable | No | ||
| exogenous_vars | No | ||
| endogenous_vars | Yes | ||
| equity_variables | No | ||
| forecast_horizon | No | ||
| uploaded_file_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, indicating mutation but no destruction. The description adds important behavioral details: it returns a 202-style payload with model_hash, requires polling get_model_status, and notes that unknown keys in var_priors are rejected. It also specifies that fitting starts asynchronously, which is beyond what annotations provide. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with a purpose statement, contextual background, a detailed Args section, and a Returns note. Each sentence serves a purpose, explaining either the tool's role or parameter constraints. It's slightly verbose but justified given the 12 parameters and the need to compensate for zero schema coverage. The key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (12 params, no schema coverage, mutation, asynchronous behavior), the description is remarkably complete. It covers prerequisites (dataset content, row count), parameter relationships, defaults for optional params, and the return type with follow-up action. Nothing an agent needs to invoke correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden for parameter documentation. It explains every parameter in the Args section, adding meaning well beyond the schema: e.g., uploaded_file_id must contain every named column, date_column cannot also be a series, endogenous_vars must have at least two, lags requires enough rows, base_variable must be endogenous, etc. This is essential for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Create and start fitting a long-term (VAR) model'. It distinguishes itself from the sibling link_var_model by explaining that this tool creates the model while link_var_model connects it to an MMM. The reference to the MMM's long_run_rollup gives domain context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: for modeling joint dynamics of series and producing long-run elasticity. It explicitly mentions the follow-up step of linking with link_var_model, which guides the agent on the workflow. However, it doesn't explicitly state when NOT to use this tool or list alternative model-creation tools (like create_model), so it's not fully explicit about exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
declare_study_holdout_useDeclare Study Holdout UseAIdempotent
Append a submitter-reported evidence-use declaration using project-owner credentials and create:models. Read get_study_prediction_access first and reference an access event from this run. Use a fresh UUID declaration_id and reuse it unchanged on retry. informed_revision requires a published affected revision in the same study; other dispositions omit it. Reason must explain actual use. Reported revision influence requires fresh validation for affected revisions; later review-only notes cannot erase it. Does not certify independence, accept or promote a model. API submissions remain identified as reported declarations.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| run_id | Yes | ||
| disposition | Yes | ||
| declaration_id | Yes | ||
| source_access_id | Yes | ||
| affected_revision_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint and readOnlyHint=false, and the description adds behavioral context beyond them: write-scope requires project-owner credentials and create:models, declaration_id idempotency mechanics, revocation of stale revision influence, and the fact that API declarations stay marked as reported. This is rich behavioral disclosure with no contradiction to the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place by adding an operational constraint or clarification. Core purpose is front-loaded, followed by prerequisite steps, retry behavior, parameter conditions, and exclusions, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a non-trivial six-parameter mutation with zero schema descriptions, the description covers prerequisites, auth, idempotent retry, conditional parameter requirements, validation implications, and non-goals. An agent has enough context to call this tool correctly and to understand follow-up obligations such as fresh validation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it succeeds: declaration_id is tied to fresh-UUID/retry semantics, source_access_id to an access event from the run, disposition and affected_revision_id to the informed_revision conditional, and reason to explaining actual use. Every parameter receives meaningful semantic guidance beyond its bare title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening phrase 'Append a submitter-reported evidence-use declaration' names a specific verb, resource, and scope, and the final sentence explicitly excludes certification/promotion duties, differentiating this from sibling study actions. It also names get_study_prediction_access as a prerequisite, which helps distinguish the read path from this write path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use instructions: read get_study_prediction_access first, reference an access event from this run, and use a fresh UUID reused unchanged on retry. It also states conditional usage rules for informed_revision versus other dispositions, giving clear operational guidance without requiring the agent to guess.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_modelDelete ModelADestructiveIdempotent
PERMANENTLY DELETE a FAILED model. Destructive and irreversible.
Only models with status "failed" can be deleted over the API — any other status returns a 409 with the model's current status (delete is for cleaning up failed fits, not curating good ones). Deleting also unlinks any MMMs that pointed at it as their VAR model and removes stored artifacts. On success returns {"deleted_model_hash": ..., "status": "deleted"}.
Check first with get_model or get_model_status if unsure of the status.
Args: model_hash: Hash of the FAILED model to delete permanently.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this destructive and non-read-only, but the description adds meaningful context: deleting is irreversible, unlinks MMMs pointing to the model, removes stored artifacts, and returns a specific success payload. It also discloses the 409 error behavior for non-failed models. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: scope, irreversibility, precondition, side effects, return value, and pre-check advice are all included. The most critical warning is front-loaded, and the Args section is clean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive one-parameter API, the description covers allowed inputs, error conditions, side effects, success response, and recommended pre-checks. Even with an output schema present, it explicitly shows the success payload, leaving little for an agent to guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description carries the full burden. It defines model_hash as the hash of the FAILED model to delete permanently, adding the critical status constraint and purpose beyond the schema's bare 'Model Hash' title. It could mention how to obtain the hash or confirm its format, but for a single parameter this is adequate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('PERMANENTLY DELETE a FAILED model') and clearly scopes the operation to failed models only. This distinguishes it from sibling tools like get_model, rename_model, or unlink_var_model, even without inspecting their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool: only for failed models, and explicitly states that any other status returns a 409. It also advises checking with get_model or get_model_status first, giving an agent clear decision guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
evaluate_study_runEvaluate Study RunA
Save an immutable assessment. First evaluate without external_evidence to obtain report.basis_hash; then calculate custom metrics from outputs and submit finite numeric or strict boolean values, method and source reference with that expected_basis_hash. The server applies the saved rule; stale model evidence is rejected. External calculations are submitter-reported, not verified. Each submission is complete: omitted custom values stay unevaluated. Manual sign-off requires a signed-in reviewer and is rejected for API keys. No automatic champion promotion. Built-in errors are fitted-window, not holdout; VAR remains unsupported.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| policy_id | Yes | ||
| external_evidence | No | ||
| expected_basis_hash | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals many non-obvious behaviors: assessments are immutable, stale model evidence is rejected, external calculations are submitter-reported and not verified, omitted custom values remain unevaluated, and built-in errors are fitted-window rather than holdout. These go far beyond the annotations, which only provide generic hints, and meaningfully shape how an agent should invoke the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence carries essential operational or behavioral information. It is front-loaded with the core purpose, 'Save an immutable assessment,' and then efficiently sequences the required workflow. There is no filler or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, an output schema, and only generic annotations, the description covers the full lifecycle: initial hash generation, evidence submission, staleness, authentication constraints, completeness semantics, and unsupported edge cases. An agent has enough information to avoid common mistakes and to decide when this tool is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description compensates by explaining the role of external_evidence and expected_basis_hash, including the ordering dependency and the requirement for finite numeric or strict boolean values. It also clarifies that submissions are submitter-reported. It does not explain run_id or policy_id beyond their names, but the workflow description provides enough context for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise action, 'Save an immutable assessment,' which clearly identifies the tool as a write operation for creating a persistent evaluation of a study run. It distinguishes this from read-only sibling tools like list_study_evaluations or comparison tools by emphasizing immutability and submission of evidence. Despite not naming a sibling explicitly, the verb and resource are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit two-step workflow: first evaluate without external_evidence to get report.basis_hash, then submit with expected_basis_hash. It also gives important usage conditions such as manual sign-off requiring a signed-in reviewer and being rejected for API keys, plus the no-automatic-champion-promotion caveat. It does not explicitly name alternative tools, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_backend_capabilitiesGet Backend CapabilitiesARead-onlyIdempotent
Discover this caller's connected backend features before planning work.
Returns only backend advertisements: model families, transformations, priors and workflow operations. A missing advertisement is unknown, not unsupported. Check each field; an advertised feature still requires permission and budget. No model is created and capabilities are not cached across callers.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations: it explains open-world semantics ('missing advertisement is unknown, not unsupported'), warns that advertised features still require permission and budget, and discloses that no model is created and capabilities are not cached across callers. This meaningfully informs how the agent should treat the result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four compact sentences, each earning its place: when to use, what it returns, how to interpret missing/advertised features, and what side effects to expect. The key guidance is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, rich annotations, and an output schema present, the description is fully sufficient for an agent to select and invoke the tool correctly. It covers timing, interpretation, permission nuance, and non-caching behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the description carries no parameter burden. The baseline of 4 applies, and the description still helps set expectations about what the returned result represents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Discover this caller's connected backend features' and clarifies it returns only backend advertisements for model families, transformations, priors, and workflow operations. This clearly differentiates it from the many sibling tools by scope and intent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this before planning work and explains how to interpret missing advertisements ('unknown, not unsupported'). It does not name exclusions or alternative tools, but none of the siblings compete with this capability-discovery role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contribution_groupsGet Contribution GroupsCRead-onlyIdempotent
Read the stored contribution groups for a model (#436). Legacy dashboard-saved configs are served verbatim.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is disclosed. The description adds 'Legacy dashboard-saved configs are served verbatim,' which is a behavioral nuance beyond the annotations, but it is terse and cryptic ('#436') and does not explain implications like formatting or transformation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short (two sentences) and front-loads the purpose, which is good. However, the second sentence is cryptic and not well structured; it references '#436' and a legacy behavior without context, making it less clear and slightly wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with one parameter and an output schema, the description is minimal. It omits any explanation of the model_hash parameter and does not mention potential error cases or prerequisites. The cryptic legacy note adds confusion rather than completeness. The output schema exists, so return values are not required, but parameter description and edge cases are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention the model_hash parameter at all. The parameter is named model_hash, which is somewhat self-explanatory, but the description adds no meaning about its format, requiredness, or how to obtain it. With zero coverage, the description must compensate, and it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads stored contribution groups for a model, using the verb 'Read' and naming the resource. It distinguishes from the sibling set_contribution_groups, though it does not explicitly name that sibling. The reference to '#436' is cryptic and not helpful.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (reading contribution groups) but provides no explicit guidance on when to use this tool versus alternatives, nor any exclusions or prerequisites. It does not mention that set_contribution_groups is the write counterpart or any conditions that would route an agent here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_data_schemaGet Data SchemaARead-onlyIdempotent
Get the canonical CSV data schema for Simba MMM input files.
Returns the JSON Schema specification describing required columns (date, KPI, multiplier, hierarchy), media channel column naming conventions ({channel}_activity, {channel}_spend), constraints (min rows, max file size), and supported date formats.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value by disclosing the tool's return contract: a JSON Schema specification listing required columns, naming conventions, constraints, and date formats. No contradiction exists, and the behavior is fully consistent with a read-only metadata query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the action and resource, and the second sentence enumerates the return contents with no wasted words. Every sentence contributes useful information, and the structure is easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, read-only schema tool with an output schema, the description is complete. It tells the agent exactly what to expect in the response, lists the schema's key contents, and needs no additional context to select or invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the input schema is trivially documented at 100% coverage. There are no parameter semantics for the description to clarify, and the baseline for zero-parameter tools is 4; the description appropriately focuses on the return value instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get the canonical CSV data schema for Simba MMM input files.' It further clarifies the exact content returned (required columns, naming conventions, constraints, date formats), leaving no ambiguity about what the tool does. It is clearly distinguishable from all siblings, none of which offer a data schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: this is the canonical schema for Simba MMM input files, which signals when an agent should call it for constructing or validating input data. It does not explicitly name exclusions or alternatives, but no sibling tool serves the same schema-retrieval purpose, so the implicit use-case guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_modelGet ModelARead-onlyIdempotent
Get a model's metadata and configuration echo — works for EVERY status, including failed models (unlike get_model_results, which needs 'complete').
Use this to inspect what a model was configured with, why it failed, or where it lives. Returns: id, model_hash, name, status, model_type ("mmm"/"var"), hierarchy_value, periodicity, is_saved, project_id/name, linked_var_model_hash, created_at/completed_at, error (the failure message — non-null only when status is "failed"), and model_config (the create-time configuration echo: data_source, columns, channels, priors as resolved, and the config flags).
NOTE: the echo omits a few accepted create_model inputs (operating_margin, annual_discount_rate, reporting_kernel) — absence there does not mean they weren't applied; check the financials results section for the stored margin.
Args: model_hash: The model hash (any status).
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and idempotent. The description adds substantive behavioral detail beyond that: it works for any status, the error field is non-null only for failed models, and it lists the configuration echo and its known omissions. This materially helps an agent predict behavior without over-claiming.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized: opening purpose, use cases, returns, and a note about omissions. Every sentence carries useful information, including the critical caveat about omitted create_model inputs. The most important differentiator (works for any status) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter input, the existing output schema, and the annotations, the description covers all decision-relevant details: why to use this over siblings, what the return shape means, and an important limitation of the echo. No critical gap remains for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only provides the parameter name and type with 0% description coverage. The description's Args section adds 'The model hash (any status),' clarifying that this identifier is valid even for failed models. For a single parameter this is adequate, though more detail on how to obtain the hash could be helpful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Get a model's metadata and configuration echo.' It clearly states what the tool returns and explicitly contrasts itself with get_model_results, making its scope unambiguous and differentiating it from a close sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: 'works for EVERY status, including failed models' and contrasts with get_model_results which 'needs complete.' It also explains common use cases: inspect configuration, understand failure, or locate a model. This is direct and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_model_resultsGet Model ResultsA
Get results from a completed model.
Available sections:
channel_summary: per-channel aggregates {Channel, Sales, Spend, Revenue, ROI}.
contributions: per-period decomposition (Date, one column per channel, plus Base, Seasonality, Event Effect, Model, Fit Actual, Actual). Values are in KPI/unit space — the multiplier is NOT applied. Use
coefficientsfor per-period revenue. Multiplicative (link="log") models fitted with the removal_lift attribution convention add anOverlapcolumn: a negative shared-synergy reconciliation term so that Base + components + Overlap = Model. Overlap is NOT a channel — never rank it, share it, or feed it to the optimizer/scenarios. Overlap requires BOTH link="log" AND attribution="removal_lift" (the API default): under aumann_shapley (the dashboard default for multiplicative models since #509), shapley, or proportional_normalized, the interaction is allocated across components, which close exactly with NO Overlap column — its absence does NOT mean the model is additive or predates the feature. Control columns are measured against the reference point resolved at fit time (#452, see model_config.control_references) — e.g. "vs. average conditions" for a control that never reaches zero — not necessarily against zero, so a referenced control's series legitimately spans zero.coefficients: per-period per-channel media results table (Date, Channel, Sales, Revenue, Spend, Media Units, ROI, Cost/Revenue/Sales per Media Unit). This is the only per-period revenue-space decomposition.
params: fitted posterior means per channel (alpha, decay, cpu, scalars).
decay_curves: adstock decay per channel (mean/lower/upper, l_max, adstock_type, curve points; dual-geometric models add decay_slow_* and dual_weight_* parameters).
response_curves: 100-point spend-vs-revenue grid per channel with credible bands ({ch}, {ch}_lower, {ch}_lower_50, {ch}_upper_50, {ch}_upper).
marginal_curves: same grid for marginal ROI (diminishing returns).
saturation: fitted saturation family and parameters (saturation_type is tanh, michaelis_menten, negative_exponential, or generalized_log; per-channel alpha/scale, plus transform_order and — for generalized_log only — per-channel sat_shape).
mroi_summary: headline marginal ROI at current spend per channel with a 94% HDI (channel, current_spend, mroi_median, mroi_hdi_3, mroi_hdi_97). Post-#591 posterior fits add two averaging-convention scalars per channel — mroi_allperiods_unweighted_median (+_hdi_3/_hdi_97) and mroi_spendweighted_active_median (+_hdi_3/_hdi_97), with profit variants on margin models — plus a top-level conventions_available array. Channels with no active periods omit the spendweighted fields. Post-#629 fits also carry a *_mean beside every *_median (mroi_mean, mroi_profit_mean, pv_kernel_mass_mean, and the convention variants). The median is what the product displays; the mean is the statistic that reconciles with the marginal-revenue curve, since derivative and mean commute and median does not. Absent on anything fitted before #629 — there is no backfill, so feature-detect rather than assume.
mroi_periods: OPT-IN ONLY (#591) — never in the default payload; request it by name in
sections. Per-period marginal ROI series: {available, hdi_prob, evaluation_point: "historical_period_spend", rows} with one row per (channel x modelled period): channel, date, spend, mroi_median/_hdi_3/hdi_97, and mroi_profit* on margin models. Models fitted before the artifact existed return {available: false, reason: "fitted_before_mroi_periods"} — refit to enable. Large (channels x periods) — pair with the channels filter.model_stats: fit diagnostics (R², MAPE, Durbin-Watson, Max R_hat, ...).
actual_vs_model: actual vs predicted per period with 50%/95% HDIs.
long_run_rollup: MMM short-term + VAR long-run revenue rollup per channel; returns {available: false, reason: "no_linked_var_model"} when no VAR model is linked to this MMM. Joins by exact name unless the link declared a channel_map (see link_var_model) — mapped rows carry var_group and an allocated elasticity slice, with group-level truth in metadata.groups. A computed rollup where nothing joined stays available: true but carries reason: "no_channel_overlap" — check metadata.coverage, then declare a channel_map on the link.
optimizer: latest optimization results (see get_optimizer_results).
predictions: latest scenario prediction rows (see get_scenario_results).
prediction_window: OPT-IN ONLY saved prediction-window actuals/model values. Request sections="prediction_window" (JSON or CSV); omitted by default. This is not certified untouched holdout evidence. For study-linked models, serving it appends an access audit event; channel/grid filters do not alter it.
posterior: full posterior summary table — one row per model variable with mean, sd, hdi_3%, hdi_97%, and r_hat (quotable 94% HDIs and per-variable convergence).
posterior_transforms: the importable transform-parameter posterior grid (what the dashboard's prior builder imports): per-channel alpha mean/sd, decay 94% HDI, dual-weight mean/sd, decay-slow HDI, sat-shape mean/sd, and the adstock structure including tied-group member aliases. Rows key on activity-column names — join via channel_map.
r_hat: per-parameter R-hat over ALL posterior variables — including transform RVs such as {channel}_decay that the posterior summary's coefficient rows do not cover. Use it to attribute a bad Max R_hat (model_stats) to a specific parameter block.
financials: the model's operating margin ({operating_margin, operating_margin_series}); omitted entirely for marginless models. operating_margin_series is a DATE-STRING-KEYED DICT ({"2024-01-01": 0.18, ...}), not a list of records.
cohort_ledger: per-(channel, source-period) forward-allocation ledger — each period's spend is credited with the future effects its adstock carryover earns (horizon slices plus PV-discounted financials from the fit-time cohort kernels). Models fitted before the artifact existed return {available: false, reason: ...} — feature-detect on
available.model_config: the resolved model specification (inputs, not posteriors) to audit or reconstruct the create_model call — includes config flags such as saturation_type, transform_order, and link ("log" = multiplicative). Multiplicative models with controls also report control_references (#452): per control, the requested and resolved attribution reference mode, the zero_distance diagnostic behind the "auto" choice, and the posterior-mean q_ref. Models created before these fields existed may omit them. priors_resolved reports what the fit actually consumed (#643): per row, overridden_fields lists only the fields that took effect, and accepted_not_used — present only when non-empty — names any that were accepted but inert for this model's configuration, each with a reason. A prior field can be spelled correctly and still do nothing: theta_* needs adstock_type "delayed", dual_weight_* needs "dual_geometric", sat_shape_* needs saturation_type "generalized_log", and the decay / half-life bounds are ignored FOR "dual_geometric". If a prior you set appears to have had no influence, read accepted_not_used first. The folded coordinates (half_marginal_*, effect_at_avg_*) are never called inert — they land in the row's scalars/alpha_sd/mean/sd.
channel_map: canonical identifier mapping, one record per channel: {channel, activity_column, spend_column} as configured at create time. This is the join key between channels[].name and the sections keyed by activity-column name (contributions, decay_curves, posterior_transforms).
The response envelope includes sections_available — trust it over any
hardcoded list if the server is newer than these docs.
IMPORTANT — channel naming: results are keyed by the channel's ACTIVITY
COLUMN name (e.g. "search_activity"), not by the channels[].name passed to
create_model. These exact keys (case- and space-sensitive) must be used in
run_optimizer bounds, laydown_weights, and period_cpm. Always read
channel_summary first to get the exact keys.
NOTE: Date values in contributions/coefficients records are millisecond epoch integers.
CONTEXT-SIZE TIP: a full pull is very large (curve sections alone are 100 grid points x channels x 5 band columns). In conversational use, request only the sections you need and pass channels=[...] and max_grid_points=20.
Args:
model_hash: The model hash.
sections: Comma-separated list of sections to include.
Leave empty for all sections.
Common: "channel_summary,model_stats" for ROI and diagnostics.
format: "json" (default) or "csv". CSV returns
{"format": "csv", "content": "..."} — concatenated
"# section" + CSV blocks, useful for saving to disk.
Filtering below applies to JSON only.
channels: Optional channel filter (matching is case/space-insensitive
and tolerates the _activity/_spend suffix). Applied to curve
sections, decay_curves, saturation, channel_summary,
coefficients, mroi_summary, and mroi_periods rows.
contributions is never filtered (its control columns are
indistinguishable from channels client-side).
max_response_bytes: Optional UTF-8 JSON result byte ceiling after filtering.
Oversize results return an actionable error, never partial evidence.
Bounds MCP content, not the backend HTTP download.
max_grid_points: Optional cap on response/marginal curve grid points;
records are strided evenly, keeping first and last.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | json | |
| channels | No | ||
| sections | No | ||
| model_hash | Yes | ||
| max_grid_points | No | ||
| max_response_bytes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint=false, idempotentHint=false), so the description carries the behavioral burden and does so extensively. It discloses the prediction_window access-audit side effect, availability-false reasons, no-backfill behavior for pre-#629 fits, the Overlap reconciliation semantics, epoch-date encoding, CSV envelope shape, and oversize-result error behavior rather than partial evidence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured — summary line, section bullets, important caveats, then Args — and front-loaded with the core purpose. It is very long, but the length is largely justified by the tool's many sections and edge cases; a little trimming of version-history detail would improve conciseness without losing safety.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is exceptionally complete for a complex, multi-section read tool: section semantics, availability reasons, channel-keying pitfalls, filter boundaries, opt-in sections, date formats, CSV behavior, and even a fallback instruction to trust sections_available over hardcoded lists. With an output schema present and this level of contextual detail, nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the Args section fully compensates: sections lists options and common values, format describes the CSV envelope, channels explains matching tolerance and which sections it affects, and max_response_bytes/max_grid_points carry precise behavioral semantics. Every parameter is meaningfully explained beyond its bare schema type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line names a specific resource — results from a completed model — which clearly separates this from sibling tools like get_model_status or get_model. The long section catalog further defines the tool's scope, and the optimizer/predictions bullets explicitly point to get_optimizer_results and get_scenario_results for those alternative views.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete when-to-use guidance: request only needed sections, use 'channel_summary,model_stats' as a common default, read channel_summary first to obtain exact activity-column keys, and pass channels/max_grid_points to bound payload size. It also marks opt-in-only sections and states when filtering applies or does not apply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_model_statusGet Model StatusARead-onlyIdempotent
Check the fitting progress of a model.
Returns status (pending/under way/complete/failed), progress percentage, estimated time remaining, and timestamps. When supported by the backend, fit_liveness reports heartbeat age and the configured stall threshold in seconds, with last_heartbeat_at as Unix seconds. seconds_until_stall_threshold is time to the stale-heartbeat threshold, not fit ETA or an exact kill time. stall_threshold_exceeded does not change the model status. If fit_liveness is absent or available is false, liveness is unknown: do not infer a healthy or stalled fit. Reasons include heartbeat_unavailable and not_fitting. Continue polling with backoff; do not automatically restart a fit.
Args: model_hash: The model hash returned by create_model or list_models.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations (which already declare readOnly, idempotent, etc.) by explaining subtle behaviors: fit_liveness heartbeat semantics, stall_threshold meaning, that stall_threshold_exceeded does not change status, and how to handle missing liveness data. This level of detail is exceptional and eliminates ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a clear purpose statement, then details on return values, liveness behavior, and polling guidance. Every sentence adds value; there is no filler. The critical information is front-loaded, and the parameter explanation is appended logically. It is concise for the complexity it covers.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (liveness, stall thresholds, edge cases) and that an output schema exists (so return format is covered elsewhere), the description is fully complete. It addresses all possible scenarios an agent might encounter: supported vs unsupported backend, absent liveness, stall threshold semantics, and appropriate polling behavior. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully explain the parameter. It does: 'model_hash: The model hash returned by create_model or list_models.' This adds clear meaning about where to obtain the value, which is essential for correct usage. The description fully compensates for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Check the fitting progress of a model.' It specifies the resource (model) and the action (check status). It also distinguishes itself from sibling tools like get_model_results or get_optimizer_results by focusing on fitting progress, not results. The description is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: it's for polling fitting progress, and explicitly instructs to 'Continue polling with backoff; do not automatically restart a fit.' It also warns about how to interpret liveness data and when not to infer health. While it doesn't name specific alternative tools, the guidance on when to use and what to avoid is sufficient for an agent to decide correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_optimizer_resultsGet Optimizer ResultsARead-onlyIdempotent
Get budget optimization status and results.
Without run_id: returns the MODEL-LEVEL optimizer state. Top-level keys:
optimizer_status ("none"/"pending"/"under way"/"complete"/"failed"),
progress + progress_text while running, and results when complete.
This reflects the LATEST run on the model — a newer run overwrites it, so
a poller can lose sight of the run it submitted.
With run_id (run_optimizer's response includes it): fetches that specific
run, immune to later runs. Top-level keys include run_id, model_hash,
status, created_at, label, inputs, and results. Poll THIS form
when you need to know whether your own run completed.
Reading results rows — the columns come from DIFFERENT conventions and
must not be treated as interchangeable:
Revenue/ROI: the optimizer's DECISION math — removal-lift counterfactual revenue at the allocated spend. This is what the solver optimized.OptimizedEvalRevenue/OptimizedEvalROIandHistoricalRevenue/HistoricalROI: fitted-convention COMPARISON columns — the reconciled accounting view matching the model's Contributions panel. Same spend, different question; never mix them withRevenue/ROIin one summary.ObjectiveMarginal: the decision-math marginal return at the optimum (the quantity the solver equalizes across unconstrained channels).MroiAtOptimized/MroiAtOptimizedHdi3/MroiAtOptimizedHdi97: posterior mROI evaluated at the optimized spend (94% HDI bounds) — a DIFFERENT quantity from ObjectiveMarginal (they can differ by several times); quote the one matching the question asked.Convergence / KKT certificate fields report solver health. All-None placeholder arrays (PeriodResponse etc.) are stripped server-side.
Args: model_hash: Hash of the model that was optimized. run_id: Optional optimization run id from run_optimizer's response. Pass it to poll a specific run's status/results.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | No | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds substantial behavioral context: the overwrite semantics of the latest run, the distinction between decision-math and fitted-convention columns, the stripping of all-None placeholder arrays, and the warning that ObjectiveMarginal and MroiAtOptimized are different quantities. This goes far beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: the two-mode distinction, the column-convention warning, and the parameter explanations are all necessary for correct use. It is front-loaded with the core purpose and mode distinction, then details. Slightly dense, but not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity — two modes, multiple result conventions, and a rich output schema — the description is remarkably complete. It explains the top-level keys for both modes, warns about column incompatibility, and clarifies which quantity answers which question. The output schema exists, so return-value details are not the description's job, and the description still adds the interpretive context the schema cannot.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter meaning. It does: model_hash is 'Hash of the model that was optimized,' and run_id is 'Optional optimization run id from run_optimizer's response' with guidance to pass it to poll a specific run. The description could add a bit more about the format of model_hash, but it fully compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('budget optimization status and results'), and immediately distinguishes two modes: without run_id returns model-level state, with run_id returns a specific run. This clearly differentiates it from siblings like run_optimizer, get_model_results, and get_scenario_results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use each form: poll without run_id for the latest model-level state, and pass run_id to poll a specific run's completion. It also warns that a newer run overwrites the latest state, so a poller can lose sight of its own run — a clear when-not-to-use signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipe_draftGet Recipe DraftARead-onlyIdempotent
Read the complete authoring snapshot and concurrency version. Preserve all fields when editing. Draft state is incomplete, unvalidated authoring data, not an executable recipe.
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, open-world, and non-destructive behavior, so the bar is lower. The description adds useful context: the response is a complete snapshot with a concurrency version, edits should preserve all fields, and the draft is not an executable recipe.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each adding distinct information: action, editing directive, and state warning. It is front-loaded with the core read operation and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single obvious parameter, an output schema, and rich annotations, the definition covers the important non-obvious semantics: completeness, concurrency, and draft validity. It could go further by explaining how the concurrency version should be used when updating, but this is not essential for a read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no property description and the tool description never mentions draft_id, so it doesn't compensate for 0% schema description coverage. The parameter name is self-explanatory, but the description adds no meaning about how to obtain or format the ID.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence uses a clear verb ('Read') with a specific resource ('complete authoring snapshot and concurrency version'), going well beyond the tool's title. It also distinguishes the draft-read operation from siblings like get_recipe_draft_template or publish_recipe_draft by emphasizing completeness and draft state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Preserve all fields when editing' provides real guidance for a read-then-edit workflow, and the warning that drafts are unvalidated authoring data sets expectations. However, it never names sibling tools or explicitly states when to choose get_recipe_draft over get_recipe_draft_template, get_recipe_revision_authoring, or list_recipe_drafts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipe_draft_templateGet Recipe Draft TemplateARead-onlyIdempotent
Get complete shared wizard defaults, hash and envelope schema. Optionally choose an owned uploaded_file_id or pipeline_version_id (never both) into frozen source bytes with verified lineage and an editable data preview. Copy snapshot into create_recipe_draft and preserve unedited fields. Defaults are not a validated model. Does not create, publish or run anything.
| Name | Required | Description | Default |
|---|---|---|---|
| family | No | mmm | |
| uploaded_file_id | No | ||
| pipeline_version_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only, idempotent, and non-destructive behavior. The description adds valuable behavioral context beyond annotations: 'Defaults are not a validated model,' the notion of 'frozen source bytes with verified lineage and an editable data preview,' and an explicit 'Does not create, publish or run anything.' No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the primary purpose first, then optional parameters, then downstream usage, then caveats. Each sentence adds information, though the phrasing 'Get complete shared wizard defaults, hash and envelope schema' is slightly dense and jargon-heavy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations and the presence of an output schema, the description covers the essential behavioral and usage details: no side effects, non-validated defaults, source object selection constraints, and the intended downstream call. The main missing piece is family semantics, but the optional parameters and output schema reduce the need for exhaustive return-value documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must compensate. It explains the two optional source parameters and their mutual exclusion ('uploaded_file_id or pipeline_version_id (never both)'), but it does not explain the 'family' parameter, its enum values (mmm/var), or how it affects the returned defaults. This is a meaningful gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get complete shared wizard defaults, hash and envelope schema.' It distinguishes itself from siblings by explicitly stating 'Does not create, publish or run anything' and by referencing create_recipe_draft, making the tool's role as a template/input source clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides practical usage guidance, including 'Optionally choose an owned uploaded_file_id or pipeline_version_id (never both)' and 'Copy snapshot into create_recipe_draft and preserve unedited fields.' It clearly implies when this tool fits in the workflow, though it does not explicitly compare against alternatives like get_recipe_draft or get_recipe_revision_authoring.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipe_revisionGet Recipe RevisionARead-onlyIdempotent
Read one exact immutable recipe revision.
| Name | Required | Description | Default |
|---|---|---|---|
| number | Yes | ||
| recipe_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds the 'immutable' property, which informs the agent that the returned data is stable and won't change, providing useful context beyond the structured hints. No contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with zero filler. It conveys the essential purpose in six words, making it exceptionally concise and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and an output schema exists to document return values, while annotations cover behavioral safety. However, the description omits parameter explanations, which is a notable gap given the 0% schema coverage. Despite the self-explanatory parameter names, the description alone is minimally adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meaning. However, the description does not explain that recipe_id identifies the recipe and number is the revision number. While the parameter names are self-explanatory, the description adds no explicit clarification, leaving the agent to infer semantics from names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('read') and resource ('one exact immutable recipe revision'). It distinguishes itself from sibling tools like get_recipe_draft and list_recipe_drafts by emphasizing 'exact' and 'immutable', making it unambiguous which operation is intended.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving a specific, immutable revision, but it does not explicitly state when to use this tool versus alternatives like get_recipe_draft or list_recipe_drafts. The context is clear but not contrasted with exclusions, so it relies on inference rather than explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipe_revision_authoringGet Recipe Revision AuthoringARead-onlyIdempotent
Read the frozen authoring snapshot of a published draft revision. Use its complete snapshot with create_recipe_draft to edit a new copy; the published revision stays unchanged. Legacy revisions without authoring state return an explicit unavailable error. Does not create or fit anything.
| Name | Required | Description | Default |
|---|---|---|---|
| number | Yes | ||
| recipe_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the annotations: the snapshot is frozen, the published revision remains unchanged, legacy revisions without authoring state return an explicit unavailable error, and the tool does not create or fit anything. This meaningfully informs an agent about side effects, limits, and error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core read action, and each sentence serves a distinct purpose: describing the resource, giving the primary usage workflow, and noting error behavior. There is no padding or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations already indicate read-only, idempotent behavior, the description covers the main usage flow and an important edge case (legacy revisions). It could be slightly more explicit about what 'authoring state' means and how the snapshot maps to create_recipe_draft, but overall it is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the undocumented recipe_id and number parameters. It indirectly implies that 'number' refers to a revision number and that 'recipe_id' identifies the recipe, but it never explicitly defines either parameter's meaning, format, or relationship to the returned snapshot.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action ('Read a frozen authoring snapshot') and a specific resource type ('published draft revision'), and explicitly distinguishes itself from mutating or creating tools with 'Does not create or fit anything.' This clearly separates it from siblings like get_recipe_revision while stating its scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies that the snapshot should be used with create_recipe_draft to edit a new copy, giving an explicit workflow and intended context. It also warns about legacy revisions returning an unavailable error, but it does not name alternative tools for cases where authoring state is not needed, such as get_recipe_revision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scenario_resultsGet Scenario ResultsARead-onlyIdempotent
Get scenario prediction results.
Without run_id: returns the MODEL-LEVEL scenario state — status (pending/complete/failed) and, when complete, the full prediction data including predicted KPI per period, channel contributions, confidence intervals, and base components (intercept, seasonality, trend). This reflects the LATEST scenario on the model — a newer run overwrites it, so a poller can lose sight of the run it submitted.
With run_id (run_scenario's response includes it): fetches that specific
saved run, immune to later runs — keys include run_id, model_hash,
name, status, pinned, notes, tags, key_metrics, timestamps,
inputs (the submitted payload), and results. Poll THIS form when you
need to know whether your own run completed, or to disambiguate
back-to-back scenarios.
NOTE: Failed scenarios return status "failed" with an error message in the JSON body (not an HTTP error). Always check the status field.
Args: model_hash: Hash of the model the scenario was run on. run_id: Optional scenario run id ("scn_..."), from run_scenario's response or list_runs(artifact="scenario").
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | No | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and non-destructive behavior. The description adds meaningful behavioral context beyond these: a newer run overwrites the latest scenario, and failed scenarios return an HTTP 200 with status 'failed' plus an error message in the body, so callers must check the status field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but earns its length: mode-by-mode behavior, a critical failure-mode note, and an Args block. The core distinction between the two forms is front-loaded, and every section adds necessary information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so detailed return-value documentation is unnecessary. For a two-mode polling tool, the description covers overwrite semantics, failure representation, run_id provenance, and when to use each form, leaving no practical gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains model_hash as the hash of the model the scenario was run on, and defines run_id's format ('scn_...') plus where to obtain it: from run_scenario's response or list_runs(artifact='scenario'). This fully covers both parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pairing ('Get scenario prediction results') and then defines two distinct behaviors: model-level latest state versus a specific saved run identified by run_id. This clearly distinguishes it from run_scenario and list_runs, which are the most related siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the condition for each invocation form: without run_id returns the latest scenario state with overwrite risk, while with run_id fetches a specific saved run. It also says directly, 'Poll THIS form when you need to know whether your own run completed, or to disambiguate back-to-back scenarios,' which is unambiguous usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scenario_templateGet Scenario TemplateARead-onlyIdempotent
Generate a forward-period scenario template from a completed model.
Returns future dates pre-filled with values from 1 year prior, the list of media and control channels, and average cost-per-unit per media channel.
IMPORTANT: Always call this before run_scenario or run_optimizer to discover:
Channel names (use these exact names in scenario_data, bounds, laydown_weights, period_cpm)
Average CPM per channel (avg_cpu_by_channel — use for period_cpm in run_optimizer)
Baseline activity values per channel (rows — use as starting point for scenarios)
Media vs control channel classification (variable_classification field)
The response also includes: operating_margin (the model's stored margin, if set — useful for profit math), variable_transforms (per-variable transform metadata), periodicity, and start_date.
WARNING: Template data may contain NaN or null values for channels without historical data. You MUST replace NaN/null with 0 before passing to run_scenario, otherwise the prediction will fail downstream.
Args: model_hash: Hash of a completed model. periods_forward: Number of future periods to generate (default 12).
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes | ||
| periods_forward | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the readOnlyHint and idempotentHint annotations by warning that template data may contain NaN/null values that must be replaced with 0 or the prediction will fail. It also discloses the presence of operating_margin, variable_transforms, and periodicity, adding behavioral context not available from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but well organized: a purpose sentence, response contents, an IMPORTANT block, a warning, and an Args section. There is minor redundancy between the initial response summary and the later IMPORTANT enumeration, but each section adds useful information and the critical usage directive is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter tool with an output schema, this description covers prerequisites (completed model hash), intended call order, return fields, NaN handling, and parameter defaults. Nothing critical for invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description compensates by defining model_hash as 'Hash of a completed model' and periods_forward as the number of future periods to generate with a default of 12. This adds some meaning beyond the bare schema types, though the model_hash explanation remains somewhat terse.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action — 'Generate a forward-period scenario template from a completed model' — and immediately differentiates itself from sibling execution tools by naming run_scenario and run_optimizer. The description also itemizes the template's contents, so an agent understands exactly what resource is produced.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit directive: 'IMPORTANT: Always call this before run_scenario or run_optimizer to discover...' This clearly states when to use the tool. It also enumerates what information to extract (channel names, average CPM, baseline rows, classification) and warns about downstream failure, which is strong pragmatic guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_studyGet StudyARead-onlyIdempotent
Read a study and its optimistic concurrency version.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds useful context by mentioning the optimistic concurrency version, which is relevant for subsequent update operations. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. Every phrase earns its place, and the concurrency-version detail is packed in without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple one-parameter read operation with strong annotations and an output schema, so the description does not need to explain return structure. It is mostly complete, though explicitly connecting study_id to the study selection would remove the only remaining ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain study_id beyond the generic 'a study.' While the parameter name and title are fairly self-evident, the description adds no detail about the ID format, requiredness, or how the concurrency version relates to it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read') and resource ('study'), and adds that the tool returns the study's optimistic concurrency version. This clearly distinguishes it from siblings like list_studies (which lists) and get_study_run (which reads a run, not a study).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Read a study' framing makes it clear this is for retrieving a single study by ID, implicitly separating it from list_studies and study-run-level tools. However, it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_study_championGet Study ChampionARead-onlyIdempotent
Read incumbent, eligibility blockers, accepted candidates and immutable champion history. Stale champions retain their historical role with review_required. Reported holdout use that informed a candidate revision blocks that revision pending fresh validation; holdout_use lists the declaration IDs. Ordinary viewing does not block. Current analyst-reviewed validation resolutions can clear the exact run acceptance; changed evidence or revoked review reblocks it. Recorded revision ancestry inherits influence. Validation references are reviewer-declared; decision_grade_ready is false until independently qualified. Selection/replacement/revocation require an owner frontend session; MCP cannot promote models.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds substantial behavioral nuance: stale champion handling, holdout-use blocking, validation resolution effects, reviewer-declared references, and the frontend-session limitation. It enriches the agent's understanding of data semantics beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but not bloated. It front-loads the core purpose in the first sentence, then layers important caveats and constraints. Each sentence adds information relevant to correct invocation or interpretation. It is appropriately concise for the amount of behavioral detail it conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not required. The description covers the key data aspects (incumbent, blockers, candidates, history) and important edge cases (stale champions, holdout blocking, validation resolutions, session limitations). It is complete enough for an agent to understand what this tool returns and the conditions that affect its results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the tool description must compensate. It does not mention study_id at all, leaving the agent to infer its meaning from the parameter name. For a read tool with a single obvious parameter, the lack of explicit explanation is a minor gap, but given the low coverage, the description fails to add any value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'Read incumbent, eligibility blockers, accepted candidates and immutable champion history.' This precisely states what the tool returns and distinguishes it from other study-related tools like get_study or get_study_run by focusing on the champion concept. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides behavioral context (e.g., 'Ordinary viewing does not block', 'Selection/replacement/revocation require an owner frontend session') that implies this is a read-only query tool. However, it never explicitly names alternative tools or states when to prefer this over a sibling like get_study. Usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_study_prediction_accessGet Study Prediction AccessARead-onlyIdempotent
Read partial prediction-access history for this run and matching recorded dataset/windows in this study. Does not expose predictions or add access events. Earlier activity, other result routes and offline work are not covered; absence never proves untouched holdout status. Repeated access does not prove retuning.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior, and the description adds substantial value beyond them: it confirms the absence of side effects, discloses coverage blind spots, and provides interpretive caveats about what the data can and cannot prove. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each earning its place: core purpose, negative behavior, coverage limits, and interpretation caveat. The most important information is front-loaded and there is zero redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a compliance-relevant read tool with rich annotations and an output schema present, the description is remarkably complete. It covers the critical interpretive pitfalls (absence of history doesn't prove holdout untouched; repeated access doesn't prove retuning) which is exactly the context an agent needs. Return structure is covered by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It does so by clarifying that run_id identifies 'this run' and that the access history is scoped to the run plus matching recorded dataset/windows in the study. It doesn't detail the run_id format, but for a single obviously-named required parameter this is adequate compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read'), a specific resource ('partial prediction-access history'), and precise scope ('for this run and matching recorded dataset/windows in this study'). It also distinguishes itself from siblings by stating what it does not do ('Does not expose predictions or add access events'), differentiating it from tools like declare_study_holdout_use.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context about what the tool covers and, importantly, what it does not cover ('Earlier activity, other result routes and offline work are not covered'). It implies when not to rely on it ('absence never proves untouched holdout status'), but it does not explicitly name alternative tools or state direct when-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_study_runGet Study RunARead-onlyIdempotent
Read durable run status and the linked model.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds that the tool returns durable status and the linked model, which is useful context, but it does not clarify what 'durable' means or describe other behavioral constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single focused sentence with no filler. The core action and key output are front-loaded, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with strong annotations and an output schema, this is nearly complete. The only slight gap is the ambiguity of 'durable' and the lack of any link to the broader study context, but the agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter, run_id, with 0% description coverage, and the tool description does not compensate by explaining the parameter's meaning, format, or source. The property name is self-evident, but the description adds no value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Read') with a clear object ('durable run status') and a distinct output ('the linked model'). This differentiates it from sibling getters like get_model_status or list_study_runs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives. The sibling list includes several related read tools, but the description does not name them or state any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_study_validation_resolutionsGet Study Validation ResolutionsARead-onlyIdempotent
Read analyst validation resolutions and revocations, including current/stale/revoked status re-evaluated against exact evidence. API keys cannot supply human independence sign-off or revoke it; use the signed-in owner UI. No audit serving event is added and no model is fitted or promoted.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, but the description adds valuable behavioral details beyond that: no audit serving event is added, no model is fitted or promoted, and statuses are re-evaluated against exact evidence. It also clarifies the human-only nature of sign-off and revocation. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three purposeful sentences with the primary action front-loaded. Each sentence adds distinct value: the read scope, the human-only limitation, and the side-effect guarantees. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, rich annotations, and a single obvious parameter, the description covers purpose, side effects, and usage limitations well. The only meaningful gap is that study_id is undocumented in both the schema and the description, which slightly reduces completeness for an agent encountering this tool cold.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and there is one required parameter, study_id. The description does not mention study_id at all, nor does it explain what values are valid or how the parameter scopes the returned resolutions. The parameter name is self-evident, but the description does not compensate for the missing schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read analyst validation resolutions and revocations'. It also clarifies the scope with 'current/stale/revoked status re-evaluated against exact evidence', which distinguishes it from nearby assessment or evaluation tools like assess_study_validation_pair or list_study_evaluations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear when-not boundary: 'API keys cannot supply human independence sign-off or revoke it; use the signed-in owner UI.' This tells an agent not to attempt sign-off or revocation through this API. However, it does not explicitly compare this tool to sibling MCP tools for reading validation data, so it stops short of full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_uploadGet UploadARead-onlyIdempotent
Get one uploaded dataset's details, including its column schema.
Returns id, filename, original_filename, source_type, mime_type, file_size, row_count, column_count, columns ([{name, dtype}, ...] — use these to build create_model's channel/control column arguments without re-reading the CSV), and created_at.
Args: file_id: The upload's id, from upload_data's response or list_uploads.
| Name | Required | Description | Default |
|---|---|---|---|
| file_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds useful non-obvious context: it returns a structured column schema and that this avoids re-reading the CSV for model building. This goes beyond what annotations alone provide without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose, followed by a compact return list and a clear Args section. Despite listing many fields, every sentence earns its place because it helps the agent know exactly what will be returned and how to use it. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter, the safe-read annotations, and the rich output schema, the description is complete for tool selection and invocation. It explains the parameter source, the return contents, and the downstream use case, leaving no practical gap for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only 'integer' and 'File Id' with 0% description coverage, so the description must carry the semantics. It does: 'The upload's id, from upload_data's response or list_uploads.' This fully explains the parameter's meaning and provenance, which is exactly what an agent needs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Get one uploaded dataset's details, including its column schema.' This clearly distinguishes it from list_uploads (which lists uploads) and upload_data (which creates an upload). The resource and output are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when this tool is useful: it explains that the returned columns can be used to build create_model's channel/control arguments without re-reading the CSV. It also specifies where to obtain file_id (from upload_data or list_uploads). It stops short of naming alternatives or explicit when-not-to-use cases, so it does not earn a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_study_runLaunch Study RunAIdempotent
Launch a frozen revision within study attempt/concurrency budgets. Requires an active study, immutable executable revision and same-study policy. Budget/state conflicts require inspection, not a new attempt key. Reuse the same submission_key after an ambiguous response; never invent another key for a retry.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes | ||
| policy_id | Yes | ||
| revision_id | Yes | ||
| submission_key | Yes | Caller-generated 8-128 character identity for one intentional attempt. Reuse identical key and inputs after a lost response; a new key may consume another attempt. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and readOnlyHint=false, and the description adds concrete behavioral detail beyond that: reuse the same submission_key after an ambiguous response and never invent another key. It also discloses conflict handling ('Budget/state conflicts require inspection') and prerequisites that annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four dense sentences with no filler. The core purpose is front-loaded, and each sentence adds a distinct operational constraint: prerequisites, conflict handling, and idempotent retry behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering idempotency/side-effect characteristics, the description covers the remaining essentials: prerequisites, budget/state conflict guidance, and retry semantics. Nothing critical is missing for an agent deciding whether and how to call this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only the submission_key parameter has schema documentation (25% coverage), but the description supplies meaning for the others: 'active study' qualifies study_id, 'immutable executable revision' defines revision_id, and 'same-study policy' constrains policy_id. This partially compensates for the sparse schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and object: 'Launch a frozen revision within study attempt/concurrency budgets.' It also adds distinguishing constraints (active study, immutable executable revision, same-study policy) that separate this from generic run tools like run_scenario or run_optimizer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists prerequisites: 'Requires an active study, immutable executable revision and same-study policy.' It also gives direct when-to-use and when-not-to behavior: budget/state conflicts require inspection rather than a new attempt key, and the same submission_key must be reused after an ambiguous response.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
link_var_modelLink Var ModelADestructive
Link a completed VAR model to an MMM (#569).
After linking, the MMM's get_model_results long_run_rollup section
joins the VAR's long-run elasticities with the MMM's short-term revenue.
A VAR links to at most one MMM at a time — the error names the current
owner if it is already linked elsewhere.
The join is by exact name unless channel_map declares which MMM channels each VAR exogenous series stands for (#682) — required whenever the VAR is fitted on group spends (e.g. four spend groups) while the MMM is tactic-level. Each group's elasticity is allocated across its member channels pro-rata by KPI short-term contribution, so the group's long-run effect is counted exactly once. Validation is strict: keys must be VAR exogenous series, values must be channel names of the (completed) MMM, and no channel may belong to two groups. The map belongs to the link: every link replaces it (omitting channel_map clears any stored map) and unlink clears it.
Args: model_hash: The MMM to attach the long-run view to. var_model_hash: The VAR model (from create_var_model). channel_map: Optional {var_exogenous_series: [mmm_channel, ...]} mapping for group-level VARs.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes | ||
| channel_map | No | ||
| var_model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal destructive and non-idempotent behavior, but the description goes far beyond them: it explains the post-link effect on get_model_results, the at-most-one-MMM constraint, the error behavior naming the current owner, strict validation rules, channel_map replacement semantics, and clearing on unlink. This is rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but structured and front-loaded with the core purpose before diving into details. Every sentence adds operational value, though the depth of detail around channel_map and validation makes it denser than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a linking tool with destructive semantics and non-trivial validation, the description covers the full context: prerequisites, result effects, constraints, error behavior, parameter semantics, and state lifecycle. The existing output schema covers return value details, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full responsibility. It clearly defines model_hash as the MMM to attach to, var_model_hash via create_var_model, and channel_map with its type, purpose, validation rules, and lifecycle. The description compensates completely for the sparse schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource: 'Link a completed VAR model to an MMM'. This clearly distinguishes it from the sibling unlink_var_model and other model-management tools. The subsequent explanation of what linking does to results makes the tool's role unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when linking is appropriate, including the one-link-per-VAR constraint and the channel_map requirement for group-level VARs. It mentions 'unlink clears it', implicitly pointing to the sibling unlink tool, though it never explicitly instructs the agent to use unlink_var_model for removal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_modelsList ModelsARead-onlyIdempotent
List all Marketing Mix Models for the authenticated user.
Returns model name, hash, status (pending/under way/complete/failed), type (mmm/var), hierarchy value, and timestamps.
NOTE: All other model endpoints use model_hash (string, e.g. "f835671a25") as the identifier. Use the model_hash from this response.
Args:
include_unsaved: Include draft/unsaved models (default false).
limit: Maximum number of models to return (default 50, max 500).
offset: Number of models to skip, for paging past limit (default 0).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| include_unsaved | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful behavioral detail beyond the annotations: it lists the returned fields, statuses, type values, hierarchy value, and timestamps, and explains the hash convention across related endpoints. This gives the agent a meaningful picture of what to expect without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured and front-loaded: purpose first, then return values, then the critical identifier note, then parameter documentation. Every sentence adds value, and the Args block is concise and directly useful. No redundant fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list endpoint with an output schema and comprehensive annotations, the description is complete. It explains the authenticated-user scope, the key fields returned, the model_hash convention that matters for all downstream calls, and all pagination and filtering parameters. Nothing an agent needs to invoke this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden for parameter semantics. It fully compensates by explaining include_unsaved as 'draft/unsaved models', limit as 'maximum number to return' with a max of 500, and offset as 'number of models to skip, for paging past limit.' This goes well beyond the bare schema properties.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List all Marketing Mix Models for the authenticated user.' This clearly identifies the operation and scope, and the resource name differentiates it from sibling list_* tools such as list_studies, list_uploads, and list_projects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context by explaining that all other model endpoints use model_hash and instructing the agent to use the model_hash from this response. It does not explicitly name alternative tools or when-not-to-use conditions, but the hash-identifier guidance strongly implies this tool is the entry point for model operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsList ProjectsARead-onlyIdempotent
List the projects (the app's model folders) you can file models into.
Returns owned and team-shared projects: per project {id, name, is_default, shared_with_team_id, model_count} — team-shared folders carry "shared": true, and model_count counts SAVED models (the set the app's model list shows). Use the ids with save_model(project_id=...) and rename_project. There is deliberately no delete over the API — use the app to delete a project.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent, so the safety profile is covered. The description adds semantic detail: team-shared folders carry 'shared': true, and model_count counts only SAVED models (the set the app's model list shows). It also discloses an intentional API limitation (no deletion), going beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact block that front-loads the core purpose in the first line, then efficiently provides output shape, field meanings, usage pointers, and a limitation. Each sentence adds distinct information and none are redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless listing tool with an output schema, the description explains the return fields and their interpretation (e.g., model_count counting SAVED models), and connects to related tools. The only remaining context lies in the output schema itself, which is provided separately, so nothing needed by an agent is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema describes all parameters (none) and there is nothing for the description to add about inputs. Per the 0-param baseline, a score of 4 is appropriate; the description instead clarifies the return payload semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List the projects (the app's model folders) you can file models into.' It distinguishes projects from other entities by framing them as model folders, and the return format clarifies this is a read-only list tool, separate from list_models and similar siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states that the returned ids should be used with save_model and rename_project, giving an immediate use case. It also notes there is no delete over the API, telling agents to use the app instead. It doesn't explicitly contrast with sibling list tools, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_quality_policiesList Quality PoliciesARead-onlyIdempotent
Read immutable quality policies for the study.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the domain fact that quality policies are 'immutable', which is useful, but it does not explain return behavior, ordering, or how policies come to exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one short sentence with no wasted words. The verb 'Read' is front-loaded, and the resource and scope are stated immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one required parameter, an output schema, and safety annotations, the description is nearly complete. It identifies the resource, the scope, and the immutability of the returned policies. The only real gap is that it does not point the agent to `create_quality_policy` for creating policies, but that is a usage-guidance concern rather than a critical invocation blocker.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It maps the action to 'the study', which corresponds to `study_id`, but does not explain where the ID comes from or how it is validated. The single parameter is self-evidently the study identifier, so minimal compensation is acceptable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('Read'), resource ('quality policies'), and scope ('for the study'). It is immediately distinguishable from the sibling `create_quality_policy` by virtue of the read/creation contrast, and no other sibling reads quality policies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the verb 'Read' and the scope 'for the study', but there is no explicit guidance such as 'use when you need to view policies; use create_quality_policy to create them.' The description does not mention alternatives or exclusions, so the agent must infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_recipe_draftsList Recipe DraftsARead-onlyIdempotent
List study draft metadata without loading datasets. Check backend draft capability first.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds value by noting it does not load datasets (scope limitation) and that it requires checking backend capability first, which is useful behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the core action and limitation. Every word earns its place; no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a simple input schema (one required parameter) and rich annotations, so the description is nearly complete. The mention of checking backend capability is a useful prerequisite, and the limitation about not loading datasets is clear. The only minor gap is lack of detail on the return format, but an output schema exists, so this is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the undocumented parameter. The description does not add any specific meaning to the 'study_id' parameter beyond what the schema provides (it's a required string). However, the description implies the parameter identifies the study for which drafts are listed, which is a minimal addition but still leaves the parameter semantics largely unspecified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states it lists study draft metadata without loading datasets, which clarifies the tool's scope and distinguishes it from tools that load full datasets. However, it does not explicitly name sibling alternatives like get_recipe_draft or create_recipe_draft, so differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions checking backend draft capability first, which provides some usage context, but it does not specify when to use this tool versus alternatives or when not to use it. No explicit guidance on selecting between list_recipe_drafts and other list/get tools is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_runsList RunsARead-onlyIdempotent
List a model's saved optimizer or scenario run history.
Returns {model_hash, runs, count, limit, offset}. Each run summary has: run_id, name, auto_named, pinned, notes, tags, status, error_details, progress fields while running, key_metrics (optimizer: total_budget, num_periods, gamma, predicted_revenue/roi, ...; scenario: num_periods, total_planned_spend, predicted_outcome, ...; null metrics are omitted — treat every key as optional), and created/started/completed timestamps. Ordering is pinned-first, then newest-first.
CAVEATS:
countis the LENGTH OF THIS PAGE, not the total run count — page until a short page.The optimizer objective ("revenue"/"profit") is NOT in the summary; fetch the specific run (get_optimizer_results with run_id) and read its
inputs— profit runs carryobjective: "profit"there, revenue runs omit the key.
Use get_optimizer_results / get_scenario_results with a run_id to fetch a listed run's full inputs and results; update_run / set_run_pinned to curate it.
Args: artifact: "optimizer" (run ids "opt_...") or "scenario" ("scn_..."). model_hash: Hash of the model whose run history to list. limit: Page size (API clamps to 1-200; default 50). offset: Rows to skip (paging).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| artifact | Yes | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description discloses important behavior: count is only the page length, ordering is pinned-first then newest-first, null metrics are omitted, and the optimizer objective is intentionally absent from summaries. These details prevent incorrect assumptions during use.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but tightly organized: a clear purpose, a structured return-value breakdown, explicit caveats, and a compact args section. Every sentence provides actionable information, and the caveats are prominently separated rather than buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the operation's scope, return shape, field semantics, paging pitfalls, missing-data caveats, and relationships to sibling tools. Even with an output schema present, it supplies enough context for an agent to call the tool correctly without further exploration.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description fully compensates: artifact is explained with expected prefixes ('optimizer' for 'opt_...', 'scenario' for 'scn_...'), model_hash is defined as the model whose history to list, limit includes clamping behavior and default, and offset explains paging. This adds meaningful semantic value absent from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List a model's saved optimizer or scenario run history.' It clarifies this is a listing operation that returns run summaries, not full results, which distinguishes it from sibling tools like get_optimizer_results and get_scenario_results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes the agent to alternatives: 'Use get_optimizer_results / get_scenario_results with a run_id to fetch a listed run's full inputs and results; update_run / set_run_pinned to curate it.' It also provides paging guidance with the caveat to page until a short page, making the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_studiesList StudiesBRead-onlyIdempotent
List project-owned studies, questions, budgets and access rights.
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds some behavioral scope by indicating the listing includes questions, budgets, and access rights, but it does not disclose pagination, permission requirements, or other runtime behavior. With strong annotations, this is adequate, not exceptional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence carries the core purpose and scope with no filler. The action is front-loaded and the object list is compact, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only one-parameter tool with an output schema and strong annotations, the definition is nearly sufficient. However, it lacks usage guidance versus sibling listing tools and leaves the parameter semantics to inference, so there are clear gaps an agent must resolve elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needs to add meaning to project_id. The phrase 'project-owned' loosely implies the parameter filters by owning project, but it does not explain the expected integer's source (e.g., from list_projects), format, or any constraints. This is insufficient compensation for an undocumented parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a concrete verb ('List') and names the resource ('studies') plus additional returned categories ('questions, budgets and access rights'). It clearly identifies project-owned scope, which differentiates it from create_study/get_study, though it doesn't explicitly name those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any when-to-use guidance or explicitly contrast with sibling list tools like list_study_recipes, list_study_runs, or list_recipe_drafts. The only hint is 'project-owned' and the required project_id, which implies a project-scoped listing but gives no exclusions or alternative conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_study_decisionsList Study DecisionsBRead-onlyIdempotent
Read analyst decisions and agent recommendations.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds some content context by specifying that the read returns analyst decisions and agent recommendations, but it does not disclose ordering, scoping behavior, or other runtime caveats. Given the annotations, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single eight-word sentence with no filler. It front-loads the operation and identifies the key content types, making it appropriately sized for a simple read tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is low-complexity: one required parameter, strong safety annotations, and an output schema is present, so return value details need not be in the description. The main gap is a lack of explicit differentiation from sibling decision-related tools, but the description and schema together give an agent enough to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate by explaining study_id, but it never does. The phrase 'study decisions' weakly implies the study scoping, and the parameter name is self-explanatory, but no actual parameter semantics are added beyond the input schema. With low coverage, this compensation is required and missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies a read operation ('Read') over a specific resource ('analyst decisions and agent recommendations'), which goes beyond the title by naming two content types. An agent can distinguish it from list_studies and similar list tools. It does not explicitly contrast with siblings, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. The sibling list includes recommend_study_run, get_study_validation_resolutions, and compare_study_runs, but the description does not explain why list_study_decisions is the appropriate choice or when another tool would be better. This is effectively no usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_study_evaluationsList Study EvaluationsB
Read preserved quality reports and evidence hashes. Serving available prediction reports appends access audit events.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a meaningful behavioral trait: 'Serving available prediction reports appends access audit events.' This goes beyond the annotations by explaining why the operation is not purely read-only. It adds useful context about side effects beyond what readOnlyHint=false already implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the primary read action. The second sentence is somewhat terse and awkwardly worded, but there is no unnecessary filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter list/read tool with an output schema, the core action and the audit side effect are stated, which makes the tool minimally usable. However, it lacks usage guidance and any parameter elaboration, leaving clear gaps in the context an agent needs to confidently select and invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter run_id has no description in the schema, and the tool description never mentions it. While the name is fairly self-explanatory, the 0% schema description coverage means the description should compensate, and it does not clarify expected format, meaning, or scope.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read preserved quality reports and evidence hashes,' which clearly indicates a read/list operation on study evaluation artifacts. However, it does not explicitly differentiate this tool from siblings like list_study_decisions or get_study_run, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives, no preconditions, and no exclusions. The second sentence mentions a side effect of serving reports but does not help an agent decide when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_study_recipesList Study RecipesARead-onlyIdempotent
Read all recipe revisions including exact effective priors, settings and data hashes. Raw datasets are omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnly, idempotent, and non-destructive. The description adds what the response includes (effective priors, settings, data hashes) and explicitly states raw datasets are omitted, which is helpful behavioral context beyond the schema. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the verb and scope, followed by a precise inclusion/exclusion statement. No filler or repetition of annotation hints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With rich annotations, an output schema, and a single obvious parameter, the description is nearly sufficient for correct invocation. It covers scope, content, and the raw-dataset exclusion. Minor gaps remain: no ordering/pagination note and no explicit relationship to the recipe-draft tools, but these are not required for a basic read-only list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only study_id with no description (0% coverage), and the description never explains what study_id refers to or how it shapes the returned revisions. The parameter is simple and self-descriptive, but the description adds no parameter-level meaning and does not compensate for the schema's lack of documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Read all recipe revisions,' a specific verb and resource, and clarifies scope ('all') and content ('exact effective priors, settings and data hashes'). The explicit exclusion of raw datasets prevents confusion with upload/list_uploads tools. It distinguishes from sibling list_recipe_drafts by focusing on revisions rather than drafts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for reading the full set of recipe revisions for a study, and the 'Raw datasets are omitted' sentence gives one boundary, but it never explicitly states when to prefer this over get_recipe_revision or list_recipe_drafts, nor does it name alternatives. Usage must be inferred from the tool name and purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_study_runsList Study RunsARead-onlyIdempotent
List preserved attempts including pending and failed runs. Supporting backends also return budget with attempts remaining, available slots and blocking reasons. Missing budget means unknown support, not permission to launch. Capacity is rechecked on reservation; recover an uncertain launch with its original submission key.
| Name | Required | Description | Default |
|---|---|---|---|
| study_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish read-only, idempotent, and non-destructive behavior, while the description adds substantial non-obvious semantics: budget presence is backend-dependent, missing budget means unknown support rather than permission, and capacity is rechecked at reservation. This is exactly the kind of behavioral context that annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler and the core purpose front-loaded. The budget and capacity details are packed efficiently, though the final sentence about recovering an uncertain launch is somewhat tangential to the act of listing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list operation with one input parameter and an output schema, the description covers the essential scope and the most important non-obvious behaviors. It is complete enough to invoke correctly, though it leaves the relationship to sibling tools like list_runs implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not mention study_id at all, so no parameter-level meaning is added beyond the input schema. The single parameter is self-explanatory from its name and schema title, which softens the gap, but the description still fails to compensate for low schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'List preserved attempts including pending and failed runs.' This clearly distinguishes it from single-run tools like get_study_run, but it does not explicitly name a sibling alternative, so it falls just short of a top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus alternatives such as list_runs or get_study_run. The budget and capacity notes explain how to interpret results, not when this tool should be chosen.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_uploadsList UploadsARead-onlyIdempotent
List the datasets in your workspace (newest first) — every source, not just API uploads: dashboard/manual uploads and pipeline-ingested datasets appear too (see source_type per file).
Returns {files, count, limit, offset} where each file has: id (the
uploaded_file_id create_model needs), filename, original_filename,
source_type, row_count, column_count, created_at. Here count IS the
true total matching the filter (unlike list_runs, where it is the page
length). Column names/dtypes are not in the listing — fetch one upload
with get_upload for those.
Args: limit: Page size (API clamps to 1-500; default 50). offset: Rows to skip (paging). name: Optional case-insensitive substring filter on the original filename.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false. The description goes well beyond these by revealing behavioral specifics: the ordering, the inclusion of non-API sources, the true count semantics, pagination behavior (limit/offset), and the omission of column details. No contradiction exists; the description adds significant value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: it opens with the core purpose, then covers the return shape and key behavioral differences, and finally lists parameters. Every sentence adds value—there is no fluff. The contrast with list_runs and the pointer to get_upload are concise and purposeful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema is present (has_output_schema: true) and the description already details the return structure, pagination, filtering, and caveats, the definition is complete for an agent to call this tool correctly. It even points to get_upload for missing details, covering all likely follow-up needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden of explaining parameters. It does so explicitly: 'limit: Page size (API clamps to 1-500; default 50)', 'offset: Rows to skip (paging)', and 'name: Optional case-insensitive substring filter on the original filename.' This fully compensates for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a specific resource ('datasets in your workspace'), and an ordering ('newest first'). It also clarifies the scope ('every source, not just API uploads') and explicitly contrasts with list_runs regarding count semantics, which distinguishes it from a sibling tool without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (to list uploads) and provides a clear alternative for a specific need: 'fetch one upload with get_upload for those' when column names/dtypes are required. It also contrasts with list_runs on the meaning of 'count', which is helpful for routing. However, it does not explicitly state 'use this when you need to list uploads' or list exclusions for other scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_recipe_draftPublish Recipe DraftAIdempotent
Publish a saved MMM or VAR draft as immutable recipe revisions. Supply a new UUID publication_id and reuse it with identical arguments after an uncertain response. Batch publication is atomic. Backend compiles the saved snapshot with shared wizard rules; never send separately prepared settings. Does not fit, consume an attempt or designate a champion. On capable backends, automatic MMM priors are resolved at publication and frozen; replay does not rebuild them. VAR requires family-specific evidence assessment; MMM policies cannot establish VAR acceptance. Enabled invalid MMM calibration fails publication; VAR calibration is unsupported. Preserve disabled authoring observations. Check backend capabilities.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| draft_id | Yes | ||
| publication_id | Yes | ||
| expected_version | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal idempotency, open-world behavior, and non-read-only semantics, and the description adds substantial context: immutable revisions, atomic batch publication, snapshot compilation, frozen MMM priors on capable backends, VAR evidence requirements, invalid-calibration failure, and preservation of disabled observations. No contradiction with annotations was found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded and most caveats are relevant, but the description is a dense block of domain warnings and includes an unclear fragment ('Does not fit, consume an attempt or designate a champion'). It is compact but not cleanly structured or fully readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given openWorldHint and the tool's complexity, the description does cover backend-capability differences, idempotent replay, atomicity, and MMM/VAR-specific constraints. However, required parameters like expected_version and reason remain unexplained, and the garbled exclusion sentence adds ambiguity, so the description is not complete on its own.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must explain the required parameters, but it only gives real semantics to publication_id ('new UUID', reuse after uncertain response) and only implicitly refers to the saved draft. The roles of expected_version and reason are not explained at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence clearly states the action and resource: publishing a saved MMM or VAR draft as immutable recipe revisions. This distinguishes it from draft creation/update tools, though it does not explicitly name sibling tools, and the later sentence 'Does not fit, consume an attempt or designate a champion' is garbled and weakens precision.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful context for when to use the tool: saved drafts, idempotent retry with the same publication_id, never sending separately prepared settings, and checking backend capabilities. It does not explicitly name alternatives or state when not to use this tool, and the exclusion phrase is unclear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_study_runRecommend Study RunA
Record a recommendation with evidence. This does not accept or promote a model; analyst acceptance happens in the frontend.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| run_id | Yes | ||
| study_id | Yes | ||
| evaluation_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations by clarifying that the write operation only records a recommendation and does not itself accept or promote, which is a non-obvious behavioral trait. Annotations already flag readOnly=false, idempotent=false, and destructive=false, and the description does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences deliver the core action and the key exclusion with no filler. The most decision-relevant constraint—'does not accept or promote'—is clearly stated after the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering side-effect flags, the tool is not wildly under-specified: an agent can tell it records a recommendation for a study run with evidence. However, because the parameters are undocumented, the workflow context—such as which evaluation/run IDs are valid and how this relates to adoption—is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description only loosely hints that 'reason' should carry evidence. The three identifier parameters (study_id, run_id, evaluation_id) and their relationships are left entirely to name inference, so the description does not sufficiently compensate for the lack of schema property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a concrete action—record a recommendation—with the object 'with evidence,' and explicitly marks what the tool does not do (accept or promote a model), which separates it from adoption/promotion siblings. It relies on the title for the 'study run' context, but the verb-resource pairing is specific enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The statement 'analyst acceptance happens in the frontend' gives an explicit when-not: this tool is for recording, not for accepting or promoting. It does not name a sibling alternative such as adopt_model_into_study, so an agent must infer which tool to use instead, but the boundary is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_modelRename ModelADestructiveIdempotent
Rename a model.
Changes only the display name; the model's saved/unsaved state is untouched (use save_model to file it into a project). The name is HTML-sanitized server-side and must be non-empty.
Args: model_hash: Hash of the model to rename. name: New display name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It adds meaningful non-obvious behavior beyond the annotations: only the display name changes, saved/unsaved state is untouched, and the name is HTML-sanitized and non-empty. This does not contradict the destructiveHint because overwriting the display name is still a mutating update.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: purpose, side-effect boundary, input handling rule, then parameter semantics. It is front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation with an output schema and annotations, the description is nearly complete: it covers purpose, parameter meaning, side-effect scope, and validation. A minor gap is the lack of explicit mention of what happens when the model hash does not exist or how the new name appears in references.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the Args block compensates by clarifying that model_hash identifies the model to rename and name is the new display name. It also carries the non-empty constraint from the description, though it does not describe hash format or sources.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first line 'Rename a model' states the exact verb and resource, and the next line 'Changes only the display name' sharply scopes the operation against siblings like save_model, delete_model, and rename_project. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly warns not to expect saved/unsaved state changes and directs the agent to save_model for filing a model into a project. It does not enumerate every alternative, but for a narrow rename operation the when-to-use context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_projectRename ProjectADestructiveIdempotent
Rename a project you OWN.
Team members can file models into a shared folder but not rename it (owner-only; 404 for a project you don't own). Renaming your default folder is safe: it keeps receiving unqualified saves under its new name.
Args: project_id: Id of the project to rename (see list_projects). name: New display name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| project_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as destructive and not read-only, but the description adds valuable behavioral context beyond them: owner-only enforcement with 404 for non-owned projects, and the reassuring detail that renaming the default folder preserves its role for unqualified saves. This meaningfully informs an agent's decision and expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core statement. Every sentence adds useful information: ownership requirement, error behavior, default-folder side effect, and parameter explanations. There is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, no-nested-object tool with an output schema and annotations, the description covers the essential context: who can call it, error semantics, side effects, and how to find the parameter value. Nothing critical is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does. project_id is explained as the ID of the project to rename with a pointer to list_projects, and name is described as the new display name. This is sufficient for a simple two-parameter tool, though it doesn't add constraints like uniqueness or length.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the specific action and resource: 'Rename a project you OWN.' It clearly distinguishes the operation from model-level operations by emphasizing ownership and the project scope, and it adds the critical condition that only owners can rename.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context: only for projects you own, with a 404 if you don't. It references list_projects for obtaining the project_id. It does not explicitly name sibling alternatives like rename_model, but the ownership and shared-folder distinction makes the appropriate use case clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revise_study_recipeRevise Study RecipeA
Create an immutable revision. Earlier versions inherit influence automatically; optional source_revision_id additionally links a same-study source recipe. Optional expected_content_hash guards effective inputs (409 requires a fresh preview). Supply the current recipe version; stale edits are rejected (412). Reload list_study_recipes, reconcile changes, then submit the current version; never overwrite blindly.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| reason | Yes | ||
| recipe_id | Yes | ||
| specification | Yes | Backend recipe envelope. api_mmm requires request; model_snapshot requires model_hash and is review-only. Unknown fields are forwarded for backend validation. | |
| expected_version | Yes | ||
| source_revision_id | No | ||
| expected_content_hash | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It discloses critical behavioral details beyond annotations: immutable revision semantics, automatic inheritance of earlier versions, optional source_revision_id linking, expected_content_hash guarding with a 409 requiring fresh preview, and stale-edit rejection with 412. These are actionable and not inferable from the sparse annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, each carrying distinct operational guidance without filler. The core concept 'immutable revision' is front-loaded, followed by inheritance, optional links, guards, error codes, and the correct workflow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with a nested specification and concurrency semantics, the description captures the essential workflow and failure modes effectively. The main gap is explicit differentiation from sibling creation/update tools and fuller meaning for name/reason, though the output schema reduces the need for return-value documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning for expected_version ('current recipe version'), source_revision_id ('same-study source recipe'), and expected_content_hash ('guards effective inputs; 409 requires a fresh preview'). However, it leaves recipe_id, name, and reason unexplained, and with only 14% schema description coverage, the compensation is partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action—'Create an immutable revision'—on a clear resource (study recipe). It distinguishes itself from siblings like create_study_recipe by emphasizing immutability and versioning, and it references list_study_recipes for reconciliation, so the tool's role is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong procedural guidance: reload list_study_recipes, reconcile changes, submit the current version, and never overwrite blindly. However, it does not explicitly contrast with alternatives such as create_study_recipe or update_recipe_draft, so it stops short of full alternative-based guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_optimizerRun OptimizerA
Run budget optimization on a completed model.
Finds the optimal budget allocation across channels to maximize predicted revenue — or predicted PROFIT with objective="profit" — within the given constraints.
PROFIT OBJECTIVE: objective="profit" requires a margin source. If the model was built with an operating margin, it is used automatically; otherwise you MUST pass forward_margin (e.g. 0.18 for an 18% margin) or the API returns an error. Result fields (Revenue, ROI, ExpectedResponse) are then on the profit basis.
IMPORTANT:
Channel names must exactly match model results (case-sensitive, space-sensitive). Results are keyed by the channel's ACTIVITY COLUMN name (e.g. "search_activity"), not by the
channels[].namepassed to create_model. Call get_model_results with sections="channel_summary" first to get exact names, or use get_scenario_template to discover channel names and their average CPM values.bounds values are percentages of total_budget (0-100), not currency amounts.
laydown_weights and period_cpm must be ARRAYS of length num_periods, not scalars. Wrong: {"TV": 10}. Correct: {"TV": [10, 10, 10, 10]}.
The same channel keys must appear in all three: bounds, laydown_weights, and period_cpm.
All period_cpm values must be positive (> 0).
laydown_weights per channel must sum to a positive value (weights are normalized internally).
Returns 202 (async). Use get_optimizer_results to poll until status is "complete".
Args: model_hash: Hash of a completed model. total_budget: Total budget in currency units. num_periods: Number of periods to optimize over (matches your planning horizon). gamma: Uncertainty-aversion weight on the outcome spread (the objective is mean - gamma * spread). 0.0 = maximize expected return only (most aggressive); higher values penalize uncertainty harder (more conservative). The dashboard typically uses values in the 0-0.1 range. currency: Currency code (e.g. "USD", "GBP"). bounds: Per-channel min/max budget allocation as PERCENTAGES (0-100). Every channel must appear. Example: {"TV_Impressions": {"lower": 5, "upper": 40}, "Search_Clicks": {"lower": 10, "upper": 50}} laydown_weights: Per-channel spend timing weights. Each value is an array of length num_periods. Weights are relative (normalized internally). Use uniform [1, 1, ...] for even distribution across periods. Example: {"TV_Impressions": [1, 1, 1, 1]} period_cpm: Per-channel cost-per-metric for each period. Each value is an array of length num_periods with positive values. Get baseline CPM from get_scenario_template (avg_cpu_by_channel field). Example: {"TV_Impressions": [10.5, 10.5, 10.5, 10.5]} objective: "revenue" (default) or "profit". See PROFIT OBJECTIVE above. forward_margin: Decimal margin in (0, 1], e.g. 0.18 = 18%. Only used with objective="profit"; required when the model has no stored operating margin. period_multiplier: Optional array of length num_periods converting KPI units to revenue per period over the planning horizon (mirrors the model's multiplier_column, e.g. price). include_historical_effect: Include carryover from historical spend in the predicted response (default True). enable_warm_start: Warm-start the optimizer from a previous solution (default True). optimizer_engine: "slsqp" (hardened SLSQP, default) or "marginal" (water-fill engine: allocates until every funded channel shows the same marginal return; exact profit-hurdle semantics and the tightest optimality certificates, with automatic SLSQP fallback). sigma_penalty: How gamma penalizes outcome spread: "std" (default), "variance" or "frozen" (advanced; smoother alternatives for hard-to-converge runs - leave on "std" normally). group_bounds: Joint constraints over channel SETS (#570), e.g. [{"name": "trade", "channels": ["TV", "Search"], "lower": 40, "upper": 60}] with lower/upper in % of total_budget (same convention as bounds). Groups must be disjoint and jointly feasible with the members' per-channel bounds. Presence forces the slsqp engine. Results gain GroupBounds/GroupBoundsReport columns; a BINDING group's members legitimately sit off the global marginal (they share the group's shadow price).
| Name | Required | Description | Default |
|---|---|---|---|
| gamma | Yes | ||
| bounds | Yes | ||
| currency | Yes | ||
| objective | No | revenue | |
| model_hash | Yes | ||
| period_cpm | Yes | ||
| num_periods | Yes | ||
| group_bounds | No | ||
| total_budget | Yes | ||
| sigma_penalty | No | std | |
| forward_margin | No | ||
| laydown_weights | Yes | ||
| optimizer_engine | No | slsqp | |
| enable_warm_start | No | ||
| period_multiplier | No | ||
| include_historical_effect | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only generic booleans (readOnlyHint false, etc.), so the description must disclose all behavioral traits. It does: returns 202 asynchronously, requires polling, mandates exact channel names, treats bounds as percentages, enforces array lengths, requires positive CPM, and explains the objective function (mean - gamma*spread). It also covers error conditions like missing forward_margin. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but justifiably so for a 16-parameter tool. It is well-structured: opening purpose, an 'IMPORTANT' section for critical gotchas, then an Args list. The most critical details (channel name exactness, bounds as percentages, array lengths) are front-loaded. Every sentence adds value, and redundancy between sections is minimal and serves emphasis. The length is proportionate to complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex with many interacting constraints and a schema that provides zero descriptions. The description covers all prerequisites, parameter semantics, error conditions, engine choices, and the async flow. It even explains the effect of group_bounds on results. Since an output schema exists, the description appropriately defers return-value details to get_optimizer_results. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full responsibility for parameter meaning. It does so comprehensively: each of the 16 parameters gets a detailed explanation with examples, constraints, defaults, and relationships. For instance, gamma is defined as uncertainty-aversion weight with a range suggestion, bounds are clarified as percentages, and group_bounds includes a full example. No parameter is left vague.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Run budget optimization on a completed model.' It clearly states the goal (optimal budget allocation to maximize revenue or profit) and distinguishes itself from sibling tools like get_optimizer_results (polling) and run_scenario (scenario runs). The purpose is unambiguous and immediately actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs when to use related tools: call get_model_results first to obtain exact channel names, use get_scenario_template to discover CPM values, and poll get_optimizer_results after the 202 response. It also explains when the profit objective requires forward_margin and when the 'marginal' engine is appropriate. Clear prerequisites and follow-ups leave no room for confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_scenarioRun ScenarioA
Run a "what-if" scenario prediction on a completed model.
Takes a set of future period rows with channel activity values and
predicts the KPI outcome. Use get_scenario_template first to get
the expected format, channel names, and baseline values. Channel names are
the activity-column keys from the template/results (e.g. "search_activity"),
not the channels[].name passed to create_model.
IMPORTANT: Before submitting, replace any NaN/null values in scenario_data with 0. The template from get_scenario_template may contain NaN for channels without historical data, which will cause the prediction to fail.
This is async (returns 202 with status "pending"). Poll get_scenario_results until status is "complete" or "failed".
Workflow: get_scenario_template -> modify values -> run_scenario -> poll get_scenario_results
Args: model_hash: Hash of a completed model. scenario_data: Array of period rows, each a dict with "Date" (YYYY-MM-DD format) and channel activity columns. Channel names must match exactly what get_scenario_template returns in the "channels" field. Example: [{"Date": "2025-01-06", "TV_Impressions": 50000, "Search_Clicks": 1200}] spend_metadata: Optional per-channel spend info for ROI calculation in results. Each entry: {"channel": "TV_Impressions", "metric": "impressions", "cpm": 25.0, "total_spend": 125000, "weekly_spend": [25000, 25000, ...]} rebuild_model: Recompile the model graph before prediction. Must be True (default) for API-initiated scenarios where the model graph is not in memory. evaluate_holdout: Evaluate the scenario against held-out actuals when the scenario period overlaps observed data (default False). skip_slicing: Skip per-channel contribution slicing in the prediction output — faster when only the KPI total is needed (default False). proxy_channels: Optional list of proxy-channel mappings, each mapping a scenario channel to a fitted channel whose transforms it borrows (for channels without their own history).
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes | ||
| skip_slicing | No | ||
| rebuild_model | No | ||
| scenario_data | Yes | ||
| proxy_channels | No | ||
| spend_metadata | No | ||
| evaluate_holdout | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses critical behavioral details beyond the annotations: the operation is async returning 202 with status pending, NaN values must be replaced with 0, and rebuild_model must be True for API-initiated scenarios. No contradiction with annotations is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and dense with useful information, including an IMPORTANT warning and a workflow line. Each section earns its place, especially given the parameter count and zero schema coverage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all seven parameters, prerequisites, async behavior, failure mode, and post-invocation polling. Since an output schema exists, not detailing return values is acceptable, and nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates by explaining every parameter with types, defaults, examples, and constraints. It even clarifies channel naming provenance and provides a concrete scenario_data example.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: running a what-if scenario prediction on a completed model. It also differentiates itself from the related siblings by referencing the get_scenario_template -> run_scenario -> get_scenario_results workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to call get_scenario_template first to obtain the expected format and channel names, and to poll get_scenario_results until completion or failure. Provides a clear workflow and prerequisite ordering, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_modelSave ModelADestructive
Save a model into a project under a display name.
API-created models start unsaved and are invisible to list_models (without include_unsaved=true) — saving files them into a project so they appear in the default listing and the dashboard's Saved Models.
The same saved-models cap applies as in the dashboard: at the cap the API returns a 400 with error_type "saved_limit". Re-saving an already-saved model renames/refiles it without consuming a new slot.
Args: model_hash: Hash of the model to save. name: Display name to save under (non-empty). project_id: Optional target project ID; must be a project you own or one shared with a team you belong to. Discover ids with list_projects; create a folder with create_project. Defaults to your default project.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| model_hash | Yes | ||
| project_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond the annotations: unsaved models are invisible to list_models without include_unsaved=true, the saved-model cap returns a 400 with error_type 'saved_limit', re-saving does not consume a new slot, and project ownership is required. This is exactly the kind of contextual detail an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-sentence purpose, then a useful lifecycle explanation, then an Args section. It is slightly long but every section contributes necessary behavioral or parameter guidance, so it earns its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core action, the unsaved-to-saved transition, error behavior, parameter constraints, ownership rules, and defaults. With an output schema already present, no important operational detail is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It explains model_hash, name (non-empty), and project_id (optional, must be owned or team-shared, defaults to default project), and even suggests how to discover project ids. All three parameters receive meaningful semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Save a model into a project under a display name.' It then clarifies the unsaved vs. saved lifecycle and visibility in list_models, which makes the tool's role distinct from siblings like create_model or rename_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage context: API-created models start unsaved and need this call to become visible in default listings. It also explains project_id constraints and points to list_projects/create_project. However, it does not explicitly state when not to use it or name alternative tools like rename_model or unsave_model.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_contribution_groupsSet Contribution GroupsADestructiveIdempotent
Persist the driver groupings the dashboard contributions view renders (#436) — configure grouping once and every viewer sees it.
Each group: {"name": str, "drivers": [column names], "color": "#hex"?, "baseAdjustments": {driver: "min"|"max"|"none"}?}. Driver names are validated against the model's media/control/halo/trademark factors (400 with a did-you-mean hint on typos); each driver may belong to at most one group; baseAdjustments must reference the group's own drivers. The special "_channel_color_overrides" pseudo-group carries a channelColors map instead of drivers.
NOTE: this is the CONTRIBUTIONS-VIEW grouping. create_model's channel_groups is the unrelated adstock parameter-sharing feature — do not confuse them.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes | ||
| contribution_groups | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=true), the description adds rich behavioral context: validation against model factors, 400 responses with did-you-mean hints, one-group-per-driver constraints, baseAdjustments scoping, and the special _channel_color_overrides pseudo-group. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact despite covering complex validation rules. It front-loads the core purpose, then gives the group shape, constraints, and a disambiguation note—each sentence adds necessary information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description is complete: it explains the object format, validation behavior, persistence semantics, and the unrelated sibling feature. An output schema exists, so return-value documentation is not required from the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It supplies the exact structure of each contribution group, including optional fields, accepted value types, and validation semantics. This is far more than the input schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Persist the driver groupings the dashboard contributions view renders.' It also explicitly contrasts this tool with create_model's channel_groups, making the purpose unmistakable and distinguishing it from a plausible sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states this is the CONTRIBUTIONS-VIEW grouping and explicitly warns not to confuse it with create_model's channel_groups, naming the alternative feature as unrelated. This gives the agent a concrete when-not-to-use signal and prevents cross-tool confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_run_pinnedSet Run PinnedADestructiveIdempotent
Pin or unpin a saved optimizer or scenario run.
Declarative and idempotent: setting the current state again is a no-op, so scripts can safely re-run it.
Args: artifact: "optimizer" (run_id "opt_...") or "scenario" ("scn_..."). model_hash: Hash of the model the run belongs to. run_id: The run's stable id from run history. pinned: Desired pin state.
| Name | Required | Description | Default |
|---|---|---|---|
| pinned | Yes | ||
| run_id | Yes | ||
| artifact | Yes | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint, readOnlyHint, and idempotentHint. The description adds specificity by explaining that setting the current pin state again is a no-op and that scripts can safely re-run it, which goes beyond the bare hint. It does not detail what happens when unpinning, but the annotation covers the destructive nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the purpose, and organized into a short declarative statement and a clear Args list. Every sentence contributes either to use intent, behavioral guarantees, or parameter understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-scalar-parameter tool with an output schema and idempotency/destructive annotations, the description covers all the information needed to invoke it correctly: accepted artifact types, id semantics, model association, and the pin state. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description carries the full burden, and it succeeds. Each parameter is explained: artifact values with run_id prefix examples, model_hash as the hash of the owning model, run_id as the stable id from run history, and pinned as the desired pin state. This adds the meaning the schema omits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence uses a specific verb and resource: 'Pin or unpin a saved optimizer or scenario run.' It clearly identifies the tool's action and object, making it distinguishable from generic siblings like update_run, and the artifact examples reinforce the domain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it by stating the action ('Pin or unpin'), and it notes that idempotency makes re-running safe in scripts. However, it does not explicitly contrast this tool with alternatives or give exclusion criteria, leaving usage guidance to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlink_var_modelUnlink Var ModelADestructiveIdempotent
Remove an MMM's VAR link (#569). Idempotent.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the description's 'Idempotent' note is somewhat redundant but reinforces the key behavioral trait. The description adds the specific scope ('an MMM's VAR link') and references issue #569, which gives context. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The core action is front-loaded, and the idempotency note is a valuable addition. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive operation, the description is mostly adequate. The output schema exists, so return values are covered. However, the description doesn't clarify what 'VAR link' means in this domain or what happens to the model after unlinking, which could matter for an agent deciding whether to call this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden for parameter meaning. However, the description doesn't explain what model_hash is or how to obtain it. The parameter name is fairly self-explanatory, but the description adds no semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Remove an MMM's VAR link') with a clear resource, and the idempotency note adds useful precision. It doesn't explicitly distinguish from sibling tools like link_var_model, but the verb 'unlink' and the resource 'VAR link' make the purpose clear enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it: when you need to remove a VAR link from an MMM. It doesn't explicitly state when not to use it or name alternatives, but the sibling context (link_var_model) makes the contrast fairly obvious. No explicit exclusions or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsave_modelUnsave ModelADestructive
Release a model's saved slot without deleting anything — the inverse of save_model (#673).
Use this for cap management: at the 20-saved-models cap, unsave a model that no longer earns its shelf spot instead of deleting it. The model reverts to the state API-created models start in (unsaved, no project; the name is kept) — it leaves the default listing and the dashboard's Saved Models but stays fully addressable by hash: fetchable, renameable, exportable, re-saveable, and visible via list_models with include_unsaved=true. Idempotent — unsaving an unsaved model is a success with freed_project_id null. delete_model remains failed-only.
Two caveats: the UNSAVED pool is auto-pruned by dashboard model creation (at 10+ unsaved models the oldest is hard-deleted, artifacts included), so re-save anything worth keeping rather than parking it unsaved long-term; and unsaving a shared model hides it from every recipient until it is saved again.
Args: model_hash: Hash of the model whose slot to release.
Returns: {model_hash, is_saved: false, freed_project_id}.
| Name | Required | Description | Default |
|---|---|---|---|
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is exemplary in disclosing side effects, idempotency, retention of hash addressability, and auto-pruning risks. However, the annotations state idempotentHint=false while the description explicitly says 'Idempotent — unsaving an unsaved model is a success.' This is a direct annotation contradiction, which per the rubric requires a score of 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it front-loads the core purpose, then covers use case, state transitions, idempotency, return shape, and important caveats. The structured Args/Returns sections make the information easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one parameter and an output schema, the description covers everything needed: behavior, model state after unsaving, listing visibility, hash addressability, re-saving, idempotency, pruning caveat, shared-model caveat, and return fields. The only downside is the annotation contradiction, but the description itself is contextually complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter model_hash has zero percent schema description coverage, but the description compensates fully by explaining it as 'Hash of the model whose slot to release.' This is precise and sufficient for an agent to populate the parameter correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Release a model's saved slot without deleting anything' and explicitly frames it as the inverse of save_model. It clearly separates unsave_model from delete_model and save_model, making the tool's role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: at the 20-saved-models cap, unsave instead of delete. It also states caveats for shared models and the auto-pruning of unsaved models, helping the agent decide whether this tool is appropriate in a given situation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_recipe_draftUpdate Recipe DraftADestructiveIdempotent
Replace authoring state using the version from get_recipe_draft. Retain every unedited field, including original priors and source bytes. Stale changes fail; reload and reconcile explicitly. Identical retries return the current draft. Does not publish or launch.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| draft_id | Yes | ||
| snapshot | Yes | Lossless editor authoring state. Backend is authoritative; preserve unknown nested fields. Source bytes are copied into encrypted draft storage (10 MB source limit); metadata limit is 5 MB. No local filesystem paths or executable code. | |
| expected_version | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses concrete concurrency behavior ('Stale changes fail'), idempotent retry semantics ('Identical retries return the current draft'), and non-side-effects ('Does not publish or launch'). It also tells agents to preserve unedited fields and source bytes, which is operationally significant for a destructive update.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four terse sentences, each carrying distinct operational information: source version, preservation rule, concurrency rule, idempotency, and side-effect exclusion. The most important action and precondition are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex update with a large nested snapshot, the description covers the key operational concerns: obtaining the version, preserving unknown/unedited data, handling stale conflicts and retries, and avoiding confusion with publish/launch. The output schema exists, so return-value details are not required here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds essential meaning to expected_version ('version from get_recipe_draft', stale changes fail) and to snapshot ('retain every unedited field, including original priors and source bytes'). draft_id and name are not explicitly explained, but their names are self-evident and the nested snapshot schema provides rich detail where the description is terse.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the action concretely: 'Replace authoring state' for a recipe draft, and specifies the source of truth ('version from get_recipe_draft'). It also carves out sibling behaviors with 'Does not publish or launch', distinguishing it from publish_recipe_draft and launch-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Directs the correct workflow: call get_recipe_draft first, use its version, and if stale, reload and reconcile. It explicitly warns against expecting publish/launch side effects and gives a precise retry rule, leaving no ambiguity about when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_runUpdate RunADestructive
Rename / annotate a saved optimizer or scenario run.
Runs are auto-named at creation (e.g. "$1.2M · 12mo · Jan 5"); renaming makes run history carry the analysis ("holiday cut -10%", "stretch 130%"). Renaming permanently flips the run's auto_named flag to false so future auto-naming never overwrites it. Only the fields you provide are changed.
Args: artifact: "optimizer" (run_id "opt_...") or "scenario" ("scn_..."). model_hash: Hash of the model the run belongs to. run_id: The run's stable id from run history. name: New display name (non-empty when given; capped at 255 chars). notes: Free-text annotation. Omit to leave untouched; pass "" to clear. tags: Replacement tag list (max 20 tags, 64 chars each).
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| tags | No | ||
| notes | No | ||
| run_id | Yes | ||
| artifact | Yes | ||
| model_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing that renaming permanently flips the auto_named flag to false, that only provided fields are changed, and that notes can be omitted to leave untouched or passed as empty string to clear. This is valuable behavioral context that complements the destructiveHint and readOnlyHint annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a concise summary line followed by a clear Args list. Every sentence earns its place: the auto-naming example illustrates intent, the permanent flag note warns about irreversibility, and the parameter constraints are precise. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all six parameters, the partial-update behavior, the permanent auto_named flip, and edge-case semantics for notes. Since an output schema is present and annotations already convey the read/write/destructive profile, an agent has everything necessary to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the Args section fully compensates by documenting every parameter: artifact values with run_id prefixes, model_hash, run_id, name constraints (non-empty, capped at 255), notes semantics (omit vs empty), and tags limits (max 20 tags, 64 chars each). The description adds significant meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line uses a specific verb-resource pair ('Rename / annotate a saved optimizer or scenario run'), which clearly identifies the tool's purpose and distinguishes it from sibling tools like set_run_pinned or update_recipe_draft. It also names the two artifact types (optimizer/scenario) and their run_id prefixes, leaving no ambiguity about what the tool operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: runs are auto-named at creation and renaming makes run history carry the analysis, implying this tool is for annotating/renaming existing runs. It doesn't explicitly reference alternatives or exclusion conditions, but the context is strong enough that an agent can infer the appropriate use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_studyUpdate StudyADestructive
Update owner-controlled study settings. State is active, paused or archived. Stale versions fail.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| state | No | Backend state: active, paused or archived. | active |
| version | Yes | ||
| question | Yes | ||
| study_id | Yes | ||
| max_attempts | Yes | ||
| max_concurrent | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal danger (destructiveHint=true) and mutation, so the description's main contribution is 'owner-controlled' (authorization context), the valid state set ('active, paused or archived'), and the optimistic concurrency behavior ('Stale versions fail'). These add meaningful behavioral context beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The core purpose is front-loaded, followed by the state enumeration and the most important behavioral caveat. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive 7-parameter update tool, the description covers the essential operational constraints: owner authorization, valid states, and version staleness. The output schema exists, so return values need no description. It could mention side effects on existing study data, but the combination of annotations and description is sufficient for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 14%, so the description must compensate. It does clarify the `state` parameter values and the `version` concurrency requirement, but it does not explain the semantics of `max_attempts`, `max_concurrent`, `name`, or `question`. Those names are somewhat self-explanatory, but the description leaves the low-coverage burden partially unmet.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Update owner-controlled study settings.' It clearly distinguishes this from sibling tools by restricting to owner-controlled settings and study-level updates, which is not ambiguous with create_study, get_study, update_run, or other sibling operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (updating settings for a study you own) and gives a key precondition: 'Stale versions fail.' However, it does not explicitly name alternatives or state when not to use this tool, such as when updating runs or recipe drafts instead of studies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_dataUpload DataA
Upload a CSV dataset to Simba for use in model building.
Provide EXACTLY ONE of csv_content (raw CSV text) or csv_path (a file path on the machine running this MCP server). Prefer csv_path for anything beyond trivial size — it avoids passing megabytes of CSV through the conversation.
The CSV should follow the canonical schema: one row per time period with date, KPI, multiplier, hierarchy, media activity/spend columns, and optional control variables.
IMPORTANT:
CSV only (not Excel). Maximum file size: 10 MB (API-enforced).
Row minimum: check get_data_schema -> x-simba-constraints.min_rows for the declared minimum; enforcement may be more permissive, and the upload response's
warningsfield is authoritative. More rows = tighter posteriors (104+ weekly rows recommended).Media columns must follow naming: {channel}_activity and {channel}_spend.
Use 0 for inactive periods, not blank or NA.
csv_path is only available when the server runs locally (stdio). On HTTP/SSE deployments it is disabled unless SIMBA_MCP_ALLOW_LOCAL_FILES=1.
Args: csv_content: The full CSV text content (not base64, just raw CSV text). csv_path: Path to a .csv file readable by the MCP server process. name: Optional dataset name for identification. Defaults to the file stem when csv_path is used. filename: Optional original filename to record alongside the dataset.
Returns the uploaded file ID (needed for create_model), row/column counts, and any validation warnings.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| csv_path | No | ||
| filename | No | ||
| csv_content | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond what the annotations provide, the description discloses the 10 MB API-enforced size limit, that the response's warnings field is authoritative, row-count guidance for posterior tightness, media-column naming conventions, and the rule to use 0 instead of blank/NA for inactive periods. It also explains a deployment-dependent behavior for csv_path, which is valuable non-obvious context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: purpose first, then parameter-choice guidance, then canonical-schema and constraint bullets, then an Args block. The bulleted IMPORTANT list is scannable and front-loaded with the most operationally critical constraints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter upload tool with no schema descriptions, this definition covers input formats, constraints, deployment conditions, related-tool references, and return semantics. The presence of an output schema covers the exact return shape, so no critical context an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description fully compensates by explaining all four parameters: csv_content must be raw CSV text and not base64, csv_path must be readable by the server process, name defaults to the file stem when csv_path is used, and filename is optional metadata. No parameter meaning is left to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource: 'Upload a CSV dataset to Simba for use in model building.' It clearly identifies the input format (CSV), the target system, and the downstream purpose, which distinguishes it from sibling tools like get_upload, list_uploads, and create_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when/when-not guidance: prefer csv_path for non-trivial data, use csv_content otherwise, accept only CSV not Excel, and note that csv_path is unavailable on HTTP/SSE deployments unless SIMBA_MCP_ALLOW_LOCAL_FILES=1 is set. It also tells the agent to consult get_data_schema for the authoritative minimum row constraint before uploading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_study_recipeValidate Study RecipeARead-onlyIdempotent
Resolve and validate a recipe without creating a run. Returns effective settings and provenance limits.
| Name | Required | Description | Default |
|---|---|---|---|
| specification | Yes | Backend recipe envelope. api_mmm requires request; model_snapshot requires model_hash and is review-only. Unknown fields are forwarded for backend validation. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to restate safety. It adds value by specifying 'without creating a run' (a behavior beyond mere read-only) and by describing the output ('returns effective settings and provenance limits'). This provides useful context beyond what annotations convey, without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the primary action ('Resolve and validate a recipe') and immediately states the key differentiator ('without creating a run') and the output. Every word earns its place; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single parameter with rich schema documentation and an output schema exists, which covers structural details. However, the description lacks explicit usage guidance (when to call this vs. related recipe tools) and does not clarify what 'resolve' or 'provenance limits' entail beyond the output mention. For a tool with nested parameters, this is a modest gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – the nested 'specification' parameter is thoroughly documented in the schema (explaining kind, request, model_hash, and the open-world behavior). The tool description itself adds no parameter-level detail. Since the schema carries the full burden, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'resolve and validate' on the resource 'recipe' and explicitly distinguishes it from creating a run, which is a distinct action. It also mentions the return value (effective settings and provenance limits), making the tool's purpose unambiguous. There is no other validation tool among the siblings, so no confusion with alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without creating a run' implies this tool is for validation before executing a run, but it does not explicitly state when to use it versus other recipe-related tools (e.g., create_study_recipe, revise_study_recipe). No alternatives or exclusion criteria are mentioned. The usage is implied rather than clearly prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
63 tool updates
v0.5.0- Added
adopt_model_into_study - Added
assess_study_validation_pair - Added
cancel_study_run - Added
compare_study_runs - Changed
create_model5 fields changed- added
Input schema / properties / channels / items / descriptionAdded value: +"Media channel binding. Exact activity-column keys identify channels in result/optimizer calls." - added
Input schema / properties / channels / items / propertiesAdded value: +{ + "activity_column": { + "type": "string" + }, + "name": { + "type": "string" + }, + "spend_column": { + "type": "string" + } +} - added
Input schema / properties / channels / items / requiredAdded value: +[ + "name", + "activity_column", + "spend_column" +] - added
Input schema / properties / control_priorsAdded value: +{ + "anyOf": [ + { + "items": { + "additionalProperties": true, + "description": "Optional override for a selected control column. Values and priors use transformed units; discover backend support first.", + "properties": { + "control": { + "type": "string" + }, + "distribution": { + "examples": [ + "normal", + "inversegamma", + "truncatednormal", + "halfnormal" + ], + "type": "string" + }, + "lower": { + "type": "number" + }, + "mean": { + "type": "number" + }, + "sd": { + "type": "number" + }, + "transform": { + "description": "N unchanged; DM divide by variable mean; STA scale by sample SD without centering; DDM divide by variable mean within hierarchy; LOG log(x/mean(x)). Backend validates applicability.", + "examples": [ + "N", + "DM", + "STA", + "DDM", + "LOG" + ], + "type": "string" + }, + "upper": { + "type": "number" + } + }, + "required": [ + "control" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Control Priors" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "create_modelDictOutput", + "type": "object" +}
- Changed
create_project1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "create_projectDictOutput", + "type": "object" +}
- Added
create_quality_policy - Added
create_recipe_draft - Added
create_study - Added
create_study_recipe - Changed
create_var_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "create_var_modelDictOutput", + "type": "object" +}
- Added
declare_study_holdout_use - Changed
delete_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "delete_modelDictOutput", + "type": "object" +}
- Added
evaluate_study_run - Added
get_backend_capabilities - Changed
get_contribution_groups1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_contribution_groupsDictOutput", + "type": "object" +}
- Changed
get_data_schema1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_data_schemaDictOutput", + "type": "object" +}
- Changed
get_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_modelDictOutput", + "type": "object" +}
- Changed
get_model_results2 fields changed- added
Input schema / properties / max_response_bytesAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Response Bytes" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_model_resultsDictOutput", + "type": "object" +}
- Changed
get_model_status1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_model_statusDictOutput", + "type": "object" +}
- Changed
get_optimizer_results1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_optimizer_resultsDictOutput", + "type": "object" +}
- Added
get_recipe_draft - Added
get_recipe_draft_template - Added
get_recipe_revision - Added
get_recipe_revision_authoring - Changed
get_scenario_results1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_scenario_resultsDictOutput", + "type": "object" +}
- Changed
get_scenario_template1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_scenario_templateDictOutput", + "type": "object" +}
- Added
get_study - Added
get_study_champion - Added
get_study_prediction_access - Added
get_study_run - Added
get_study_validation_resolutions - Changed
get_upload1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "get_uploadDictOutput", + "type": "object" +}
- Added
launch_study_run - Changed
link_var_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "link_var_modelDictOutput", + "type": "object" +}
- Changed
list_models1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "list_modelsDictOutput", + "type": "object" +}
- Changed
list_projects1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "list_projectsDictOutput", + "type": "object" +}
- Added
list_quality_policies - Added
list_recipe_drafts - Changed
list_runs1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "list_runsDictOutput", + "type": "object" +}
- Added
list_studies - Added
list_study_decisions - Added
list_study_evaluations - Added
list_study_recipes - Added
list_study_runs - Changed
list_uploads1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "list_uploadsDictOutput", + "type": "object" +}
- Added
publish_recipe_draft - Added
recommend_study_run - Changed
rename_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "rename_modelDictOutput", + "type": "object" +}
- Changed
rename_project1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "rename_projectDictOutput", + "type": "object" +}
- Added
revise_study_recipe - Changed
run_optimizer1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "run_optimizerDictOutput", + "type": "object" +}
- Changed
run_scenario1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "run_scenarioDictOutput", + "type": "object" +}
- Changed
save_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "save_modelDictOutput", + "type": "object" +}
- Changed
set_contribution_groups1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "set_contribution_groupsDictOutput", + "type": "object" +}
- Changed
set_run_pinned1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "set_run_pinnedDictOutput", + "type": "object" +}
- Changed
unlink_var_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "unlink_var_modelDictOutput", + "type": "object" +}
- Changed
unsave_model1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "unsave_modelDictOutput", + "type": "object" +}
- Added
update_recipe_draft - Changed
update_run1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "update_runDictOutput", + "type": "object" +}
- Added
update_study - Changed
upload_data1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "title": "upload_dataDictOutput", + "type": "object" +}
- Added
validate_study_recipe
29 tool updates
v0.3.2- First observed
create_model - First observed
create_project - First observed
create_var_model - First observed
delete_model - First observed
get_contribution_groups - First observed
get_data_schema - First observed
get_model - First observed
get_model_results - First observed
get_model_status - First observed
get_optimizer_results - First observed
get_scenario_results - First observed
get_scenario_template - First observed
get_upload - First observed
link_var_model - First observed
list_models - First observed
list_projects - First observed
list_runs - First observed
list_uploads - First observed
rename_model - First observed
rename_project - First observed
run_optimizer - First observed
run_scenario - First observed
save_model - First observed
set_contribution_groups - First observed
set_run_pinned - First observed
unlink_var_model - First observed
unsave_model - First observed
update_run - First observed
upload_data
TDQS
Scored across 63 tools
The core model/upload/optimizer/scenario tools are distinct, but the recipe and study clusters overlap heavily: create_recipe_draft vs create_study_recipe and get_recipe_revision_authoring vs get_recipe_revision are easy to confuse from names alone. Detailed descriptions resolve most ambiguity, but an agent must read carefully before choosing.
All 63 tools follow a consistent snake_case verb_noun pattern: get_*, list_*, create_*, update_*, run_*, launch_*, evaluate_*, compare_*. Even the longer compound nouns like study_validation_pair and recipe_revision_authoring are internally consistent with their siblings, so the set is highly predictable.
At 63 tools, the server is far above the well-scoped range and feels like a full platform API rather than a focused MCP surface. The broad Simba domain explains some of the count, but the surface would be much more usable split into modeling, run/optimization, and study-governance servers.
The surface covers nearly the entire MMM and VAR lifecycle: schema/upload, model creation/status/results, optimizer/scenario runs, projects, and deep study/recipe/quality governance. It is not a perfect 5 because a few lifecycle actions such as deleting non-failed models/projects, champion promotion, and manual sign-off are deliberately frontend-only and documented as gaps an agent cannot complete.
Maintenance
Related MCP Connectors
Conversational access to advertising performance data, creative analysis, and campaign insights
Conversational access to advertising performance data, creative analysis, and campaign insights
AI marketing agent for Google Ads, Meta, GA4, TikTok, LinkedIn, Shopify, HubSpot and more.
Ask live marketing data anything to get verified answers, client-ready reports, and next steps.
Related MCP Servers
- -licenseNot gradedqualityBmaintenanceConnects AI assistants to marketing mix models, enabling natural language data upload, performance modeling, budget optimization, and scenario testing.-
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to create, analyze, and optimize ad campaigns across Google Ads, Meta Ads, TikTok Ads, LinkedIn Ads, Amazon Ads, and ChatGPT Ads through natural language using 400+ tools.93MIT
- FlicenseNot gradedqualityCmaintenanceEnables marketing optimization tasks such as copywriting, campaign analysis, social media planning, audience segmentation, and KPI tracking through natural language.82 npm-

PaidSync MCP Serverofficial
AlicenseNot gradedqualityFmaintenanceConnects Google Ads, Meta Ads, and LinkedIn Ads to AI assistants, enabling natural language ad campaign management, reporting, and optimization across platforms.MIT