Skip to main content
Glama
rephol

plate-cost

by rephol

plate-cost

MCP-приложение, которое калькулирует себестоимость рецептов и устанавливает цены на позиции меню — интерактивный калькулятор, который модель открывает вместо того, чтобы самой выполнять арифметику.

Спросите Клода «помоги мне рассчитать цену моего наси горенг» — и вы получите рабочую таблицу: строки ингредиентов, закупочные цены, процент отходов, выход порции, ползунок наценки. Измените число — всё пересчитается. Нажмите Использовать эти числа — и модель продолжит разговор с цифрами, которые ввели вы, а не с теми, что она выдумала.

Построено на MCP Apps (ext-apps).

plate-cost в референсном хосте ext-apps

Работает в референсном хосте basic-host из ext-apps — не в Клоде. Модель предложила рецепт, виджет загрузил его, а «Использовать эти числа» отправило исправленные цифры обратно в разговор.

Почему это приложение, а не инструмент

Калькуляция — это исследование, а не вопрос. Вы не знаете, какой ответ вам нужен, пока не подвинете размер порции и не посмотрите, как движется маржа. Чат — плохой интерфейс для этого, а модель, считающая в уме, — ещё хуже: LLM ненадёжны в многошаговых числовых операциях и абсолютно надёжны в уверенном звучании.

Поэтому разделение такое: виджет собирает ввод, сервер делает математику, модель ведёт разговор.

Related MCP server: ScenarioSim MCP

Интересная часть: знание, откуда взялись числа

В MCP Apps есть открытый пробел — ext-apps#746: вызов tools/call из виджета и вызов, который решила сделать модель, неразличимы на сервере. Для большинства инструментов это неважно. Для инструмента калькуляции это решает, выполняете ли вы арифметику или отмываете догадку.

mcp-app-attest закрывает этот пробел — извлечён из этого репозитория, который стал его первым потребителем. Сервер выпускает короткоживущий токен каждый раз, когда отдаёт ресурс приложения, и подставляет его в документ; виджет возвращает его в _meta при каждом вызове. Модель никогда не видит тело ресурса, поэтому не может создать токен. Вызовы получают ответ в любом случае — в ответе указано, какой именно:

{ "perPortion": 3300, "inputsFrom": "model" }

а когда числа пришли от модели, текстовый ответ говорит об этом:

Примечание: эти цифры получены от модели, а не из калькулятора. Подтвердите закупочные цены у пользователя, прежде чем полагаться на них.

Проверено сквозным образом на референсном хосте, а не только в юнит-тестах:

[provenance] inputsFrom=model  reason=missing  meta=null
[provenance] inputsFrom=app    meta={..."io.platecost/app-attestation":"XfqGVAiP…"}

Чем это не является. Это не авторизация и не доказательство того, что человек что-то вводил. Это различает пути кода, а не личности. Если хост копирует текст ресурса в контекст модели, модель может прочитать токен — ничто здесь этому не препятствует, это контракт хоста — сохранять это. Скомпрометированный виджет может отправить что угодно. Относитесь к этому как к разнице между «введено в мою форму» и «создано языковой моделью» — именно это и требуется в #746.

С тех пор это было извлечено в mcp-app-attest, который перешёл на подписанные токены вместо хранимых — см. примечание «что не сработало» ниже, почему.

Две вещи, в которых домен ошибается

Обе находятся в src/costing.ts, обе имеют тесты.

Отходы означают покупать больше, а не использовать больше. Стоимость равна used / (1 - wastePct), а не used * (1 + wastePct). При 50% отходов вы покупаете вдвое, а не в полтора раза. Наивная версия занижает каждый обрезанный ингредиент, который у вас есть.

Маржа и наценка — разные числа. Маржа — это (price - cost) / price; наценка — (price - cost) / cost. Наценка 60% — это маржа 37,5%, а маржа 60% требует наценки 150%. priceForMargin принимает маржу — именно это означает «мы хотим 65%» на кухне — и возвращает оба значения, так что разрыв виден, а не предполагается.

Также обрабатывается: преобразование единиц внутри семейств массы и объёма с отказом между ними (kg → l требует плотность, которую вы не указали), доля стоимости на ингредиент и накладные расходы, применяемые на порцию, а не на партию.

Попробуйте

npm install
npm run build      # bundles the widget to a single inlined HTML
npm test           # 21 tests
npm run dev        # widget standalone in a browser, no host

Укажите MCP-клиенту на server.ts. Вне хоста плейсхолдер аттестации никогда не подставляется, поэтому вызовы помечаются как model — это честный ответ.

Что не сработало

  • Транспорт без сохранения состояния по HTTP. Первая версия создавала новый сервер на каждый запрос, что нормально для инструментов без состояния и молча ломает этот: аттестация выпускалась экземпляром сервера, которого уже не существовало, когда виджет делал обратный вызов, поэтому каждый вызов виджета отклонялся как unknown. Тесты в памяти не могли этого увидеть — они используют один экземпляр. Только работа с реальным хостом выявила это.

  • Обвинение SDK. Прежде чем найти вышеуказанное, очевидным подозреваемым было то, что _meta теряется при передаче. Это не так: референсный хост пересылает его без изменений через прокси песочницы. Это стоит знать, потому что весь механизм зависит от того, что хосты так делают, а спецификация этого не требует.

