.fyi page spec for agents
This is the machine-readable spec for creating .fyi page files.
Fetch this markdown. Do not scrape the HTML app shell.
- Raw markdown:
/fyi-page-instructions.md - Human HTML (same schema, app chrome):
/fyi-page-instructions - HTML view of this spec:
/fyi-page-instructions/agent
The .fyi format is JSON, not a binary format. It is used by FYINotes, ApuntesIA, and WorkStream Manager.
If an MCP client is connected to FYI Pages, prefer create_fyi_page, get_fyi_page, add_fyi_notes, and update_fyi_notes instead of emitting a .fyi file, unless the user asks for a file.
Goal
Produce one complete .fyi file as valid JSON with:
id: page idd: visible documentb: paired blob/body document
d stores titles, labels, URLs, columns, order, and symbols.
b stores longer body text for expandable notes.
Matching note ids in d and b pair titles with bodies.
Output rules
- Return only valid JSON. No markdown fences, comments, or trailing commas.
- Use unique integer ids. Prefer epoch milliseconds for the page id, then increment by one per note.
- Keep
id,d.uDocs.meta.id,b.uDocs.meta.id,d.uDocs.pub.id, andb.uDocs.pub.idthe same. - Set
d.uDocs.meta.typto"d"andb.uDocs.meta.typto"b". - Set page
vto18, pubvto4, notevto12. - Set
uDocs.meta.catanduDocs.pub.catto"General"unless the app provides another approved publish category. Do not put topic names such as Home, Work, or Travel inmeta.cat. - Set every note
alrmto0unless the user asks for an alarm (epoch ms). - Set each note
encto1and store body text as raw Unicode. Do not HTML-escape&,",<,>in storage. Missing/0is legacy HTML-entity storage.enc: 2is JSON text int1for type"11". - Safe plain text only. No scripts, event handlers, script tags, iframes, forms, or invented URLs.
After creating d.uDocs.meta and d.uDocs.pub, deep-copy them into b, then set b.uDocs.meta.typ to "b".
Page schema
{
"id": 1777777777000,
"d": {
"uDocs": {
"meta": {
"id": 1777777777000,
"name": "Page Title",
"ty": "000000",
"auth": "",
"updt": 1777777777000,
"vu": "",
"clck": 0,
"gclk": 0,
"col": "3",
"cols": "true",
"cat": "General",
"skey": "outside-model-1777777777000",
"v": 18,
"s": 0,
"u": "",
"u1": "",
"u2": "",
"u3": "",
"fav": 0,
"typ": "d"
},
"coltxt": [["0","1","2","3","4","5","6","7","8","9","10","11","12"], [], [], [], [], [], [], [], [], [], [], [], []],
"zdata": [],
"pub": {
"v": 4,
"title": "Page Title",
"cat": "General",
"id": 1777777777000,
"wType": "",
"signature": "",
"pw": "",
"sURL1": "",
"sURL2": "",
"sURL3": "",
"sURL4": "",
"pURL": "",
"wURL": "",
"cURL": "",
"mURL": "",
"Notes": ""
},
"tabs": ["", "", "", "", "", "", "", "", "", "", "", "", ""],
"colb": [1, 1, 1, "eng"]
}
},
"b": {
"uDocs": {
"meta": {},
"coltxt": [["0","1","2","3","4","5","6","7","8","9","10","11","12"], [], [], [], [], [], [], [], [], [], [], [], []],
"zdata": [],
"pub": {},
"tabs": ["", "", "", "", "", "", "", "", "", "", "", "", ""],
"colb": [1, 1, 1, "eng"]
}
}
}
Note schema
Each uDocs.zdata item is a note. Use the same shape in d and b:
{
"id": 1777777777001,
"col": 1,
"css": "",
"ty": "1",
"t0": "Visible note title",
"t1": "",
"t2": "",
"t3": "",
"t4": "",
"t5": "",
"t6": "",
"ordr": 100,
"updt": 1777777777000,
"bdt": 0,
"clck": 0,
"gclk": 0,
"v": 12,
"s": 0,
"u": 0,
"pre1": 0,
"pre2": 2,
"grp": 0,
"lvl": 0,
"pop": 0,
"tab": 0,
"pa": 0,
"alrm": 0,
"enc": 1
}
d and b notes should share id, col, ty, t0, ordr, pre2, pa, alrm, and enc. If a note has row, copy that too.
- Short/large notes: title in
d.t0, longer body in matchingb.t1. - URL notes: label in
d.t0, URL ind.t1. - JSON notes (
"11"): title ind.t0, JSON text inb.t1,enc: 2on both records. - Mermaid notes (
"12"): title ind.t0, diagram source inb.t1,enc: 1on both records. The file stores source text only.
Space ordr by 100 (100, 200, 300). Optional integer row is the semantic table row. If row is missing or not a positive integer, the app uses floor(ordr / 100) (not the first character of ordr).
Note types (ty)
| Value | Meaning |
|---|---|
"1" | Text note |
"2" | Small expandable note |
"3" | Large note |
"4" | URL-style item |
"5" | Horizontal rule |
"6" | Phone note |
"7" | Section header |
"8" | Email note |
"9" | Block note |
"10" | Container block note |
"11" | JSON note (enc: 2, JSON in b.t1) |
"12" | Mermaid note (enc: 1, source in b.t1) |
For most generated pages use "7" headers, "1" short facts, "2" expandable notes, "3" long notes, "5" optional dividers, and "12" only when a diagram is requested.
Symbols (pre2)
| Value | Meaning |
|---|---|
0 | No symbol |
1 | Arrow / marker |
2 | Bullet |
3 | Empty checkbox / todo |
4 | Checked checkbox |
5 | Star / important |
6 | Warning |
7 | Urgent |
8 | Heart / favorite |
9 | Flag / milestone |
Headers normally use pre2: 0.
Page flags (meta.ty)
Page uDocs.meta.ty is a 6-character flag string, default "000000". It is not note ty.
| Index (0-based) | Meaning |
|---|---|
1 (second character) | Layout: 0 Columns, 1 Semantic table. Example "010000". |
4 (fifth character) | Quiz Mode and related special modes. Leave 0 unless the app set it. |
Keep unused characters 0. When toggling layout, change only index 1.
Layout
Set meta.col to the column count as a string, commonly "2" or "3".
Assign each note col from 1 through that count.
Keep a section and its child notes in the same column.
Set meta.cols to "true" when column headings are enabled.
**Columns** (meta.ty index 1 = 0, default "000000"): notes stack independently in each column. Order inside a column is ordr. Compact column order uses 100, 200, 300. Empty table cells disappear in this view.
**Semantic table** (meta.ty index 1 = 1, example "010000"): notes line up in a grid by col then row then ordr. Notes that share a row sit on the same horizontal line; empty cells are allowed. Use this only when the user asks for a table or aligned grid. Phone still uses the column/carousel path.
Switching layouts does not rewrite col or ordr. Switching Columns → Semantic table assigns dense row (1, 2, 3… per column, in ordr order) only on notes that do not already have row. Notes that already have row keep it so empty cells return when the page is a table again. The blob copies row when it is set; no extra blob fields are required.
Example table notes (same row, different col):
{"id":1777777777001,"col":1,"row":1,"ty":"7","t0":"Planning","ordr":100}
{"id":1777777777002,"col":2,"row":1,"ty":"7","t0":"Risks","ordr":100}
{"id":1777777777003,"col":1,"row":2,"ty":"1","t0":"Define the goal","ordr":100}
Content rules
- Use section headers. Keep
t0short. Put long text inb.t1. - Checkboxes only for actions. Warnings only for real risks.
- Do not invent URLs. If a link checker is available, skip
404responses.
Minimal example
{
"id": 1777777777000,
"d": {
"uDocs": {
"meta": {
"id": 1777777777000,
"name": "Sample Project Plan",
"ty": "000000",
"auth": "",
"updt": 1777777777000,
"vu": "",
"clck": 0,
"gclk": 0,
"col": "2",
"cols": "true",
"cat": "General",
"skey": "outside-model-1777777777000",
"v": 18,
"s": 0,
"u": "",
"u1": "",
"u2": "",
"u3": "",
"fav": 0,
"typ": "d"
},
"coltxt": [["0","1","2","3","4","5","6","7","8","9","10","11","12"], [], [], [], [], [], [], [], [], [], [], [], []],
"zdata": [
{"id":1777777777001,"col":1,"css":"sB","ty":"7","t0":"Planning","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":100,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":0,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777002,"col":1,"css":"","ty":"2","t0":"Define the goal","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":200,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":3,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777003,"col":2,"css":"sB","ty":"7","t0":"Risks","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":300,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":0,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777004,"col":2,"css":"","ty":"1","t0":"Confirm dependencies before scheduling.","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":400,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":6,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1}
],
"pub": {
"v": 4,
"title": "Sample Project Plan",
"cat": "General",
"id": 1777777777000,
"wType": "",
"signature": "",
"pw": "",
"sURL1": "",
"sURL2": "",
"sURL3": "",
"sURL4": "",
"pURL": "",
"wURL": "",
"cURL": "",
"mURL": "",
"Notes": ""
},
"tabs": ["", "", "", "", "", "", "", "", "", "", "", "", ""],
"colb": [1, 1, 1, "eng"]
}
},
"b": {
"uDocs": {
"meta": {
"id": 1777777777000,
"name": "Sample Project Plan",
"ty": "000000",
"auth": "",
"updt": 1777777777000,
"vu": "",
"clck": 0,
"gclk": 0,
"col": "2",
"cols": "true",
"cat": "General",
"skey": "outside-model-1777777777000",
"v": 18,
"s": 0,
"u": "",
"u1": "",
"u2": "",
"u3": "",
"fav": 0,
"typ": "b"
},
"coltxt": [["0","1","2","3","4","5","6","7","8","9","10","11","12"], [], [], [], [], [], [], [], [], [], [], [], []],
"zdata": [
{"id":1777777777001,"col":1,"css":"sB","ty":"7","t0":"Planning","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":100,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":0,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777002,"col":1,"css":"","ty":"2","t0":"Define the goal","t1":"Write the outcome in one sentence, list the owner, and identify the first measurable success point.","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":200,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":3,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777003,"col":2,"css":"sB","ty":"7","t0":"Risks","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":300,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":0,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1},
{"id":1777777777004,"col":2,"css":"","ty":"1","t0":"Confirm dependencies before scheduling.","t1":"","t2":"","t3":"","t4":"","t5":"","t6":"","ordr":400,"updt":1777777777000,"bdt":0,"clck":0,"gclk":0,"v":12,"s":0,"u":0,"pre1":0,"pre2":6,"grp":0,"lvl":0,"pop":0,"tab":0,"pa":0,"alrm":0,"enc":1}
],
"pub": {
"v": 4,
"title": "Sample Project Plan",
"cat": "General",
"id": 1777777777000,
"wType": "",
"signature": "",
"pw": "",
"sURL1": "",
"sURL2": "",
"sURL3": "",
"sURL4": "",
"pURL": "",
"wURL": "",
"cURL": "",
"mURL": "",
"Notes": ""
},
"tabs": ["", "", "", "", "", "", "", "", "", "", "", "", ""],
"colb": [1, 1, 1, "eng"]
}
}
}
System prompt
You create .fyi pages. Return only valid JSON. Use this schema exactly: top-level id, visible document d, and blob/body document b. Use unique epoch-millisecond-style ids. Use page meta version 18, note version 12, pub version 4, uDocs.meta.cat: "General", uDocs.pub.cat: "General", note alrm: 0 unless alarms are requested, and note enc: 1 with raw Unicode body text except JSON notes (ty: "11", enc: 2). Default page meta.ty is "000000" (Columns). For Semantic table layout set the second character to 1 ("010000") and optional note row; if row is omitted, row is floor(ordr / 100). Use ty: "7" for section headers, ty: "1" for normal text, ty: "2" for expandable small notes, ty: "3" for long notes, ty: "11" for JSON notes, and ty: "12" for Mermaid diagram notes (source in b.t1, enc: 1). Use pre2 symbols: 0 none, 1 arrow, 2 bullet, 3 todo, 4 checked, 5 star, 6 warning, 7 urgent, 8 heart, 9 flag. Put visible titles in d.uDocs.zdata[].t0. Put longer body text in matching b.uDocs.zdata[].t1. Put URLs in d.uDocs.zdata[].t1 only when valid. No scripts, event handlers, iframes, forms, or invented links.
Validation checklist
- JSON parses.
- Top-level keys are
id,d, andb. d.uDocsandb.uDocsexist.d.uDocs.meta.typis"d"andb.uDocs.meta.typis"b".- Both
zdataarrays exist and use matching ids. - Every note has
id,col,ty,t0,ordr,updt,v,pre2,pa,alrm, andenc. pre2is an integer from0through9.ordrvalues are sorted and spaced.- Page
meta.tyis six characters. Semantic table uses index1=1("010000"). If a note hasrow, it is a positive integer and matches indandb. - No unsafe HTML or executable code.
- Included URLs are verified when a link checker is available.