Skip to main content
Glama
rephol

plate-cost

by rephol

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

plate-cost läuft im Referenzhost von 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: TradingCalc MCP Server

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 (kgl 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 host

Richte 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 unknown abgelehnt 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 _meta wä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.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides basic arithmetic operations and advanced mathematical functions through the Model Context Protocol (MCP), with features like calculation history tracking and expression evaluation.
    1
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides deterministic trading calculations for PnL, risk, margin, and funding, enabling users to get exact numbers for trade planning and risk assessment via MCP or REST API.
    11
    1
    MIT
  • A
    license
    C
    quality
    B
    maintenance
    Deterministic Odoo ERP calculators: implementation, migration and upgrade cost, ROI and TCO, US/Canada/EU sales tax and VAT, Canadian payroll source deductions, and inventory maths (reorder point, safety stock, EOQ, landed cost, OEE). 24 tools, each a pure function, the numbers are arithmetic rather than a model's guess. Hosted remote server, no install and no API key; a stdio bridge is included
    24
    MIT
  • A
    license
    A
    quality
    A
    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
    47
    MIT

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/rephol/plate-cost'

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