plate-cost
plate-cost
Una MCP App que calcula el coste de las recetas y pone precio a los platos del menú: una calculadora interactiva que el modelo abre en lugar de hacer él mismo la aritmética.
Pídele a Claude «ayúdame a poner precio a mi nasi goreng» y obtendrás una hoja de cálculo funcional: filas de ingredientes, precios de compra, porcentajes de merma, rendimiento por porción, un control deslizante de margen. Cambia un número y todo se recalcula. Pulsa Usar estos números y el modelo continúa la conversación con las cifras que has introducido tú, no con las que él haya inventado.
Construido sobre MCP Apps (ext-apps).

Se ejecuta en el host de referencia basic-host de ext-apps — no en Claude. El modelo propuso la receta, el widget la cargó, y «Usar estos números» envió las cifras corregidas de vuelta a la conversación.
Por qué esto es una app y no una herramienta
Calcular costes es exploración, no una pregunta. No sabes qué respuesta quieres hasta que has movido el tamaño de la ración y has visto moverse el margen. El chat es una mala interfaz para eso, y un modelo haciendo la aritmética mentalmente es peor: los LLM no son fiables en trabajo numérico de varios pasos, pero son completamente fiables a la hora de sonar seguros de sí mismos.
Así que la división es: el widget captura las entradas, el servidor hace las cuentas, el modelo habla.
Related MCP server: ScenarioSim MCP
La parte interesante: saber de dónde vienen los números
MCP Apps tiene un vacío abierto — ext-apps#746: una tools/call desde un widget y una que el modelo decidió hacer son indistinguibles en el servidor. Para la mayoría de las herramientas eso no importa. Para una herramienta de costes, decide si estás haciendo aritmética o maquillando una conjetura.
mcp-app-attest lo cierra — extraído de este repositorio, que es su primer consumidor. El servidor acuña un token de corta duración cada vez que sirve el recurso de la app y lo sustituye en el documento; el widget lo devuelve en _meta en cada llamada. El modelo nunca ve el cuerpo del recurso, por lo que no puede generar el token. Las llamadas se responden de todas formas — la respuesta indica cuál ha recibido:
{ "perPortion": 3300, "inputsFrom": "model" }y cuando las cifras proceden del modelo, la respuesta de texto lo dice:
Nota: estas cifras provienen del modelo, no de la calculadora. Confirme los precios de compra con el usuario antes de confiar en ellas.
Verificado de extremo a extremo contra el host de referencia, no solo en pruebas unitarias:
[provenance] inputsFrom=model reason=missing meta=null
[provenance] inputsFrom=app meta={..."io.platecost/app-attestation":"XfqGVAiP…"}Lo que esto no es. No es autorización, ni prueba de que un humano haya tecleado nada. Distingue rutas de código, no identidades. Si un host copia el texto del recurso al contexto del modelo, el modelo puede leer el token — nada aquí lo impide; es el contrato que el host debe mantener. Un widget comprometido puede enviar lo que quiera. Trátalo como la diferencia entre «escrito en mi formulario» y «producido por un modelo de lenguaje», que es exactamente lo que pide #746.
Desde entonces se ha extraído en mcp-app-attest, que pasó a usar tokens firmados en lugar de almacenados — véase la nota de «lo que no funcionó» más abajo para saber por qué.
Dos cosas en las que el dominio se equivoca
Ambas están en src/costing.ts y ambas tienen pruebas.
La merma significa comprar más, no usar más. El coste es used / (1 - wastePct), no used * (1 + wastePct). Con un 50 % de merma se compra el doble, no una vez y media. La versión ingenua subestima todos tus ingredientes con merma.
El margen y el recargo son números diferentes. El margen es (price - cost) / price; el recargo es (price - cost) / cost. Un recargo del 60 % es un margen del 37,5 %, y un margen del 60 % necesita un recargo del 150 %. priceForMargin toma el margen — que es lo que significa «queremos un 65 %» en una cocina — y devuelve ambos, para que la diferencia sea visible en lugar de asumida.
También se maneja: conversión de unidades dentro de las familias de masa y volumen, con un rechazo entre ellas (kg → l necesita una densidad que no has dado), la parte del coste por ingrediente y los gastos generales aplicados por ración en lugar de por lote.
Pruébalo
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 hostApunta un cliente MCP a server.ts. Fuera de un host, el marcador de posición de atestación nunca se sustituye, por lo que las llamadas se etiquetan como model — que es la respuesta honesta.
Lo que no funcionó
Un transporte HTTP sin estado. La primera versión creaba un servidor nuevo por petición, lo cual está bien para herramientas sin estado, pero rompe esta en silencio: la atestación se acuñaba en una instancia del servidor que ya no existía cuando el widget respondía, así que cada llamada del widget era rechazada como
unknown. Las pruebas en memoria no podían verlo — comparten una única instancia. Solo al ejecutarlo contra un host real salió a la luz.Culpar al SDK. Antes de encontrar lo anterior, el sospechoso obvio era que
_metase eliminaba en tránsito. No es así: el host de referencia lo reenvía intacto a través del proxy de sandbox. Merece la pena saberlo, porque todo el mecanismo depende de que los hosts lo hagan y la especificación no lo exige.
Estado
v0. Dos herramientas (cost-recipe, price-portion), un widget, 21 pruebas.
No construido: persistencia entre conversaciones, comparación de varias recetas y cualquier cosa que toque el problema de espacios de nombres en
#753 /
#745 — callServerTool
utiliza nombres de herramienta sin calificar, por lo que esto se romperá detrás de un agregador. Esa es la próxima cuestión que merece la pena resolver y no está resuelta aquí.
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.
Maintenance
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