Skip to main content
Glama
getsimba-ai

Simba MCP Server

Official
by getsimba-ai

create_model

Create and start a Bayesian Marketing Mix Model fit from uploaded data, returning a model hash you can poll for status.

Instructions

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.)

Returns the model_hash for status polling.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
linkNoidentity
nameNo
trendNo
priorsNo
samplerNo
channelsYes
kpi_columnYes
likelihoodNonormal
attributionNo
date_columnYes
seasonalityNo
channel_groupsNo
control_columnsNo
saturation_typeNotanh
transform_orderNoadstock_first
hierarchy_columnYes
operating_marginNo
reporting_kernelNo
uploaded_file_idYes
control_referenceNo
multiplier_columnNo
total_media_effectNoOther
annual_discount_rateNo
operating_margin_columnNo
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it is exceptionally transparent: it discloses async queuing, immediate hash return, polling needs, unsaved-model visibility, commit via save_model, strict validation (unknown keys rejected with 400), and the operating_margin_column root-caveat. It also explains resolved priors in get_model for verification.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The structure is front-loaded with a one-paragraph summary followed by an Args block, and each parameter gets its own explanation, which is appropriate for 24 complex parameters. However, the description is long and includes internal ticket references (#630, #672, etc.) and repeated caveats that add noise without helping tool selection or invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a complex creation endpoint: it covers the async return contract, model state lifecycle, validation behavior, and all parameter semantics. Since there is no output schema, it correctly states that the return value is a model_hash for status polling; no critical invocation information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

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: every one of the 24 parameters is explained, including defaults, valid values, mutually exclusive pairs, and cross-parameter constraints. The priors section in particular adds meaning far beyond the schema's bare additionalProperties.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Create and start fitting a new Bayesian Marketing Mix Model.' It also differentiates from siblings by describing the async fit-and-poll lifecycle with get_model_status and clearly separates this from create_var_model's domain. The purpose is unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states exactly what happens on use: it queues an async fit and returns immediately, and directs the agent to poll get_model_status until 'complete'. It does not explicitly enumerate when to choose this over create_var_model, but the resource type ('Bayesian Marketing Mix Model') makes the context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/getsimba-ai/simba-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server