Foundry

Working with an agent

Foundry never calls a model. Your agent is the author, and this page is about making it a good one: how to point it at the conventions, and how to ask for screens that do not look like every other AI mockup.

Point your agent at the conventions

foundry init writes AGENTS.md at the root of your project. It is the whole contract: the file layout, the single spec: block per file, the rules the checks enforce, what design.md compiles to, how to place an icon, how to link two screens. One file, no vendor.

Keep it as the only copy. Whatever your agent needs, have it reference AGENTS.md rather than duplicate it, or you end up with two versions and one of them rots.

Load it on demand, not on every turn

Most agents have two kinds of instruction: one loaded into every conversation, and one loaded when it is relevant. Spec conventions belong in the second kind.

They are eighty lines you need while authoring a flow, and dead weight while you fix a CSS bug. Putting them in an always-on file spends context on every single turn to buy nothing most of the time. Worse, an instruction that is always present stops being read as a signal.

So pick the mechanism your tool offers, in this order of preference.

A skill, a rule with a trigger, or a slash command. The good case. In Claude Code, a skill in .claude/skills/spec/SKILL.md: frontmatter with a name and a description that says when to use it, then a body that can be as short as a pointer.

md
---
name: spec
description: How to read, write and evolve this project's spec and screens. Use whenever adding or changing a feature.
---

Follow AGENTS.md at the root of this repository, then run `foundry check`.

The agent loads it when the description matches the task, and ignores it otherwise. In Cursor, the equivalent is a rule scoped with globs, so it attaches when you touch spec/** or flows/**.

An always-on file, if that is all you have. Then keep it to one line, never the content:

md
See AGENTS.md for how this project's spec and screens work.

That is CLAUDE.md, .github/copilot-instructions.md, or your tool's equivalent. One line costs almost nothing and the agent pulls the file when it needs it.

Nothing at all, if your agent already reads AGENTS.md. That is the point of the convention.

Make the repeated work reusable

Same idea, applied to the tasks you run over and over. If your agent supports saved prompts, skills or slash commands, three earn their keep:

  • Draft a flow. Takes a flow name and its intent, writes spec/flows/<name>.md to the format, then runs foundry check.
  • Author the screens of a flow. Reads the flow's spec: block and writes one file per screen and state, using the design tokens.
  • Fix the check. Feeds the output of foundry check back in and asks for the smallest edit that clears it.

The point is not to save typing. It is that the same instruction produces the same shape of output next week, and the week after, when the model has changed.

Prompting the spec

The spec is prose plus one YAML block, so the prose is where you spend your effort. A useful prompt gives the agent what a brief usually skips:

Draft spec/flows/booking.md. A visitor picks a service, then a slot, then confirms. Cover the empty case, no slot left this week, and the failure case, payment declined. The rule that matters: a booking is never confirmed without an explicit review step. Keep the prose short and put every machine fact in the spec: block.

Then let the machine answer:

bash
foundry check

Paste the failures back rather than describing them. overlay "filter" has no outgoing edge to dismiss it is a more precise instruction than anything you would have written by hand.

Prompting the screens, without the slop

This is where most AI output falls apart. Generated screens tend to converge on the same look: a default palette, Inter, a purple gradient, dots and badges everywhere, everything centred, every card the same rounded rectangle. It is not the model being lazy, it is the prompt leaving every choice open. Ask for "a beautiful modern UI" and you get the average of everything.

The fix is to spend your words on the choices that a designer would actually make.

Name the product's world, not its adjectives. "Warm, calm, a paper notebook you would leave on a kitchen table" tells the agent more than "clean and modern".

Pick the type on purpose. A reading serif for a product that holds people's words, a tight grotesk for a dashboard. Say which and why, and it stops reaching for the default.

Give the palette a job. Not "use nice colours" but "warm paper ground, one ember accent, and it only ever marks the thing that needs attention". A single accent used once beats six hues.

Ask for real content. Real note titles, real amounts, real names. Lorem and "Item 1" make a layout impossible to judge, and they hide the density problems you actually need to see.

Name the tells you refuse. Write them down once, and every screen inherits them. Two files share that job, and it is worth keeping them apart.

spec/project.md under ## Rules holds the product rules, the ones a reviewer could check without opening a design tool:

  • colour tints for mood, never as the only carrier of meaning
  • capture is always one tap away
  • no em dash in copy

design.md under ## Don't holds the visual refusals, the tells that make generated work recognisable:

  • no stock palette, and no second accent competing with the main one
  • no dot, badge or pill on anything that is not genuinely a state
  • nothing centred by default
  • no lorem, no "Item 1"

The split matters because the two are read at different moments: the rules constrain what a screen must do, the refusals constrain how it may look.

A prompt that puts this together:

Write the screens for the booking flow, mobile. Use the tokens from design.md, never raw hex. The slot picker shows a real week with real times and two slots already taken, never placeholders. Link a slot to the review screen with data-wf-to. Respect the rules in spec/project.md and the refusals in design.md.

Then look at the dense screen. Craft shows on the screen with the most content, never on the empty one. Render with foundry serve and judge the busiest state first.

A brief, end to end applies all of this to one real project, and shows the design.md and the screens it produced.

What the machine catches, and what it does not

foundry check verifies structure: every edge lands somewhere, every overlay has a way out, nothing is orphaned, nav points at flows that exist. It will never tell you a screen is ugly.

That division is the point. Coherence is mechanical, so a machine holds it. Beauty comes from the brief you write, and it stays your job.

Give the agent this site, not a copy of it

AGENTS.md covers the format inside your project. When a question goes past it, the agent should be able to read the documentation rather than guess, and this site is built to be read by one.

Every page is published three ways from the same markdown:

  • llms.txt at foundry.cisstech.com/llms.txt: the map of the site, one line per page with its summary. llms-full.txt is the whole documentation in a single file, for pasting into a context window.
  • search.json: the content index, so an agent can look up a heading instead of loading everything.
  • Each page as plain markdown, which is what the Copy as markdown button at the top of a page hands you.

Connect it as an MCP server

The site can also be exposed as a tool your agent calls, through the MCP server that ships with the engine behind this documentation:

bash
npx @cisstech/nge-doc-mcp

Point it at this site and the agent searches and reads pages on demand, at the version currently published, instead of relying on what it remembers about Foundry. That matters for a format that is still moving: the answer comes from the docs, not from training data.

The rule stays the same as for AGENTS.md. One source, several doors, and no copy to keep in sync. The site onboards you, and the same files answer the agent.

Last updated Jul 30, 2026