MCP Fusion/Core concepts/Models und Presenters

Models und Presenters

Frag die KI über Vinkius

Deklarieren Sie Ihre Domäne einmal mit defineModel und gestalten Sie, was der Agent mit createPresenter wahrnimmt: Schemas, Rules, Schwärzung, UI-Blöcke, Affordances und Limits.

Models und Presenters sind das M und das V von the MVA pattern. Das Model deklariert Ihre Domäne einmal. Der Presenter formt die Wahrnehmung dieser Domäne für den Agenten. Die Trennung ist bewusst: dasselbe Model kann mehrere Presenter haben, einen pro Zielgruppe oder Aufgabe.

Models

typescript
import { defineModel } from '@mcpfusion/core';

const InvoiceModel = defineModel('Invoice', (m) => {
  m.casts({ amount_cents: 'number' });
  m.hidden(['internal_notes', 'cost_basis']);
  m.guarded(['id', 'created_at']);
  m.fillable({
    create: ['customer_id', 'amount_cents', 'due_date'],
    update: ['status'],
  });
});
  • .casts(): Typumwandlungen, die beim Lesen angewendet werden
  • .hidden(): Felder, die den Server nie verlassen, nicht einmal in der Debug-Ausgabe
  • .guarded(): Felder, die der Agent nicht schreiben kann
  • .fillable(): die einzigen Felder, die jede Operation schreiben darf

Alles, was Sie nicht deklarieren, existiert für den Agenten schlicht nicht. Das Model kompiliert zu einem Zod-Schema, sodass InvoiceModel.schema Eingaben validiert und typeof InvoiceModel.infer Ihnen den TypeScript-Typ liefert.

.describe()-Annotationen an Feldern werden automatisch extrahiert und zu Systemregeln für den Agenten, sodass die Bedeutung des Feldes mit dem Feld reist.

Presenters

typescript
import { createPresenter, t, suggest, ui } from '@mcpfusion/core';

const InvoicePresenter = createPresenter('Invoice')
  .schema({
    id: t.string,
    customer: t.string,
    amount_cents: t.number.describe('CENTS, divide by 100'),
    status: t.enum('draft', 'paid', 'overdue'),
  })
  .rules([
    'CRITICAL: amount_cents is in CENTS. Divide by 100.',
  ])
  .redactPII(['customer.email', 'customer.ssn'])
  .ui((inv) => [
    ui.table(['Field', 'Value'], [
      ['Invoice', inv.id],
      ['Amount', inv.amount_cents / 100],
      ['Status', inv.status],
    ]),
  ])
  .suggest((inv) => [
    inv.status === 'overdue'
      ? suggest('billing.remind', 'Send a payment reminder')
      : null,
  ])
  .limit(50);

Die Builder-Methoden

MethodeWas sie macht
.schema()Die Felder, die für den Agenten existieren, mit t-Typen und Beschreibungen
.rules()Systemprompt-Zeilen, die in jede Antwort dieses Presenters injiziert werden
.redactPII()Feldpfade, die vor der Serialisierung entfernt werden, die Egress-Firewall
.ui()Gerenderte Blöcke wie Tabellen; ihre Daten umgehen die Schwärzung absichtlich
.suggest()Affordances: nächste Schritte, die der Agent in Betracht ziehen kann
.limit()Obergrenze der zurückgegebenen Elemente, mit selbstheilender Trunkierungsmeldung
.embed()Verschachtelte Presenter für verwandte Entitäten

Rules sind Verträge, keine Kommentare

.rules()-Zeilen werden in den Systemkontext injiziert, sodass das Modell sie nicht ignorieren kann wie einen Codekommentar. Hier gehören Einheiten, Währungen, Statuswerte und alles hin, was das Modell ständig falsch macht.

Schwärzung läuft spät, absichtlich

Die DLP-Engine kompiliert die .redactPII()-Pfade in eine optimierte Schwärzungsfunktion, die pro Presenter zwischengespeichert wird. Die Schwärzung läuft nach dem Rendern der UI-Blöcke und unmittelbar vor der Serialisierung, sodass Dashboards echte Werte behalten, während der Modellkontext sauber bleibt.

Daten von .ui() umgehen die Schwärzung absichtlich: eine Tabelle für einen menschlichen Bediener kann echte Werte zeigen. Halten Sie Geheimnisse aus .ui()-Blöcken fern, es sei denn, ein Mensch ist der einzige Konsument.

Eine Entität, viele Zielgruppen

typescript
const AdminPresenter = createPresenter('Invoice').schema({ /* everything */ });
const SupportPresenter = createPresenter('Invoice')
  .schema({ id: t.string, status: t.enum('draft', 'paid', 'overdue') })
  .limit(10);

Rollenbasierte Wahrnehmung braucht kein zusätzliches Modul: wählen Sie den Presenter pro Tenant oder Rolle in der Middleware, und dieselbe Tool bedient beide Zielgruppen sicher. Siehe Credentials und Governance.

Nächste Schritte

  • Tools: Presenter mit .returns() anhängen
  • Routing: dateibasierte Erkennung von Tools
  • Testing: prüfen, was der Agent erhält