mcp-rune 0.107.0
Be star #1 Get started
SECTION II · GUIDE 05 OF 49
Reading
3 min
Topic
reference
Spec
v0.107.0
Source
02-the-model/derivation-overview.md
On this page5 sections

Derivation overview

This is the chapter’s primer. Before you read the five guides below, this page is the one-page map of what gets derived — automatically, no extra wiring — from your Model declaration. Skim the table, then come back to it as you read each guide so you can see what each piece of a declaration unlocks.

Everything below is what makes the “Model is the single source of truth” claim concrete.

Try it — see derivation in action before reading the map

Verified against rune CLI 0.11.0 · @mcp-rune/mcp-rune 0.107.0 · Node 24.

If you finished the Quickstart you already have everything you need: the scaffolded bookshelf-tour project, the MCP Inspector connected to it, and a Book model declared in src/models/book.ts. Before you scan the derivation table, observe two surfaces deriving from that one declaration.

1. Tool list — derived from MODEL_CLASSES

In the Inspector, call list_models with {}. Expect:

[
  {
    "name": "book",
    "endpoint": "books",
    "description": "A Book record",
    "attributes": ["name", "description"],
    "required_attributes": ["name"],
    "read_only": false
  }
]

Three things on this row are derived: endpoint from static api.endpoint, attributes from the static attributes map, and required_attributes from the required: true flag on name. You didn’t write any of them into a registry — list_models reads the class itself.

2. Prompt guide text — derived from description + attributes

Call get_prompt_guide with { "guide_name": "book" }. The response is a multi-section Markdown guide whose Attribute reference table at the bottom looks like this:

| Attribute     | Type   | Required | Valid Values |
|---------------|--------|----------|--------------|
| name          | string | Yes      |              |
| description   | text   | No       |              |

No template lives in src/prompts/book-prompt.ts for this table — it’s synthesised from the same static attributes block.

Observe: one declaration, two surfaces, zero glue code. Multiply that across every row in the table below and you have the chapter’s argument: the Model is one place, and everything else points back to it. As you read each guide, return to this table to remember which row you’re filling in.

What gets derived

SurfaceDriven byCovered in
Prompt schemaattributes + associations (via derivePromptSchema)Prompt derivation
Prompt guide textdescription + attributes + examplesPrompt creation
9 polymorphic toolsMODEL_CLASSES registry — every model gets all 9Polymorphic tools
Form validationrequired, default, validation, enumValuesValidation and defaults
App formsattributes + kinds<input> type per fieldModel form
Picker / multi-pickerbelongsTo / hasMany → recommended picker appMCP apps, Associations
Display renderingdisplayValue + per-kind renderAttributes and kinds
Search filtersattributes + the search request shaperSearch filters
API payload shapeapi.convention (defaults to the server-wide one)API convention
Foreign-key columnsassociations.belongsTo{key}_id attributeAssociations
Graph edgesassociations(record → target) edgesRetrieval & GraphRAG
Embedding textattributes (text/string fields concatenated)Analysis quickstart
Auto-generated docsdescription + attributes + associationsPolymorphic tools (the get_prompt_guide tool)

What you write vs what derives

   What you write                          What the framework derives
 ┌────────────────────────┐    ┌────────────────────────────────────┐
 │  static description    │    │ Prompt guide intro                  │
 │  static api            │───▶│ DataLayer endpoint + convention     │
 │  static attributes     │    │ Form fields + validation + kinds    │
 │    { type, required,   │    │ Prompt schema + LLM-facing labels   │
 │      default,          │    │ Search filter surface               │
 │      validation,       │    │ App display rendering               │
 │      enumValues, … }   │    │ Embedding text (analysis layer)     │
 │  static associations   │    │ FK columns + pickers                │
 │    { belongsTo,        │    │ Graph edges (analysis layer)        │
 │      hasMany }         │    │ Required-FK checks at form time     │
 │  get displayValue()    │    │ Picker labels + summary rendering   │
 └────────────────────────┘    └────────────────────────────────────┘

What you still have to write yourself

Derivation covers the uniform parts. The places where you reach back in and write actual code:

  • Custom kinds — when 'string:isbn' needs more than what the built-in string kind does. See Attributes and kinds.
  • Prompt content — the actual promptContent getter on your Prompt class. The framework provides PromptContentBuilder as a fluent helper, but you decide what goes into the guide text. See Prompt creation.
  • Custom tools — anything beyond CRUD. The nine polymorphic tools cover the data-plane uniformly; bespoke verbs (cancel a subscription, recompute a score) are BaseTool subclasses you write. See Tool creation.
  • Custom apps — when the default 7 apps don’t fit your UX. See Custom app.
  • Domain knowledge — concepts, business rules, workflows. The framework doesn’t synthesize these from your model — they’re a separate declaration set. See Domain knowledge.

The dividing line is: structural derives, semantic doesn’t. The framework can derive that status is an enum with three values; it cannot derive that status: 'completed' should require rating to be set (that’s a business rule). The next several chapters walk through both halves in detail.

What’s next in this chapter

The table above is the map. The rest of chapter II walks every cell:

  1. Defining a model — the smallest realistic declaration and the four static fields the framework reads.
  2. Attributes and kinds — the type: taxonomy and how one value moves through three representations.
  3. AssociationsbelongsTo and hasMany, the foreign keys they infer, and what derivation unlocks from them.
  4. Validation and defaultsrequired, default, and the validation pass that fires before any write.
  5. Definition vs consumption — why the model code is the only place to declare these things, and the architectural seam the next chapter builds on.

After chapter II, Chapter 3 — The Prompt picks up with the first major consumer of the Model: the prompt that teaches an LLM how to fill the form your model defines.