Статус

v0. Два инструмента (cost-recipe, price-portion), один виджет, 21 тест.

Не реализовано: сохранение между разговорами, сравнение нескольких рецептов и всё, что касается проблемы пространства имён в #753 / #745 — callServerTool использует голые имена инструментов, поэтому это сломается за агрегатором. Это следующая задача, которую стоит решить, и здесь она не решена.

MIT.

Available Tools

2 tools
cost-recipeCost a recipeB

Cost one batch of a recipe and one portion of it, given ingredient purchase prices, quantities used, waste percentages and portion yield. Opens an interactive calculator. Do not compute food costs yourself — call this.

NameRequiredDescriptionDefault
nameYes
ingredientsYes
yieldPortionsYes
overheadPerPortionNo

Output Schema

NameRequiredDescription
perBatchYes
breakdownYes
inputsFromYes
perPortionYes
overheadPerPortionYes
ingredientCostPerPortionYes

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden, but it does disclose a meaningful behavioral trait: the tool 'opens an interactive calculator' rather than silently returning a number, and it warns against self-computation. It omits any note on side effects, permissions, or whether the interactive session blocks, and an output schema covers the return payload.

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?

Three short sentences, front-loaded with the core action and ending on the key directive. Every sentence carries content, though the fragments 'given…' and the calculator note could be tightened.

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

Completeness3/5

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 no explanation, and the description covers the main input concepts. It still leaves overheadPerPortion undocumented and provides no basis for choosing between this tool and price-portion, which is a real gap for a 4-parameter tool with an undocumented optional field.

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

Parameters3/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. It does name the ingredient-side concepts (purchase prices, quantities used, waste percentages, portion yield), mapping to four of the parameters, but the optional overheadPerPortion parameter is never mentioned and no unit/format semantics are clarified.

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

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('cost one batch of a recipe and one portion') plus the key input categories, which is more than a restatement of the name. It does not, however, differentiate itself from the sibling price-portion, so an agent cannot tell the two apart from the description alone.

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

Usage Guidelines3/5

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

Explicitly directs the agent to use this tool rather than computing food costs itself ('Do not compute food costs yourself — call this'), which is genuine usage guidance. It offers no condition for preferring this over the sibling price-portion, so routing between the two is left to inference.

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

price-portionPrice a portionA

Turn a portion cost into a selling price at a target margin, and report margin, markup and food-cost percentage. Margin and markup are different numbers — call this rather than converting between them yourself.

NameRequiredDescriptionDefault
costYes
priceNo
targetMarginPctNo

Output Schema

NameRequiredDescription
costYes
priceYes
profitYes
marginPctYes
markupPctYes
foodCostPctYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations, so the description carries the burden. It discloses the computed outputs (margin, markup, food-cost percentage) and warns about margin/markup confusion, but says nothing about required inputs, error behavior, or how cost/price/targetMarginPct interact (e.g., whether price overrides targetMarginPct).

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

Conciseness5/5

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

Two tight sentences, front-loaded with the core action and ending on the key disambiguation. No wasted words.

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

Completeness4/5

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

Output schema exists, so return-value detail is unnecessary. The description covers the tool's purpose and usage warning but is thin on the input parameter interaction (price vs targetMarginPct) given 0% schema coverage.

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

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It clarifies the semantic dependency of the three fields implicitly (cost in, target margin or price out) and defines margin/markup, partially compensating. However, it doesn't explain the precedence between providing 'price' vs 'targetMarginPct'.

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?

States a specific verb (price) and resources (portion cost → selling price) and the exact computation (target margin, reporting margin/markup/food-cost %). Distinguishes from sibling cost-recipe by being about pricing rather than costing a recipe.

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?

Gives a clear conditional steer: 'call this rather than converting between them yourself' for margin vs markup conversion, implying when-to-use over manual math. No explicit exclusion vs cost-recipe, but context is clear.

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.

  1. 2 tool updatesv0.1.0
    • First observedcost-recipe
    • First observedprice-portion

TDQS

A3.5/5.0

Scored across 2 tools

Disambiguation4/5

The two tools have distinct purposes: costing a recipe versus converting a cost into a selling price. There is minor thematic overlap around food-cost math, but each description clarifies the boundary.

Naming Consistency3/5

Both names use a noun_noun or verb_noun style ('cost-recipe', 'price-portion') with hyphenation, but the verb-first pattern is only loosely applied and not fully predictable.

Tool Count3/5

Two tools is thin for a costing/pricing domain; it may be intentionally narrow, but it is borderline for useful coverage.

Completeness3/5

The surface covers recipe costing and portion pricing, but lacks operations for managing ingredients, recipes, or price lists, creating notable gaps for a full workflow.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides hospitality intelligence tools for restaurant optimization, including menu profitability analysis, food cost calculation, reservation management, review sentiment analysis, and allergen checking.
    6 npm
    37 PyPI
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A deterministic what-if scenario simulation MCP server that projects business metrics over time with exact decimal arithmetic, offering sensitivity analysis and break-even solving.
    6
    36 npm
    1
    MIT