plate-cost
plate-cost
Eine MCP App, die Rezepte kalkuliert und Menüpunkte bepreist — ein interaktiver Rechner, den das Modell öffnet, statt die Rechenarbeit selbst zu erledigen.
Frag Claude „hilf mir, mein nasi goreng zu bepreisen“ und du bekommst eine funktionierende Tabelle: Zutatenzeilen, Einkaufspreise, Abfallprozente, Portionsausbeute, einen Margin-Regler. Änderst du eine Zahl, wird alles neu berechnet. Drücke Diese Zahlen übernehmen und das Modell führt das Gespräch mit den von dir eingegebenen Zahlen fort, statt mit Zahlen, die es erfunden hat.
Basierend auf MCP Apps (ext-apps).

Läuft im basic-host-Referenzhost von ext-apps — nicht Claude. Das Modell hat das Rezept vorgeschlagen, das Widget hat es geladen, und „Diese Zahlen übernehmen“ hat die korrigierten Zahlen zurück ins Gespräch geschickt.
Warum es eine App und kein Tool ist
Kalkulation ist Erkundung, keine Frage. Du weißt nicht, welche Antwort du willst, bis du die Portionsgröße bewegt und beobachtet hast, wie sich die Marge bewegt. Chat ist dafür eine schlechte Oberfläche, und ein Modell, das die Rechenarbeit im Kopf macht, ist noch schlimmer — LLMs sind bei mehrstufiger numerischer Arbeit unzuverlässig und absolut zuverlässig darin, überzeugt zu klingen.
Die Aufteilung ist also: Das Widget erfasst die Eingaben, der Server rechnet, das Modell redet.
Related MCP server: ScenarioSim MCP
Der interessante Teil: zu wissen, woher die Zahlen kommen
MCP Apps hat eine offene Lücke — ext-apps#746: ein tools/call von einem Widget und eines, das das Modell aus eigener Entscheidung macht, sind auf dem Server nicht zu unterscheiden. Für die meisten Tools spielt das keine Rolle. Bei einem Kalkulationstool entscheidet es, ob du rechnest oder eine Vermutung legitimierst.
mcp-app-attest schließt sie — extrahiert aus diesem Repo, das sein erster Nutzer ist. Der Server erzeugt jedes Mal, wenn er die App-Ressource ausliefert, ein kurzlebiges Token und setzt es in das Dokument ein; das Widget sendet es bei jedem Aufruf in _meta zurück. Das Modell sieht den Ressourcentext nie, also kann es das Token nicht erzeugen. Aufrufe werden in jedem Fall beantwortet — die Antwort sagt, welcher Fall es war:
{ "perPortion": 3300, "inputsFrom": "model" }und wenn die Zahlen vom Modell stammen, sagt die Textantwort das auch:
Hinweis: Diese Zahlen stammen vom Modell, nicht vom Rechner. Bestätige die Einkaufspreise mit dem Benutzer, bevor du dich auf sie verlässt.
Ende-zu-Ende gegen den Referenzhost verifiziert, nicht nur in Unit-Tests:
[provenance] inputsFrom=model reason=missing meta=null
[provenance] inputsFrom=app meta={..."io.platecost/app-attestation":"XfqGVAiP…"}Was es nicht ist. Keine Autorisierung und kein Beweis, dass ein Mensch etwas eingegeben hat. Es unterscheidet Codepfade, nicht Identitäten. Wenn ein Host den Ressourcentext in den Modellkontext kopiert, kann das Modell das Token lesen — nichts hier verhindert das; es ist Sache des Hosts, das zu unterlassen. Ein kompromittiertes Widget kann senden, was es will. Behandle es als den Unterschied zwischen „in mein Formular eingegeben“ und „von einem Sprachmodell erzeugt“ — genau das verlangt #746.
Es wurde inzwischen in mcp-app-attest extrahiert, das auf signierte Token umgestellt hat statt auf gespeicherte — siehe dazu die Anmerkung „Was nicht funktioniert hat“ weiter unten.
Zwei Dinge, die die Domäne falsch macht
Beide stehen in src/costing.ts, beide haben Tests.
Abfall bedeutet, mehr zu kaufen, nicht mehr zu verwenden. Die Kosten sind used / (1 - wastePct), nicht used * (1 + wastePct). Bei 50 % Abfall kaufst du doppelt so viel, nicht anderthalbmal so viel. Die naive Version unterschätzt jede Zutat mit Verschnitt, die du besitzt.
Marge und Aufschlag sind unterschiedliche Zahlen. Die Marge ist (price - cost) / price; der Aufschlag ist (price - cost) / cost. Ein Aufschlag von 60 % ist eine Marge von 37,5 %, und eine Marge von 60 % erfordert einen Aufschlag von 150 %. priceForMargin nimmt die Marge als Parameter — das ist es, was „wir wollen 65 %“ in einer Küche bedeutet — und liefert beides, sodass die Lücke sichtbar statt nur angenommen wird.
Ebenfalls behandelt: Einheitenumrechnung innerhalb der Familien Masse und Volumen, wobei eine Umrechnung zwischen ihnen abgelehnt wird (kg → l benötigt eine Dichte, die du nicht angegeben hast), Kostenanteil pro Zutat und Gemeinkosten, die pro Portion statt pro Charge angewendet werden.
Ausprobieren
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 hostRichte einen MCP-Client auf server.ts aus. Außerhalb eines Hosts wird der Attestierungs-Platzhalter nie ersetzt, daher werden Aufrufe als model gekennzeichnet — das ist die ehrliche Antwort.
Was nicht funktioniert hat
Ein zustandsloser HTTP-Transport. Die erste Version baute pro Anfrage einen neuen Server, was für zustandslose Tools in Ordnung ist und dieses hier unbemerkt bricht: Die Attestierung wurde von einer Serverinstanz erzeugt, die nicht mehr existierte, als das Widget zurückrief, sodass jeder Widget-Aufruf als
unknownabgelehnt wurde. Die In-Memory-Tests konnten das nicht sehen — sie teilen sich eine Instanz. Erst der Lauf gegen einen echten Host hat es offengelegt.Dem SDK die Schuld zu geben. Bevor ich das Obige fand, war der naheliegende Verdächtige, dass
_metawährend der Übertragung entfernt wird. Das ist nicht der Fall: Der Referenzhost leitet es unversehrt durch den Sandbox-Proxy weiter. Wissenswert, weil der gesamte Mechanismus davon abhängt, dass Hosts das tun, und die Spezifikation es nicht verlangt.
Status
v0. Zwei Tools (cost-recipe, price-portion), ein Widget, 21 Tests.
Nicht gebaut: Persistenz zwischen Gesprächen, der Vergleich mehrerer Rezepte und alles, was das Namespace-Problem in #753 / #745 berührt — callServerTool verwendet nackte Toolnamen, daher wird das hinter einem Aggregator brechen. Das ist das Nächste, was es zu lösen lohnt, und es ist hier nicht gelöst.
MIT.
Available Tools
2 toolscost-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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| ingredients | Yes | ||
| yieldPortions | Yes | ||
| overheadPerPortion | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| perBatch | Yes | |
| breakdown | Yes | |
| inputsFrom | Yes | |
| perPortion | Yes | |
| overheadPerPortion | Yes | |
| ingredientCostPerPortion | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| cost | Yes | ||
| price | No | ||
| targetMarginPct | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| cost | Yes | |
| price | Yes | |
| profit | Yes | |
| marginPct | Yes | |
| markupPct | Yes | |
| foodCostPct | Yes |
TDQS
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.
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.
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.
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.
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.
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.
2 tool updates
v0.1.0- First observed
cost-recipe - First observed
price-portion
TDQS
Scored across 2 tools
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.
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.
Two tools is thin for a costing/pricing domain; it may be intentionally narrow, but it is borderline for useful coverage.
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.
Related MCP Connectors
The brain for restaurant costs, pricing, and true profit (read/edit menu, recipes, costs).
Read-only kitchen costing, recipe scaling, UK GP, starter menus, and prep lists for chefs.
Auditable construction takeoffs with locked waste and conservative purchase rounding.
Read recipes, nutrition and inventory, manage ingredients and costs, and render ReciPal labels.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceProvides hospitality intelligence tools for restaurant optimization, including menu profitability analysis, food cost calculation, reservation management, review sentiment analysis, and allergen checking.6 npm37 PyPIMIT
- AlicenseAqualityCmaintenanceA deterministic what-if scenario simulation MCP server that projects business metrics over time with exact decimal arithmetic, offering sensitivity analysis and break-even solving.636 npm1MIT
- FlicenseNot gradedqualityDmaintenanceEnables precise financial analysis of AI agent costs, including token pricing, multi-step run estimates, model comparison, and ROI versus human labor, with deterministic decimal math.-
- AlicenseAqualityBmaintenanceEnables deterministic recipe and portion math with USDA-sourced macros, gram conversions, cooked yields, and per-eater portions.12MIT