Funnel Calibrator
Allows reading the day's advertising objective and prior conclusions from an Obsidian vault via the Local REST API, and writing calibrated verdicts back to the vault as durable records.
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., "@Funnel CalibratorRecalibrate Stop and Goal CPL for our top SKU using its measured approval and buyout rates."
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.
Funnel Calibrator
An MCP server that recalibrates advertising decisions against what a sales funnel actually does — not what it is assumed to do.
KSE AI Agentic Lab — Individual Lab Assignment (Week 7, MCP Integration). Defence: 25 August 2026.
The problem this solves
The project is built on a live Ukrainian cash-on-delivery (COD) e-commerce business selling women's clothing through Meta ads. Its funnel has five stages:
Meta ads ──► Lead ──► Call-centre approval ──► Shipment ──► Buyout at post office ──► ProfitBecause payment happens on delivery, the outcome of an ad campaign is not known when the money is spent. It is known two to four weeks later, when the customer either collects the parcel or does not. The business bridges that gap with two portfolio-wide constants — a 65% approval rate and a 52.5% buyout rate — and uses them to compute, for every product, the maximum cost-per-lead at which that product still breaks even (Stop CPL) and the target it should be optimised toward (Goal CPL).
Those constants are portfolio averages applied to individual products, and individual products diverge sharply from them. Measured examples from the source business: one manufacturer's products buy out at 37% against the assumed 52.5%; one product's approval rate measured 53% against the assumed 65%; buyout correlates strongly with price band, ranging from roughly 93% at 690–790 ₴ to roughly 55% above 1290 ₴.
When a product's real rates are worse than assumed, its real break-even CPL is lower than the number the business is steering by — so the advertising target can sit above the true break-even point. Traffic looks healthy in the ads dashboard while every lead loses money, and the loss only becomes visible at the monthly financial close, weeks later.
This is an open-loop control system: the measurement never returns to the decision. Funnel Calibrator closes the loop.
Related MCP server: marketplace-reality-check-mcp
What it does
The server measures each product's own funnel rates from historical order data, recomputes that product's true CPL bounds, and audits proposed advertising decisions against the corrected figures — returning structured evidence rather than a verdict to be taken on faith.
Two problems make this harder than an average, and both are handled explicitly in the tool contracts:
Censoring. Recent orders have not resolved yet — a parcel in transit is neither a buyout nor a return. Counting them naively depresses the measured rate. The server excludes cohorts younger than a configurable maturity window and reports how many orders it set aside.
Small samples. Per product, per size, per colour, the counts get small quickly. Every measurement carries its sample size and a reliability flag, and the server declines to draw conclusions below a configurable threshold rather than reporting confident noise.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Agent (Claude Agent SDK) │
│ │
│ ├── MCP ──► Obsidian Local REST API [existing] │
│ │ decision journal: reads the day's objective │
│ │ and prior conclusions, writes calibrated │
│ │ verdicts back as a durable record │
│ │ │
│ └── MCP ──► Funnel Calibrator [custom] │
│ measure → recalibrate → recommend → audit │
│ │ │
│ ▼ │
│ local snapshot dataset │
│ (anonymised order cohorts + unit economics) │
└─────────────────────────────────────────────────────────────┘The custom server runs as a separate process communicating over stdio, and is startable independently of the agent.
Agent flow
Read the day's advertising objective and yesterday's conclusions from the Obsidian vault.
Measure each product's observed funnel rates from the snapshot (censoring- and sample-aware).
Recompute that product's true
Stop/GoalCPL and the drift against the assumed baseline.Diagnose why a product underperforms — the cure differs by cause — and recommend a next action.
Audit the day's proposed decisions against the corrected bounds.
Write the calibrated verdict, with its evidence chain, back to the vault.
Each step consumes the previous step's output: the vault's contents determine what is measured, the measurement determines the corrected bounds, and the bounds determine whether a proposed decision stands or is overturned.
Custom tools
Tool | Responsibility |
| Observed approval / buyout / return rates for one product, with cohort censoring and sample-size gating. Primary data-source tool. |
| Recomputes true |
| Distinguishes the failure mode — weak offer, contested auction, traffic quality, creative fatigue, structural loss — and returns the matching action. |
| Tests a proposed decision against the calibrated bounds; returns |
A fifth tool, list_covered_skus, resolves a product code against the dataset. It is documented but deliberately not counted toward the assignment's three substantive tools — it sits too close to "list all rows".
Full input/output schemas, error conditions, side effects, and worked examples: docs/tool-contracts.md.
Why these four, why they sit at the MCP boundary, and what the design gives up: docs/design-rationale.md.
What it found
Article 21-154, measured on 95 resolved orders:
Assumed | Observed | |
Approval | 65% | 59.0% |
Buyout | 52.5% | 45.3% |
Stop CPL (break-even) | $2.32 | $1.61 |
Goal CPL (target) | $1.63 | $1.12 |
The target the business optimises toward, $1.63, sits above the product's true break-even of $1.61. Every lead bought at target loses money, while the ads dashboard shows a cost per lead comfortably inside its goal. The product had been scaled twice on that basis.
The build also turned up a CRM status — 35 "Відмова", 216 shipped orders — that the business's own reporting classifies as unknown and counts nowhere. Evidence in docs/design-rationale.md §5.
Data source
A local, anonymised snapshot dataset of historical order cohorts, exported from the business CRM by scripts/export_snapshot.py: 4 132 orders across 51 products, 1 June – 24 August 2026. No authentication and no network access are required at runtime, which makes the demonstration deterministic and reproducible — the export is a separate program from the server, run offline and ahead of time.
All personally identifiable information — customer names, phone numbers, addresses, waybill numbers, call-centre operator names — is stripped at export by a field whitelist, so a field the CRM adds later cannot leak by default. The snapshot retains only what the calibration requires: product code, order status, creation date, amount, and campaign labels. See data/README.md for the anonymisation policy and schema.
Quickstart
Prerequisites: Python ≥ 3.11 and uv. Obsidian with the Local REST API plugin is required only for the agent flow, not for running the server.
git clone https://github.com/denkor1015-debug/funnel-calibrator.git
cd funnel-calibrator
uv syncRun the MCP server standalone (it speaks MCP over stdio and will wait for a client):
uv run funnel-calibratorInspect the exposed tools interactively with the MCP Inspector:
npx @modelcontextprotocol/inspector uv run funnel-calibratorRun the tests:
uv run pytestConfiguration is read from environment variables; copy the template and edit:
cp .env.example .envRunning the agent flow
The agent needs the Obsidian side as well. One-time setup, in full: demo-vault/README.md.
Open
demo-vault/in Obsidian as a vault — not a personal vault.Install and enable the community plugin Local REST API with MCP by Adam Coddington (coddingtonbear/obsidian-local-rest-api). Several similarly named plugins mention MCP; this is the approved one.
Copy its generated API key into
.envasOBSIDIAN_API_KEY.Enable Enable Non-encrypted (HTTP) Server in the same pane and set
OBSIDIAN_PORT=27123. The plugin's HTTPS certificate is self-signed and Node rejects it;demo-vault/README.mdexplains the alternative if you would rather keep TLS.
Then:
uv run python agent/run_agent.py --dry-run # connect to both servers, list tools, stop
uv run python agent/run_agent.py # full flow, writes demo-vault/Decisions/<today>.mdThe Claude Agent SDK inherits the Claude Code CLI's authentication, so no Anthropic API key is set or needed. The only secret in play is the Obsidian plugin's token.
Agent wiring in portable form, for other MCP hosts: agent/mcp_config.example.json.
Regenerating the dataset
Not required to run anything — data/ is committed. The economics half rebuilds with no credentials at all:
uv run python scripts/export_snapshot.py --economics-onlyThe order half reads the business CRM through a worker, with the shared secret taken from KEYCRM_MCP_SECRET. It throttles, backs off on HTTP 429, and resumes rather than restarts:
uv run python scripts/export_snapshot.py --from 2026-06-01 --to 2026-08-24Repository layout
src/funnel_calibrator/ MCP server
server.py tool definitions and MCP wiring
contracts.py typed output contracts — the published output schemas
snapshot.py dataset loading, status taxonomy, cohort censoring
calibration.py unit economics — mirrors the business's own econ.py
policy.py diagnosis tree: evidence ──► diagnosis ──► action
scripts/ snapshot exporter, Obsidian contract capture,
mcp_call.py — call any tool over real MCP from a shell
data/ snapshot dataset + anonymisation policy
demo-vault/ Obsidian vault for the demonstration (no personal notes)
docs/ tool contracts, design rationale, defence checklist
agent/ end-to-end agent flow across both connections
tests/ 65 tests: calibration, censoring, sample gating, policy,
contracts, and the tools exercised over the wireBuild plan
Repository scaffolding, architecture, and design rationale
Snapshot exporter with PII stripping, rate-limit backoff, and resumable catalogue mapping
measure_sku_funnel— censoring and sample gatingrecalibrate_cpl_bounds— unit-economics recomputationrecommend_next_action— failure-mode diagnosisaudit_ad_verdict— decision auditingObsidian MCP integration and end-to-end agent flow
Failure-path handling and demonstration
Tool-contract documentation and defence script
Assignment requirements map
Requirement | Where |
Part A — approved existing MCP server | Obsidian Local REST API, the plugin's own MCP server, no wrapper. |
Part B — custom MCP server, ≥ 3 substantive tools |
|
Part C — tool-contract documentation |
|
Part D — operational requirements | No secrets committed; all configuration via environment variables; local dataset, so no network access at runtime and no API fixtures required; the export path throttles and backs off on HTTP 429 |
Design rationale |
|
Defence script |
|
Licence
MIT — see LICENSE.
Available Tools
5 toolsaudit_ad_verdictAudit a proposed advertising decisionARead-only
Test an advertising decision that originated elsewhere — a daily watchdog report, an operator's judgement, a note in the decision journal — against this product's recalibrated economics. Returns 'supported', 'contradicted', or 'insufficient_data', together with the numeric chain that produced the verdict and a counter-recommendation where the proposal is contradicted. Use before acting on any recommendation this server did not itself produce. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| sku | Yes | Product code, e.g. 21-183 | |
| source | No | Where the proposal came from, for the audit record | |
| current_cpl | Yes | Cost per lead the proposal is based on, USD | |
| cpl_trend_days | No | Days the cost per lead has held | |
| proposed_action | Yes | The decision being proposed | |
| competitor_active | No | Whether a competitor is bidding on this product |
Output Schema
| Name | Required | Description |
|---|---|---|
| sku | Yes | |
| verdict | Yes | |
| evidence | Yes | |
| rationale | Yes | |
| reliability | Yes | |
| proposed_action | Yes | |
| counter_recommendation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavioral context beyond the annotations: it returns a numeric chain and a counter-recommendation when the proposal is contradicted, and clarifies the three verdict states. 'Read-only' duplicates readOnlyHint=true, so that portion is redundant rather than additive.
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, front-loaded with the purpose and immediately followed by return values and the usage rule. The em-dash enumeration of proposal sources is slightly verbose but earns its place by clarifying scope.
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 values need not be exhaustively explained, yet the description still names the verdicts and the counter-recommendation. Combined with the pre-action usage rule, an agent has everything needed 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 100%, so every parameter is already documented in the schema (sku, source, current_cpl, cpl_trend_days, proposed_action enum, competitor_active). The description adds no format, units, or edge-case guidance for any parameter, so baseline 3 applies.
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 (test/audit) and resource (an advertising decision originating elsewhere), and enumerates the three possible verdicts returned. It implicitly separates itself from siblings like recommend_next_action by scoping to decisions this server did not produce.
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?
Gives an explicit trigger: 'Use before acting on any recommendation this server did not itself produce,' which also implies the exclusion (decisions the server generated). It does not name an alternative sibling tool by name, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_covered_skusList products the snapshot can answer forARead-only
List the product codes present in the loaded snapshot, with their order counts and whether price and cost data exist for them. Use to resolve a product code before measuring, or to see what the dataset covers. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| min_orders | No | Only list products with at least this many orders |
Output Schema
| Name | Required | Description |
|---|---|---|
| window | Yes | |
| products | Yes | |
| total_orders | Yes | |
| status_taxonomy | Yes | |
| snapshot_generated_at | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered. The trailing 'Read-only.' merely restates the annotation, and the listed return fields duplicate the output schema, so the description adds little behavioral context beyond what structured fields 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?
Two tight sentences: the first states what is listed and what each entry contains, the second states when to use it. Nothing is wasted and the purpose 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 read-only list of one optional filter parameter, the definition covers purpose, contents, and usage adequately, and an output schema exists so return structure need not be explained. Only pagination or result-size behavior is unaddressed, a minor 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?
There is a single optional parameter, min_orders, whose schema description ('Only list products with at least this many orders') is complete at 100% coverage. The description does not reference this filter at all, so it adds no meaning beyond the schema; baseline 3 applies.
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+resource ('List the product codes present in the loaded snapshot') and even specifies the returned fields (order counts, price/cost availability). It implicitly routes the agent away from the measuring sibling by framing itself as the step 'before measuring', so an agent can distinguish it from measure_sku_funnel.
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 context cues: 'Use to resolve a product code before measuring, or to see what the dataset covers.' That covers the two main situations for calling it. It does not name a specific alternative sibling or state when not to use it, keeping it short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
measure_sku_funnelMeasure a product's funnelARead-only
Measure the observed call-centre approval, post-office buyout, and return rates for one product over a date window, counting only order cohorts old enough to have resolved. Use this before any decision that depends on approval or buyout rates, instead of assuming the portfolio-wide 65% approval and 52.5% buyout. Returns rates together with sample size and a reliability flag, and returns null rates with reliability 'insufficient' rather than a number when the resolved sample is too small to support a conclusion. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| sku | Yes | Product code as it appears in the snapshot, e.g. 21-183 | |
| window_to | No | ISO date YYYY-MM-DD; defaults to the snapshot date | |
| window_from | No | ISO date YYYY-MM-DD; defaults to the snapshot start | |
| maturity_days | No | Days an order must be old before it counts as resolved. Defaults to FC_COHORT_MATURITY_DAYS (21). Range 0–90. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sku | Yes | |
| leads | Yes | |
| window | Yes | |
| refused | Yes | |
| approved | Yes | |
| bought_out | Yes | |
| min_sample | Yes | |
| buyout_rate | Yes | |
| reliability | Yes | |
| return_rate | Yes | |
| approval_rate | Yes | |
| cohort_cutoff | Yes | |
| maturity_days | Yes | |
| resolved_orders | Yes | |
| shipped_resolved | Yes | |
| excluded_in_flight | Yes | |
| excluded_still_moving | Yes | |
| snapshot_generated_at | Yes | |
| excluded_awaiting_call | Yes | |
| excluded_immature_cohort | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces 'Read-only' while adding real behavioral context: only mature/resolved cohorts are counted, null is returned with reliability 'insufficient' when the sample is too small, and results include sample size and a reliability flag. That is meaningful disclosure beyond 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?
Front-loaded with the core action and scope, followed by usage guidance and return behavior; every sentence carries information. It runs slightly long, but nothing is redundant padding.
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 enumerate return fields, and it still covers usage, cohort maturity, small-sample handling, and read-only status. Nothing an agent needs to call this 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 coverage is 100%, so the baseline is 3, but the description adds conceptual meaning to the parameters by explaining that only cohorts 'old enough to have resolved' are counted, which clarifies the role of maturity_days and the window parameters beyond the raw ISO-date 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?
States a specific verb (measure) and resource (call-centre approval, post-office buyout, and return rates for one product) with explicit scope (date window, resolved cohorts only). An agent can distinguish this from the sibling tools without opening any 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?
Gives clear when-to-use guidance: 'before any decision that depends on approval or buyout rates, instead of assuming the portfolio-wide 65% approval and 52.5% buyout.' It does not name a sibling alternative, but the triggering condition is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recalibrate_cpl_boundsRecalibrate CPL boundsARead-only
Recompute Stop CPL (the cost per lead at which profit reaches zero) and Goal CPL (the optimisation target) for one product from its own measured funnel rates instead of portfolio-wide assumptions, and report the drift against the baseline currently in use. Measures the product itself when observed rates are not supplied. Use whenever a cost-per-lead target is being set, defended, or questioned. Flags the case where the assumed target sits above the true break-even, which is invisible in the ads dashboard. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| sku | Yes | Product code, e.g. 21-183 | |
| usd_uah | No | Hryvnia per US dollar; defaults to the product's rate | |
| window_to | No | ISO date, used only when measuring on demand | |
| window_from | No | ISO date, used only when measuring on demand | |
| observed_buyout | No | Measured buyout rate 0–1; measured on demand when omitted | |
| observed_approval | No | Measured approval rate 0–1; measured on demand when omitted |
Output Schema
| Name | Required | Description |
|---|---|---|
| sku | Yes | |
| drift_pct | Yes | |
| inputs_used | Yes | |
| rate_source | Yes | |
| reliability | Yes | |
| observed_rates | Yes | |
| resolved_orders | Yes | |
| structural_loss | Yes | |
| contribution_uah | Yes | |
| goal_cpl_assumed | Yes | |
| stop_cpl_assumed | Yes | |
| goal_cpl_observed | Yes | |
| stop_cpl_observed | Yes | |
| economics_reliable | Yes | |
| target_above_breakeven | Yes | |
| contribution_uah_assumed | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description confirms 'Read-only.' Parity there. The description adds real behavior: it falls back to measuring the product itself when rates are omitted, and it reports drift vs. the current baseline. It does not disclose cost/latency of on-demand measurement, keeping it out of the 5.
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 sentences, each load-bearing: what is computed, the source substitution, the fallback, the trigger, and the flag. Verb+resource is front-loaded, and 'Read-only' is correctly placed last as a closing guarantee.
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 explanations are unnecessary. For a 6-param read-only tool the description covers purpose, fallback behavior, and the business flag adequately. It omits when observed_* should be supplied vs. left null (beyond 'when omitted'), a minor 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%, so each parameter is documented in the schema. The description adds only the fallback semantics ('measured on demand when omitted'), which is already stated per-param in the schema. It does not explain the observed_* vs. window_* interaction beyond that. Baseline 3 applies.
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 (recompute) and two named resources (Stop CPL, Goal CPL), defines each parenthetically in business terms, and distinguishes the computation source ('from its own measured funnel rates instead of portfolio-wide assumptions'). An agent can separate this from siblings like measure_sku_funnel.
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?
Explicit trigger: 'Use whenever a cost-per-lead target is being set, defended, or questioned.' Names the specific alert condition it surfaces (assumed target above true break-even, invisible in the ads dashboard). No sibling is named as an alternative, but the when-to-use clause is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_next_actionRecommend the next advertising actionARead-only
Diagnose why a product is underperforming and return the matching remedy. Given the product's measured funnel, its current cost per lead, and optional competitor and creative signals, identifies the likeliest failure mode — structural loss, contested auction, traffic quality, offer or price mismatch, creative fatigue, or a weak offer — and returns the action that fits it. Use when a campaign misses its target and the cause is not yet established, because cheap leads that fail on the call and leads that fail at the post office need opposite remedies. Returns action 'hold' with diagnosis 'insufficient_data' rather than guessing when the sample is too small. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| sku | Yes | Product code, e.g. 21-183 | |
| window_to | No | ISO date | |
| current_cpl | Yes | Current cost per lead in USD | |
| window_from | No | ISO date | |
| cpl_trend_days | No | Days the current cost per lead has held | |
| competitor_active | No | Whether a known competitor is bidding on this product | |
| creative_ctr_trend | No | Change in click-through rate; negative means falling | |
| creative_frequency | No | Meta frequency for the running creative |
Output Schema
| Name | Required | Description |
|---|---|---|
| sku | Yes | |
| action | Yes | |
| evidence | Yes | |
| priority | Yes | |
| diagnosis | Yes | |
| rationale | Yes | |
| confidence | Yes | |
| measurement | Yes | |
| breakeven_condition | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the closing 'Read-only' is redundant. However, the description adds real behavioral context beyond the annotations: the diagnosis taxonomy it applies, the signals it consumes, and the fallback behavior ('hold' with 'insufficient_data') instead of a forced recommendation. That fallback is the kind of trait an agent cannot infer from structured fields.
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?
Front-loads the purpose in the first sentence, then layers the failure taxonomy, the usage trigger, and the fallback rule in a logical order. The 'call vs. post office' analogy consumes a clause that is illustrative rather than strictly load-bearing, and the trailing 'Read-only' duplicates the annotation, so it is dense but not maximally tight.
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 document return fields, and it correctly only hints at the shape ('action hold', 'diagnosis insufficient_data'). Given 8 parameters at full schema coverage plus annotations, nearly everything an agent needs to call this correctly is present; only explicit sibling routing is absent.
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% across all 8 parameters, so the schema already defines sku, current_cpl, window_*, cpl_trend_days, competitor_active and the creative signals. The description only gestures at them collectively ('measured funnel, its current cost per lead, and optional competitor and creative signals') without adding format, units, or interaction semantics. Baseline 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?
States a specific verb and resource ('Diagnose why a product is underperforming and return the matching remedy') and enumerates the exact failure modes it distinguishes (structural loss, contested auction, traffic quality, offer or price mismatch, creative fatigue, weak offer). An agent can tell this apart from measure_sku_funnel or audit_ad_verdict, which measure or judge rather than prescribe a remedy.
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?
Gives an explicit trigger ('Use when a campaign misses its target and the cause is not yet established') and a justification for the tool's existence (opposite remedies for leads that fail on the call vs. at the post office). It also states a boundary condition — returns 'hold'/'insufficient_data' rather than guessing on small samples. It stops short of naming sibling tools as alternatives, so it is clear context without explicit routing.
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.
5 tool updates
v0.1.0- First observed
audit_ad_verdict - First observed
list_covered_skus - First observed
measure_sku_funnel - First observed
recalibrate_cpl_bounds - First observed
recommend_next_action
TDQS
Scored across 5 tools
Each tool targets a distinct decision stage: listing covered SKUs, measuring observed funnel rates, recalibrating CPL bounds, recommending remedies, and auditing external verdicts. The two diagnostic tools (recommend_next_action and audit_ad_verdict) are clearly separated by whether the decision originated from this server or elsewhere. No overlapping or indistinguishable purposes.
All tools use a consistent snake_case verb_noun pattern (measure_sku_funnel, recalibrate_cpl_bounds, recommend_next_action, audit_ad_verdict, list_covered_skus). The convention is predictable and readable throughout.
Five tools is well-scoped for a specialized funnel calibration server. Each tool earns its place: discovery, measurement, recalibration, diagnosis, and verification. There is no redundancy or thin surface.
The surface covers the full read-only analytics lifecycle from listing SKUs to auditing external decisions, with sensible fallbacks for insufficient data. A minor gap is the absence of a dedicated tool to fetch or compare the current portfolio-wide baseline assumptions, though descriptions imply those are internally available.
Maintenance
Related MCP Connectors
Verified commerce data and proof-backed shopper activation tools for agents.
Commerce intelligence for AI agents. Diagnose drop-offs, fix checkouts, optimize pricing.
The hidden intelligence for AI marketing agents. Real campaign data, not LLM guesses.
Ecommerce conversion for coding agents: AOV bundles, cart, upsell, imagery, page audit.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceExposes product analytics metrics from an internal data warehouse via MCP, enabling agents to query metrics, product summaries, and event breakdowns.-
- AlicenseNot gradedqualityCmaintenanceEnables evaluation of digital marketplaces by classifying demand signals, scoring commercial viability, sanity-checking claims, and comparing candidate channels.Academic Free v1.1
- AlicenseNot gradedqualityBmaintenanceEnables agents to turn customer conversations into provably correct remodeling quotes by extracting catalog-bounded line items with evidence and calculating prices deterministically.MIT
- AlicenseNot gradedqualityCmaintenanceEnables agents to query historical call-center call reason notes and tags on demand, detect statistically significant emerging problem spikes against baselines, and evaluate automated categorizers against ground truth.MIT