[{"data":1,"prerenderedAt":2231},["ShallowReactive",2],{"navigation_docs_en":3,"-en-guides-build-an-application":297,"-en-guides-build-an-application-surround":2226},[4,30,68,103,187,287],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Use Cases","\u002Fen\u002Fgetting-started\u002Fuse-cases","en\u002F1.getting-started\u002F4.use-cases","i-lucide-layers",{"title":26,"path":27,"stem":28,"icon":29},"Concepts","\u002Fen\u002Fgetting-started\u002Fconcepts","en\u002F1.getting-started\u002F5.concepts","i-lucide-book",{"title":26,"path":31,"stem":32,"children":33,"page":6},"\u002Fen\u002Fconcepts","en\u002F2.concepts",[34,38,43,48,53,58,63],{"title":35,"path":36,"stem":37,"icon":14},"Organization","\u002Fen\u002Fconcepts\u002Forganization","en\u002F2.concepts\u002F1.organization",{"title":39,"path":40,"stem":41,"icon":42},"Data Model","\u002Fen\u002Fconcepts\u002Fdata-model","en\u002F2.concepts\u002F2.data-model","i-lucide-database",{"title":44,"path":45,"stem":46,"icon":47},"Access Control","\u002Fen\u002Fconcepts\u002Faccess-permissions","en\u002F2.concepts\u002F3.access-permissions","i-lucide-user-key",{"title":49,"path":50,"stem":51,"icon":52},"Audit Logs","\u002Fen\u002Fconcepts\u002Faudit-logs","en\u002F2.concepts\u002F4.audit-logs","i-lucide-scroll-text",{"title":54,"path":55,"stem":56,"icon":57},"Introspection","\u002Fen\u002Fconcepts\u002Fintrospection","en\u002F2.concepts\u002F6.introspection","i-lucide-database-search",{"title":59,"path":60,"stem":61,"icon":62},"Query Engine","\u002Fen\u002Fconcepts\u002Fquery-engine","en\u002F2.concepts\u002F7.query-engine","i-lucide-workflow",{"title":64,"path":65,"stem":66,"icon":67},"AI","\u002Fen\u002Fconcepts\u002Fai","en\u002F2.concepts\u002F8.ai","i-lucide-sparkles",{"title":69,"path":70,"stem":71,"children":72,"page":6},"Guides","\u002Fen\u002Fguides","en\u002F4.guides",[73,78,83,88,93,98],{"title":74,"path":75,"stem":76,"icon":77},"Build an Application with AI Assistance","\u002Fen\u002Fguides\u002Fbuild-an-application","en\u002F4.guides\u002F1.build-an-application","i-lucide-route",{"title":79,"path":80,"stem":81,"icon":82},"REST API Quickstart","\u002Fen\u002Fguides\u002Frest-api","en\u002F4.guides\u002F1.rest-api","i-lucide-plug",{"title":84,"path":85,"stem":86,"icon":87},"SDK Quickstart","\u002Fen\u002Fguides\u002Fsdk","en\u002F4.guides\u002F2.sdk","i-lucide-terminal",{"title":89,"path":90,"stem":91,"icon":92},"Configure SSO","\u002Fen\u002Fguides\u002Fconfigure-sso","en\u002F4.guides\u002F3.configure-sso","i-lucide-key-round",{"title":94,"path":95,"stem":96,"icon":97},"Configure MCP","\u002Fen\u002Fguides\u002Fmcp","en\u002F4.guides\u002F4.mcp","i-lucide-brain-cog",{"title":99,"path":100,"stem":101,"icon":102},"Customize Content Space","\u002Fen\u002Fguides\u002Fcustomize-content-space","en\u002F4.guides\u002F5.customize-content-space","i-lucide-columns-3-cog",{"title":104,"path":105,"stem":106,"children":107,"page":6},"Developer","\u002Fen\u002Fdeveloper","en\u002F5.developer",[108,163],{"title":109,"path":110,"stem":111,"children":112,"page":6},"Data Access","\u002Fen\u002Fdeveloper\u002Fapi","en\u002F5.developer\u002F1.api",[113,118,123,128,133,138,143,148,153,158],{"title":114,"path":115,"stem":116,"icon":117},"Overview","\u002Fen\u002Fdeveloper\u002Fapi\u002Foverview","en\u002F5.developer\u002F1.api\u002F1.overview","i-lucide-globe",{"title":119,"path":120,"stem":121,"icon":122},"Errors","\u002Fen\u002Fdeveloper\u002Fapi\u002Ferrors","en\u002F5.developer\u002F1.api\u002F10.errors","i-lucide-alert-triangle",{"title":124,"path":125,"stem":126,"icon":127},"Authentication","\u002Fen\u002Fdeveloper\u002Fapi\u002Fauthentication","en\u002F5.developer\u002F1.api\u002F2.authentication","i-lucide-lock",{"title":129,"path":130,"stem":131,"icon":132},"Reading Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Freading-data","en\u002F5.developer\u002F1.api\u002F3.reading-data","i-lucide-book-open",{"title":134,"path":135,"stem":136,"icon":137},"Writing Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Fwriting-data","en\u002F5.developer\u002F1.api\u002F4.writing-data","i-lucide-pencil",{"title":139,"path":140,"stem":141,"icon":142},"Filtering","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiltering","en\u002F5.developer\u002F1.api\u002F5.filtering","i-lucide-filter",{"title":144,"path":145,"stem":146,"icon":147},"Field Selection","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffield-selection","en\u002F5.developer\u002F1.api\u002F6.field-selection","i-lucide-list-checks",{"title":149,"path":150,"stem":151,"icon":152},"Sorting & Pagination","\u002Fen\u002Fdeveloper\u002Fapi\u002Fsorting-pagination","en\u002F5.developer\u002F1.api\u002F7.sorting-pagination","i-lucide-arrow-up-down",{"title":154,"path":155,"stem":156,"icon":157},"Relational Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Frelational-data","en\u002F5.developer\u002F1.api\u002F8.relational-data","i-lucide-network",{"title":159,"path":160,"stem":161,"icon":162},"Files & Assets","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiles","en\u002F5.developer\u002F1.api\u002F9.files","i-lucide-file-up",{"title":164,"path":165,"stem":166,"children":167,"page":6},"Client SDK","\u002Fen\u002Fdeveloper\u002Fsdk","en\u002F5.developer\u002F2.sdk",[168,172,177,182],{"title":169,"path":170,"stem":171,"icon":19},"Installation","\u002Fen\u002Fdeveloper\u002Fsdk\u002Finstallation","en\u002F5.developer\u002F2.sdk\u002F1.installation",{"title":173,"path":174,"stem":175,"icon":176},"Client Setup","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fclient-setup","en\u002F5.developer\u002F2.sdk\u002F2.client-setup","i-lucide-settings",{"title":178,"path":179,"stem":180,"icon":181},"Type System","\u002Fen\u002Fdeveloper\u002Fsdk\u002Ftype-system","en\u002F5.developer\u002F2.sdk\u002F3.type-system","i-lucide-braces",{"title":183,"path":184,"stem":185,"icon":186},"Advanced","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fadvanced","en\u002F5.developer\u002F2.sdk\u002F5.advanced","i-lucide-puzzle",{"title":188,"path":189,"stem":190,"children":191,"page":6},"Reference","\u002Fen\u002Freference","en\u002F6.reference",[192,196,212,216,221,258],{"title":193,"path":194,"stem":195,"icon":176},"Configuration","\u002Fen\u002Freference\u002Fenvironment-variables","en\u002F6.reference\u002F1.environment-variables",{"title":197,"path":198,"stem":199,"children":200,"icon":82},"Connectors","\u002Fen\u002Freference\u002Fconnectors","en\u002F6.reference\u002F2.connectors\u002Findex",[201,202,207],{"title":197,"path":198,"stem":199,"icon":82},{"title":203,"path":204,"stem":205,"icon":206},"PostgreSQL and Supabase","\u002Fen\u002Freference\u002Fconnectors\u002Fpostgresql-supabase","en\u002F6.reference\u002F2.connectors\u002F1.postgresql-supabase","i-simple-icons-postgresql",{"title":208,"path":209,"stem":210,"icon":211},"MySQL and MariaDB","\u002Fen\u002Freference\u002Fconnectors\u002Fmysql-mariadb","en\u002F6.reference\u002F2.connectors\u002F2.mysql-mariadb","i-simple-icons-mysql",{"title":213,"path":214,"stem":215,"icon":181},"Data Types Representation","\u002Fen\u002Freference\u002Fdata-types","en\u002F6.reference\u002F3.data-types",{"title":217,"path":218,"stem":219,"icon":220},"Permissions Reference","\u002Fen\u002Freference\u002Fpermissions","en\u002F6.reference\u002F4.permissions","i-lucide-shield",{"title":222,"path":223,"stem":224,"children":225,"page":6},"API Reference","\u002Fen\u002Freference\u002Fapi-reference","en\u002F6.reference\u002F5.api-reference",[226,231,236],{"title":227,"path":228,"stem":229,"icon":230},"System Endpoints","\u002Fen\u002Freference\u002Fapi-reference\u002Fsystem-endpoints","en\u002F6.reference\u002F5.api-reference\u002F1.system-endpoints","i-lucide-server",{"title":232,"path":233,"stem":234,"icon":235},"OpenAPI Spec","\u002Fen\u002Freference\u002Fapi-reference\u002Fopenapi-spec","en\u002F6.reference\u002F5.api-reference\u002F2.openapi-spec","i-lucide-file-code",{"title":237,"path":238,"stem":239,"children":240,"icon":242},"Schema Migration","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration","en\u002F6.reference\u002F5.api-reference\u002F3.schema-migration\u002Findex",[241,243,248,253],{"title":237,"path":238,"stem":239,"icon":242},"i-lucide-database-zap",{"title":244,"path":245,"stem":246,"icon":247},"Apply Migrations","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fapply-migrations","en\u002F6.reference\u002F5.api-reference\u002F3.schema-migration\u002F1.apply-migrations","i-lucide-upload",{"title":249,"path":250,"stem":251,"icon":252},"Import Changes","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fimport-changes","en\u002F6.reference\u002F5.api-reference\u002F3.schema-migration\u002F2.import-changes","i-lucide-refresh-cw",{"title":254,"path":255,"stem":256,"icon":257},"Operation Reference","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Foperation-reference","en\u002F6.reference\u002F5.api-reference\u002F3.schema-migration\u002F3.operation-reference","i-lucide-list-tree",{"title":259,"path":260,"stem":261,"children":262,"page":6},"Pitfalls","\u002Fen\u002Freference\u002Fpitfalls","en\u002F6.reference\u002F6.pitfalls",[263,267,272,277,282],{"title":114,"path":264,"stem":265,"icon":266},"\u002Fen\u002Freference\u002Fpitfalls\u002Foverview","en\u002F6.reference\u002F6.pitfalls\u002F1.overview","i-lucide-triangle-alert",{"title":268,"path":269,"stem":270,"icon":271},"Concurrent Migrations","\u002Fen\u002Freference\u002Fpitfalls\u002Fconcurrent-migrations","en\u002F6.reference\u002F6.pitfalls\u002F2.concurrent-migrations","i-lucide-git-merge",{"title":273,"path":274,"stem":275,"icon":276},"Instance Configuration","\u002Fen\u002Freference\u002Fpitfalls\u002Finstance-configuration-related-problems","en\u002F6.reference\u002F6.pitfalls\u002F3.instance-configuration-related-problems","i-lucide-wrench",{"title":278,"path":279,"stem":280,"icon":281},"Overly Permissive Public Roles","\u002Fen\u002Freference\u002Fpitfalls\u002Foverly-permissive","en\u002F6.reference\u002F6.pitfalls\u002F4.overly-permissive","i-lucide-shield-off",{"title":283,"path":284,"stem":285,"icon":286},"No Aggregates","\u002Fen\u002Freference\u002Fpitfalls\u002Fno-aggregates","en\u002F6.reference\u002F6.pitfalls\u002F5.no-aggregates","i-lucide-sigma",{"title":288,"icon":289,"path":290,"stem":291,"children":292,"page":6},"Release Notes","i-lucide-rocket","\u002Fen\u002Frelease-notes","en\u002F7.release-notes",[293],{"title":294,"path":295,"stem":296,"icon":289},"Changelog","\u002Fen\u002Frelease-notes\u002Fchangelog","en\u002F7.release-notes\u002F1.changelog",{"id":298,"title":74,"body":299,"description":2219,"extension":2220,"links":2221,"meta":2222,"navigation":2223,"path":75,"seo":2224,"stem":76,"__hash__":2225},"docs_en\u002Fen\u002F4.guides\u002F1.build-an-application.md",{"type":300,"value":301,"toc":2195},"minimark",[302,306,326,334,344,349,438,446,462,466,497,500,504,511,541,551,558,576,582,589,591,595,602,605,616,622,630,632,636,639,660,664,670,684,690,693,712,717,721,736,739,774,785,789,796,799,847,857,860,960,970,972,976,979,982,1067,1082,1088,1091,1172,1178,1180,1184,1192,1196,1202,1263,1328,1389,1406,1410,1417,1420,1720,1747,1757,1760,1879,1885,1891,1949,1952,2003,2013,2019,2022,2024,2028,2035,2153,2157,2159,2163,2191],[303,304,114],"h2",{"id":305},"overview",[307,308,309,310,315,316,320,321,325],"p",{},"This walkthrough shows rapid, AI-assisted development on Monospace end to end — from an empty instance to a working application or internal tool. You'll wire up your AI coding agent with the official Monospace ",[311,312,314],"a",{"href":313},"#_3-connect-your-ide","skill"," and ",[311,317,319],{"href":318},"\u002Fguides\u002Fmcp","MCP server",", bootstrap a schema from your IDE, and build on top with the typed ",[311,322,324],{"href":323},"\u002Fguides\u002Fsdk","SDK",".",[307,327,328,329,333],{},"The whole thing fits in ",[330,331,332],"strong",{},"about an hour",", and you start from nothing. You don't need to bring an existing database or model any data by hand. Your agent creates the schema for you over MCP, and Monospace turns it into a governed API the moment it exists.",[307,335,336,339,340,343],{},[330,337,338],{},"What you'll build:"," an internal ",[330,341,342],{},"restock console"," for an operations team. It surfaces products that have dropped below their reorder threshold and lets an operator file a restock request, reading live from your workspace through one governed API.",[345,346,348],"h3",{"id":347},"the-build-at-a-glance","The Build at a Glance",[350,351,352,368],"table",{},[353,354,355],"thead",{},[356,357,358,362,365],"tr",{},[359,360,361],"th",{},"Stage",[359,363,364],{},"What you do",[359,366,367],{},"Rough time",[369,370,371,386,400,412,425],"tbody",{},[356,372,373,380,383],{},[374,375,376],"td",{},[311,377,379],{"href":378},"#_1-start-up-monospace","1. Start up Monospace",[374,381,382],{},"Launch the stack, sign in, create a workspace",[374,384,385],{},"15 min",[356,387,388,394,397],{},[374,389,390],{},[311,391,393],{"href":392},"#_2-connect-your-data-sources","2. Connect your data sources",[374,395,396],{},"See how Monospace federates databases you already run",[374,398,399],{},"10 min",[356,401,402,407,410],{},[374,403,404],{},[311,405,406],{"href":313},"3. Connect your IDE",[374,408,409],{},"Get an API key, install the skill, connect the MCP server",[374,411,385],{},[356,413,414,420,423],{},[374,415,416],{},[311,417,419],{"href":418},"#_4-bootstrap-the-schema","4. Bootstrap the schema",[374,421,422],{},"Let your agent build the data model from a prompt",[374,424,385],{},[356,426,427,433,436],{},[374,428,429],{},[311,430,432],{"href":431},"#_5-generate-the-sdk-and-build","5. Generate the SDK and build",[374,434,435],{},"Type-safe client, then the application itself",[374,437,385],{},[307,439,440,441,445],{},"Once it's running, the ",[311,442,444],{"href":443},"#bonus-deploy-with-a-service-account","Deploy with a Service Account"," bonus shows how to give the application its own scoped identity for production.",[447,448,449,450,453,454,457,458,461],"note",{},"A ",[330,451,452],{},"workspace"," is your tenant. It holds a schema and the data source connections behind it. A ",[330,455,456],{},"collection"," is a container for items of the same type (the equivalent of a table), and a ",[330,459,460],{},"field"," is a named value on an item.",[303,463,465],{"id":464},"prerequisites","Prerequisites",[467,468,469,479,487,490],"ul",{},[470,471,472,478],"li",{},[311,473,477],{"href":474,"rel":475},"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002Finstall\u002F",[476],"nofollow","Docker Compose"," to run Monospace locally.",[470,480,481,486],{},[311,482,485],{"href":483,"rel":484},"https:\u002F\u002Fclaude.com\u002Fclaude-code",[476],"Claude Code"," (the primary agent in this guide) or another MCP-capable agent such as Cursor or Codex.",[470,488,489],{},"Node.js, for the SDK and its type generator.",[470,491,492,493,496],{},"Optionally, a PostgreSQL, MySQL, or MariaDB database if you want to connect real data in ",[311,494,495],{"href":392},"Stage 2",". The tutorial bootstraps its own schema, so this is not required.",[498,499],"hr",{},[303,501,503],{"id":502},"_1-start-up-monospace","1. Start Up Monospace",[307,505,506,507,510],{},"Follow the ",[311,508,16],{"href":509},"\u002Fgetting-started\u002Finstallation"," to launch the stack with Docker Compose. In short:",[512,513,519],"pre",{"className":514,"code":515,"filename":516,"language":517,"meta":518,"style":518},"language-bash shiki shiki-themes monospace-light monospace-light monospace-dark","docker compose up -d\n","terminal","bash","",[520,521,522],"code",{"__ignoreMap":518},[523,524,527,531,535,538],"span",{"class":525,"line":526},"line",1,[523,528,530],{"class":529},"ssBNi","docker",[523,532,534],{"class":533},"suKVh"," compose",[523,536,537],{"class":533}," up",[523,539,540],{"class":529}," -d\n",[307,542,543,544,550],{},"Once the containers report healthy, open the Studio at ",[330,545,546],{},[311,547,548],{"href":548,"rel":549},"http:\u002F\u002Flocalhost:8100",[476],". The compose file sets no admin credentials, so on first run Monospace greets you with an onboarding screen. Create your admin account there, then sign in.",[307,552,553],{},[554,555],"img",{"alt":556,"src":557},"Monospace Studio onboarding screen for creating the first admin account on a fresh install","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Flogin.png",[307,559,560,561,564,565,567,568,571,572,575],{},"Your ",[330,562,563],{},"organization"," is the top-level container, representing your company or team. Inside it, create a ",[330,566,452],{}," for this application. Name it ",[520,569,570],{},"Acme-Inventory"," and give it the URL slug ",[520,573,574],{},"acme-inventory",". The workspace is where your schema and data source connections live.",[307,577,578],{},[554,579],{"alt":580,"src":581},"The \"Create workspace\" dialog with the name Acme-Inventory","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Fcreate-workspace.png",[583,584,585,586,588],"tip",{},"Running locally is the fastest way to follow along. Everything here works identically against a deployed instance. Swap ",[520,587,548],{}," for your host.",[498,590],{},[303,592,594],{"id":593},"_2-connect-your-data-sources","2. Connect Your Data Sources",[447,596,597,598,601],{},"No database to connect right now? Skip ahead. This tutorial builds its own schema in ",[311,599,600],{"href":418},"Stage 4"," using the workspace's built-in data source, so you can follow the whole thing with nothing but Docker.",[307,603,604],{},"Federating the databases you already run is Monospace's core capability. You can connect one or many, and query across them through a single governed API without ETL or replication.",[307,606,607,608,611,612,615],{},"In the Studio, go to ",[330,609,610],{},"Data Model → Data Sources",", add a connection, and choose your connector. Enter the connection details and use ",[330,613,614],{},"Test Connection"," before saving.",[307,617,618],{},[554,619],{"alt":620,"src":621},"The Data Sources view with the \"Add data source\" connector picker open","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Fcreate-data-source.png",[307,623,624,625,629],{},"When you connect an existing database, Monospace runs ",[311,626,628],{"href":627},"\u002Fconcepts\u002Fintrospection","Database Introspection",": it reads your tables and maps them to collections automatically, with their fields and relations already in place.",[498,631],{},[303,633,635],{"id":634},"_3-connect-your-ide","3. Connect Your IDE",[307,637,638],{},"Your coding agent doesn't have Monospace in its training data. Left alone, it guesses at the API. Three pieces get it ready:",[467,640,641,648,655],{},[470,642,643,644,647],{},"an ",[330,645,646],{},"API key"," to authenticate",[470,649,650,651,654],{},"the ",[330,652,653],{},"official skill"," so it knows how Monospace actually works",[470,656,650,657,659],{},[330,658,319],{}," so it can read and write your real workspace.",[345,661,663],{"id":662},"get-an-api-key","Get an API Key",[307,665,666,667,669],{},"As a new admin, the fastest way to authenticate is an ",[330,668,646],{}," bound to your own account. This is your personal access token for the API: it inherits your admin permissions, so it can do everything you need while building.",[307,671,672,673,676,677,680,681,683],{},"Open your ",[330,674,675],{},"Account Settings"," and go to ",[330,678,679],{},"Access",", then create an ",[330,682,646],{}," there. Give it a name and a TTL, then copy it now, since the plaintext value is shown once.",[307,685,686],{},[554,687],{"alt":688,"src":689},"The API key creation dialog showing the one-time key value","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Faccess-token.png",[307,691,692],{},"Store it as an environment variable, never in source control:",[512,694,697],{"className":514,"code":695,"filename":696,"language":517,"meta":518,"style":518},"MONOSPACE_API_KEY=YOUR_API_KEY\n",".env",[520,698,699],{"__ignoreMap":518},[523,700,701,705,709],{"class":525,"line":526},[523,702,704],{"class":703},"sNJ9c","MONOSPACE_API_KEY",[523,706,708],{"class":707},"sLVBU","=",[523,710,711],{"class":533},"YOUR_API_KEY\n",[447,713,714,715,325],{},"An admin key is the right choice for building locally. When you deploy the application for real, swap it for a narrowly scoped identity, as shown in ",[311,716,444],{"href":443},[345,718,720],{"id":719},"install-the-monospace-skill","Install the Monospace Skill",[307,722,723,724,729,730,735],{},"The ",[311,725,728],{"href":726,"rel":727},"https:\u002F\u002Fgithub.com\u002Fdirectus\u002Fmonospace-agent-skills",[476],"Monospace Agent Skills"," bundle is the official ",[311,731,734],{"href":732,"rel":733},"https:\u002F\u002Fagentskills.io",[476],"Agent Skills"," package. It gives your agent the ground truth for the REST API, the typed SDK, the codegen workflow, and the MCP tools, so it writes correct calls on the first try.",[307,737,738],{},"Install it into Claude Code from the plugin marketplace:",[512,740,742],{"className":514,"code":741,"filename":485,"language":517,"meta":518,"style":518},"claude plugin marketplace add directus\u002Fmonospace-agent-skills\nclaude plugin install monospace@monospace-agent-skills\n",[520,743,744,761],{"__ignoreMap":518},[523,745,746,749,752,755,758],{"class":525,"line":526},[523,747,748],{"class":529},"claude",[523,750,751],{"class":533}," plugin",[523,753,754],{"class":533}," marketplace",[523,756,757],{"class":533}," add",[523,759,760],{"class":533}," directus\u002Fmonospace-agent-skills\n",[523,762,764,766,768,771],{"class":525,"line":763},2,[523,765,748],{"class":529},[523,767,751],{"class":533},[523,769,770],{"class":533}," install",[523,772,773],{"class":533}," monospace@monospace-agent-skills\n",[583,775,776,777,780,781,784],{},"Using another agent? The skill follows the open standard. Install it anywhere with ",[520,778,779],{},"npx skills add directus\u002Fmonospace-agent-skills",", or copy ",[520,782,783],{},"skills\u002Fmonospace\u002F"," into your agent's skills directory.",[345,786,788],{"id":787},"connect-the-mcp-server","Connect the MCP Server",[307,790,791,792,795],{},"Monospace serves an MCP endpoint ",[330,793,794],{},"per workspace",", so your agent can query and mutate data through the same governed API as the rest of your stack. Every tool call runs under the permissions of the API key you connect with.",[307,797,798],{},"Add the server to Claude Code with a single command:",[512,800,802],{"className":514,"code":801,"filename":485,"language":517,"meta":518,"style":518},"claude mcp add --scope project --transport http monospace \\\n  http:\u002F\u002Flocalhost:8100\u002Fapi\u002Facme-inventory\u002Fmcp \\\n  --header \"Authorization: Bearer YOUR_API_KEY\"\n",[520,803,804,831,838],{"__ignoreMap":518},[523,805,806,808,811,813,816,819,822,825,828],{"class":525,"line":526},[523,807,748],{"class":529},[523,809,810],{"class":533}," mcp",[523,812,757],{"class":533},[523,814,815],{"class":529}," --scope",[523,817,818],{"class":533}," project",[523,820,821],{"class":529}," --transport",[523,823,824],{"class":533}," http",[523,826,827],{"class":533}," monospace",[523,829,830],{"class":529}," \\\n",[523,832,833,836],{"class":525,"line":763},[523,834,835],{"class":533},"  http:\u002F\u002Flocalhost:8100\u002Fapi\u002Facme-inventory\u002Fmcp",[523,837,830],{"class":529},[523,839,841,844],{"class":525,"line":840},3,[523,842,843],{"class":529},"  --header",[523,845,846],{"class":533}," \"Authorization: Bearer YOUR_API_KEY\"\n",[307,848,849,852,853,856],{},[520,850,851],{},"--scope project"," writes the config to a shareable ",[520,854,855],{},".mcp.json"," in your project root, so anyone who clones the repo gets the same server.",[307,858,859],{},"If you'd rather write that file by hand, or your setup can't run the command, create it directly:",[512,861,865],{"className":862,"code":863,"filename":855,"language":864,"meta":518,"style":518},"language-json shiki shiki-themes monospace-light monospace-light monospace-dark","{\n  \"mcpServers\": {\n    \"monospace\": {\n      \"type\": \"http\",\n      \"url\": \"http:\u002F\u002Flocalhost:8100\u002Fapi\u002Facme-inventory\u002Fmcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${MONOSPACE_API_KEY}\"\n      }\n    }\n  }\n}\n","json",[520,866,867,873,882,889,904,917,925,936,942,948,954],{"__ignoreMap":518},[523,868,869],{"class":525,"line":526},[523,870,872],{"class":871},"sTMul","{\n",[523,874,875,879],{"class":525,"line":763},[523,876,878],{"class":877},"snHjA","  \"mcpServers\"",[523,880,881],{"class":871},": {\n",[523,883,884,887],{"class":525,"line":840},[523,885,886],{"class":877},"    \"monospace\"",[523,888,881],{"class":871},[523,890,892,895,898,901],{"class":525,"line":891},4,[523,893,894],{"class":877},"      \"type\"",[523,896,897],{"class":871},": ",[523,899,900],{"class":533},"\"http\"",[523,902,903],{"class":871},",\n",[523,905,907,910,912,915],{"class":525,"line":906},5,[523,908,909],{"class":877},"      \"url\"",[523,911,897],{"class":871},[523,913,914],{"class":533},"\"http:\u002F\u002Flocalhost:8100\u002Fapi\u002Facme-inventory\u002Fmcp\"",[523,916,903],{"class":871},[523,918,920,923],{"class":525,"line":919},6,[523,921,922],{"class":877},"      \"headers\"",[523,924,881],{"class":871},[523,926,928,931,933],{"class":525,"line":927},7,[523,929,930],{"class":877},"        \"Authorization\"",[523,932,897],{"class":871},[523,934,935],{"class":533},"\"Bearer ${MONOSPACE_API_KEY}\"\n",[523,937,939],{"class":525,"line":938},8,[523,940,941],{"class":871},"      }\n",[523,943,945],{"class":525,"line":944},9,[523,946,947],{"class":871},"    }\n",[523,949,951],{"class":525,"line":950},10,[523,952,953],{"class":871},"  }\n",[523,955,957],{"class":525,"line":956},11,[523,958,959],{"class":871},"}\n",[307,961,962,963,966,967,969],{},"Written this way, Claude Code expands ",[520,964,965],{},"${MONOSPACE_API_KEY}"," from your environment, keeping the key out of the file. For Cursor, Codex, Gemini, and the OpenAI SDKs, the ",[311,968,94],{"href":318}," guide has the exact per-client setup. The URL and bearer token are the same everywhere.",[498,971],{},[303,973,975],{"id":974},"_4-bootstrap-the-schema","4. Bootstrap the Schema",[307,977,978],{},"Here's where it starts to pay off. Instead of modeling collections by hand, describe the data model to your agent and let it build the schema over MCP.",[307,980,981],{},"In your IDE, give the agent this prompt:",[983,984,985,991,1064],"blockquote",{},[307,986,987,988,990],{},"Create three collections in the ",[520,989,574],{}," workspace on its built-in database.",[467,992,993,1009,1032],{},[470,994,995,897,998,1001,1002,1001,1005,1008],{},[520,996,997],{},"Products",[520,999,1000],{},"name"," (string), ",[520,1003,1004],{},"sku",[520,1006,1007],{},"reorder_threshold"," (integer)",[470,1010,1011,897,1014,1017,1018,1020,1021,1001,1024,1027,1028,1031],{},[520,1012,1013],{},"StockLevels",[520,1015,1016],{},"product"," (to-one relation to ",[520,1019,997],{},"), ",[520,1022,1023],{},"warehouse",[520,1025,1026],{},"quantity_on_hand"," (integer), ",[520,1029,1030],{},"updated_at"," (timestamp)",[470,1033,1034,897,1037,1017,1039,1020,1041,1027,1044,1047,1048,1051,1052,1051,1055,1020,1058,1001,1061,1031],{},[520,1035,1036],{},"RestockRequests",[520,1038,1016],{},[520,1040,997],{},[520,1042,1043],{},"quantity",[520,1045,1046],{},"status"," (string, one of ",[520,1049,1050],{},"draft",", ",[520,1053,1054],{},"submitted",[520,1056,1057],{},"received",[520,1059,1060],{},"requested_by",[520,1062,1063],{},"created_at",[307,1065,1066],{},"Then seed five sample products with stock levels, two of them below their reorder threshold.",[307,1068,1069,1070,1073,1074,1077,1078,1081],{},"The agent calls ",[520,1071,1072],{},"read_data_sources"," to get the built-in database's source id, applies the model with ",[520,1075,1076],{},"mutate_schema",", then seeds the sample data with ",[520,1079,1080],{},"create_items",". With the skill installed, it knows the exact tools and the shape of a valid migration.",[307,1083,1084],{},[554,1085],{"alt":1086,"src":1087},"The agent in the IDE creating the collections over MCP, with the new collections appearing in the Studio","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Fclaude-terminal.png",[307,1089,1090],{},"The MCP server exposes seven tools, each checked against your key's permissions:",[350,1092,1093,1103],{},[353,1094,1095],{},[356,1096,1097,1100],{},[359,1098,1099],{},"Tool",[359,1101,1102],{},"What it does",[369,1104,1105,1115,1124,1133,1143,1152,1162],{},[356,1106,1107,1112],{},[374,1108,1109],{},[520,1110,1111],{},"read_schema",[374,1113,1114],{},"Inspect collections, fields, and relations",[356,1116,1117,1121],{},[374,1118,1119],{},[520,1120,1072],{},[374,1122,1123],{},"List connected data sources; include the built-in database on request",[356,1125,1126,1130],{},[374,1127,1128],{},[520,1129,1076],{},[374,1131,1132],{},"Create or alter schema",[356,1134,1135,1140],{},[374,1136,1137],{},[520,1138,1139],{},"list_items",[374,1141,1142],{},"Query items with filter, sort, and pagination",[356,1144,1145,1149],{},[374,1146,1147],{},[520,1148,1080],{},[374,1150,1151],{},"Create one or more items",[356,1153,1154,1159],{},[374,1155,1156],{},[520,1157,1158],{},"update_item",[374,1160,1161],{},"Update a single item",[356,1163,1164,1169],{},[374,1165,1166],{},[520,1167,1168],{},"delete_item",[374,1170,1171],{},"Delete a single item",[1173,1174,1175,1177],"caution",{},[520,1176,1076],{}," can alter or drop collections and fields. Your admin key can run it while building. A deployed application never changes schema at runtime, so the scoped identity you ship with should not have that permission.",[498,1179],{},[303,1181,1183],{"id":1182},"_5-generate-the-sdk-and-build","5. Generate the SDK and Build",[307,1185,1186,1187,1191],{},"Now the payoff. Generate a client typed to ",[1188,1189,1190],"em",{},"your"," schema, then build the application against it with full autocomplete and compile-time safety.",[345,1193,1195],{"id":1194},"generate-the-typed-client","Generate the Typed Client",[307,1197,1198,1199,1201],{},"Install the SDK, scaffold a config, and generate the client. The ",[311,1200,84],{"href":323}," covers each step in depth.",[1203,1204,1206,1221,1235,1249],"code-group",{"sync":1205},"pm",[512,1207,1210],{"className":514,"code":1208,"filename":1209,"language":517,"meta":518,"style":518},"npm install @monospace\u002Fsdk\n","npm",[520,1211,1212],{"__ignoreMap":518},[523,1213,1214,1216,1218],{"class":525,"line":526},[523,1215,1209],{"class":529},[523,1217,770],{"class":533},[523,1219,1220],{"class":533}," @monospace\u002Fsdk\n",[512,1222,1225],{"className":514,"code":1223,"filename":1224,"language":517,"meta":518,"style":518},"pnpm add @monospace\u002Fsdk\n","pnpm",[520,1226,1227],{"__ignoreMap":518},[523,1228,1229,1231,1233],{"class":525,"line":526},[523,1230,1224],{"class":529},[523,1232,757],{"class":533},[523,1234,1220],{"class":533},[512,1236,1239],{"className":514,"code":1237,"filename":1238,"language":517,"meta":518,"style":518},"yarn add @monospace\u002Fsdk\n","yarn",[520,1240,1241],{"__ignoreMap":518},[523,1242,1243,1245,1247],{"class":525,"line":526},[523,1244,1238],{"class":529},[523,1246,757],{"class":533},[523,1248,1220],{"class":533},[512,1250,1253],{"className":514,"code":1251,"filename":1252,"language":517,"meta":518,"style":518},"bun add @monospace\u002Fsdk\n","bun",[520,1254,1255],{"__ignoreMap":518},[523,1256,1257,1259,1261],{"class":525,"line":526},[523,1258,1252],{"class":529},[523,1260,757],{"class":533},[523,1262,1220],{"class":533},[1203,1264,1265,1281,1297,1313],{"sync":1205},[512,1266,1268],{"className":514,"code":1267,"filename":1209,"language":517,"meta":518,"style":518},"npx @monospace\u002Fsdk init\n",[520,1269,1270],{"__ignoreMap":518},[523,1271,1272,1275,1278],{"class":525,"line":526},[523,1273,1274],{"class":529},"npx",[523,1276,1277],{"class":533}," @monospace\u002Fsdk",[523,1279,1280],{"class":533}," init\n",[512,1282,1284],{"className":514,"code":1283,"filename":1224,"language":517,"meta":518,"style":518},"pnpm exec monospace init\n",[520,1285,1286],{"__ignoreMap":518},[523,1287,1288,1290,1293,1295],{"class":525,"line":526},[523,1289,1224],{"class":529},[523,1291,1292],{"class":533}," exec",[523,1294,827],{"class":533},[523,1296,1280],{"class":533},[512,1298,1300],{"className":514,"code":1299,"filename":1238,"language":517,"meta":518,"style":518},"yarn run monospace init\n",[520,1301,1302],{"__ignoreMap":518},[523,1303,1304,1306,1309,1311],{"class":525,"line":526},[523,1305,1238],{"class":529},[523,1307,1308],{"class":533}," run",[523,1310,827],{"class":533},[523,1312,1280],{"class":533},[512,1314,1316],{"className":514,"code":1315,"filename":1252,"language":517,"meta":518,"style":518},"bun run monospace init\n",[520,1317,1318],{"__ignoreMap":518},[523,1319,1320,1322,1324,1326],{"class":525,"line":526},[523,1321,1252],{"class":529},[523,1323,1308],{"class":533},[523,1325,827],{"class":533},[523,1327,1280],{"class":533},[1203,1329,1330,1344,1359,1374],{"sync":1205},[512,1331,1333],{"className":514,"code":1332,"filename":1209,"language":517,"meta":518,"style":518},"npx @monospace\u002Fsdk generate\n",[520,1334,1335],{"__ignoreMap":518},[523,1336,1337,1339,1341],{"class":525,"line":526},[523,1338,1274],{"class":529},[523,1340,1277],{"class":533},[523,1342,1343],{"class":533}," generate\n",[512,1345,1347],{"className":514,"code":1346,"filename":1224,"language":517,"meta":518,"style":518},"pnpm exec monospace generate\n",[520,1348,1349],{"__ignoreMap":518},[523,1350,1351,1353,1355,1357],{"class":525,"line":526},[523,1352,1224],{"class":529},[523,1354,1292],{"class":533},[523,1356,827],{"class":533},[523,1358,1343],{"class":533},[512,1360,1362],{"className":514,"code":1361,"filename":1238,"language":517,"meta":518,"style":518},"yarn run monospace generate\n",[520,1363,1364],{"__ignoreMap":518},[523,1365,1366,1368,1370,1372],{"class":525,"line":526},[523,1367,1238],{"class":529},[523,1369,1308],{"class":533},[523,1371,827],{"class":533},[523,1373,1343],{"class":533},[512,1375,1377],{"className":514,"code":1376,"filename":1252,"language":517,"meta":518,"style":518},"bun run monospace generate\n",[520,1378,1379],{"__ignoreMap":518},[523,1380,1381,1383,1385,1387],{"class":525,"line":526},[523,1382,1252],{"class":529},[523,1384,1308],{"class":533},[523,1386,827],{"class":533},[523,1388,1343],{"class":533},[307,1390,1391,1394,1395,1397,1398,1051,1400,1402,1403,1405],{},[520,1392,1393],{},"generate"," reads your live schema over the OpenAPI endpoint, using the same ",[520,1396,704],{},", and writes a fully typed client. Every collection the agent created, ",[520,1399,997],{},[520,1401,1013],{},", and ",[520,1404,1036],{},", is now a typed property on the client.",[345,1407,1409],{"id":1408},"build-the-application","Build the Application",[307,1411,1412,1413,1416],{},"The console's entire data layer is two typed SDK calls — no hand-rolled API, no ORM. Sketch them in a scratch file, ",[520,1414,1415],{},"src\u002Frestock.ts",", to see the shape before your agent builds the UI around them.",[307,1418,1419],{},"List the products that have dropped below their reorder threshold, lowest stock first:",[512,1421,1425],{"className":1422,"code":1423,"filename":1415,"language":1424,"meta":518,"style":518},"language-typescript shiki shiki-themes monospace-light monospace-light monospace-dark","import { createClient } from '.\u002Fgenerated\u002Fmonospace';\n\nconst client = createClient({\n  url: 'http:\u002F\u002Flocalhost:8100',\n  workspace: 'acme-inventory',\n  apiKey: process.env.MONOSPACE_API_KEY,\n});\n\nconst stockLevels = await client.StockLevels.readMany({\n  fields: ['id', 'quantity_on_hand', { product: ['id', 'name', 'sku', 'reorder_threshold'] }],\n  sort: [{ quantity_on_hand: { direction: 'asc' } }],\n});\n\n\u002F\u002F Monospace filters compare a field to a value, not one field to another, so the\n\u002F\u002F reorder check runs here rather than in the query.\nconst lowStock = stockLevels.filter((level) => {\n  const threshold = level.product?.reorder_threshold;\n  return threshold != null && level.quantity_on_hand != null && level.quantity_on_hand \u003C threshold;\n});\n","typescript",[520,1426,1427,1450,1456,1473,1483,1493,1512,1517,1521,1546,1582,1593,1598,1603,1610,1616,1648,1673,1715],{"__ignoreMap":518},[523,1428,1429,1432,1435,1438,1441,1444,1447],{"class":525,"line":526},[523,1430,1431],{"class":707},"import",[523,1433,1434],{"class":871}," { ",[523,1436,1437],{"class":703},"createClient",[523,1439,1440],{"class":871}," } ",[523,1442,1443],{"class":707},"from",[523,1445,1446],{"class":533}," '.\u002Fgenerated\u002Fmonospace'",[523,1448,1449],{"class":871},";\n",[523,1451,1452],{"class":525,"line":763},[523,1453,1455],{"emptyLinePlaceholder":1454},true,"\n",[523,1457,1458,1461,1464,1467,1470],{"class":525,"line":840},[523,1459,1460],{"class":707},"const",[523,1462,1463],{"class":529}," client",[523,1465,1466],{"class":707}," =",[523,1468,1469],{"class":529}," createClient",[523,1471,1472],{"class":871},"({\n",[523,1474,1475,1478,1481],{"class":525,"line":891},[523,1476,1477],{"class":871},"  url: ",[523,1479,1480],{"class":533},"'http:\u002F\u002Flocalhost:8100'",[523,1482,903],{"class":871},[523,1484,1485,1488,1491],{"class":525,"line":906},[523,1486,1487],{"class":871},"  workspace: ",[523,1489,1490],{"class":533},"'acme-inventory'",[523,1492,903],{"class":871},[523,1494,1495,1498,1501,1503,1506,1508,1510],{"class":525,"line":919},[523,1496,1497],{"class":871},"  apiKey: ",[523,1499,1500],{"class":703},"process",[523,1502,325],{"class":871},[523,1504,1505],{"class":703},"env",[523,1507,325],{"class":871},[523,1509,704],{"class":529},[523,1511,903],{"class":871},[523,1513,1514],{"class":525,"line":927},[523,1515,1516],{"class":871},"});\n",[523,1518,1519],{"class":525,"line":938},[523,1520,1455],{"emptyLinePlaceholder":1454},[523,1522,1523,1525,1528,1530,1533,1535,1537,1539,1541,1544],{"class":525,"line":944},[523,1524,1460],{"class":707},[523,1526,1527],{"class":529}," stockLevels",[523,1529,1466],{"class":707},[523,1531,1532],{"class":707}," await",[523,1534,1463],{"class":703},[523,1536,325],{"class":871},[523,1538,1013],{"class":703},[523,1540,325],{"class":871},[523,1542,1543],{"class":529},"readMany",[523,1545,1472],{"class":871},[523,1547,1548,1551,1554,1556,1559,1562,1564,1566,1569,1571,1574,1576,1579],{"class":525,"line":950},[523,1549,1550],{"class":871},"  fields: [",[523,1552,1553],{"class":533},"'id'",[523,1555,1051],{"class":871},[523,1557,1558],{"class":533},"'quantity_on_hand'",[523,1560,1561],{"class":871},", { product: [",[523,1563,1553],{"class":533},[523,1565,1051],{"class":871},[523,1567,1568],{"class":533},"'name'",[523,1570,1051],{"class":871},[523,1572,1573],{"class":533},"'sku'",[523,1575,1051],{"class":871},[523,1577,1578],{"class":533},"'reorder_threshold'",[523,1580,1581],{"class":871},"] }],\n",[523,1583,1584,1587,1590],{"class":525,"line":956},[523,1585,1586],{"class":871},"  sort: [{ quantity_on_hand: { direction: ",[523,1588,1589],{"class":533},"'asc'",[523,1591,1592],{"class":871}," } }],\n",[523,1594,1596],{"class":525,"line":1595},12,[523,1597,1516],{"class":871},[523,1599,1601],{"class":525,"line":1600},13,[523,1602,1455],{"emptyLinePlaceholder":1454},[523,1604,1606],{"class":525,"line":1605},14,[523,1607,1609],{"class":1608},"seNfP","\u002F\u002F Monospace filters compare a field to a value, not one field to another, so the\n",[523,1611,1613],{"class":525,"line":1612},15,[523,1614,1615],{"class":1608},"\u002F\u002F reorder check runs here rather than in the query.\n",[523,1617,1619,1621,1624,1626,1628,1630,1633,1636,1639,1642,1645],{"class":525,"line":1618},16,[523,1620,1460],{"class":707},[523,1622,1623],{"class":529}," lowStock",[523,1625,1466],{"class":707},[523,1627,1527],{"class":703},[523,1629,325],{"class":871},[523,1631,1632],{"class":529},"filter",[523,1634,1635],{"class":871},"((",[523,1637,1638],{"class":707},"level",[523,1640,1641],{"class":871},") ",[523,1643,1644],{"class":707},"=>",[523,1646,1647],{"class":871}," {\n",[523,1649,1651,1654,1657,1659,1662,1664,1666,1669,1671],{"class":525,"line":1650},17,[523,1652,1653],{"class":707},"  const",[523,1655,1656],{"class":529}," threshold",[523,1658,1466],{"class":707},[523,1660,1661],{"class":703}," level",[523,1663,325],{"class":871},[523,1665,1016],{"class":703},[523,1667,1668],{"class":871},"?.",[523,1670,1007],{"class":703},[523,1672,1449],{"class":871},[523,1674,1676,1679,1681,1684,1687,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708,1711,1713],{"class":525,"line":1675},18,[523,1677,1678],{"class":707},"  return",[523,1680,1656],{"class":703},[523,1682,1683],{"class":707}," !=",[523,1685,1686],{"class":529}," null",[523,1688,1689],{"class":707}," &&",[523,1691,1661],{"class":703},[523,1693,325],{"class":871},[523,1695,1026],{"class":703},[523,1697,1683],{"class":707},[523,1699,1686],{"class":529},[523,1701,1689],{"class":707},[523,1703,1661],{"class":703},[523,1705,325],{"class":871},[523,1707,1026],{"class":703},[523,1709,1710],{"class":707}," \u003C",[523,1712,1656],{"class":703},[523,1714,1449],{"class":871},[523,1716,1718],{"class":525,"line":1717},19,[523,1719,1516],{"class":871},[307,1721,1722,1723,1726,1727,1729,1730,1732,1733,1736,1737,315,1740,1402,1743,1746],{},"The return type narrows to the exact ",[520,1724,1725],{},"fields"," you request, including the nested ",[520,1728,1016],{}," relation and its ",[520,1731,1007],{},". See ",[311,1734,139],{"href":1735},"\u002Fdeveloper\u002Fapi\u002Ffiltering"," for value operators like ",[520,1738,1739],{},"_lt",[520,1741,1742],{},"_in",[311,1744,144],{"href":1745},"\u002Fdeveloper\u002Fapi\u002Ffield-selection"," for nested relations.",[447,1748,1749,1750,1753,1754,1756],{},"Monospace filters compare a field to a value, not one field to another. A cross-field check — like stock below its ",[1188,1751,1752],{},"own"," ",[520,1755,1007],{}," — runs in your code after the read, as above.",[307,1758,1759],{},"File a restock request when an operator acts on a shortage:",[512,1761,1763],{"className":1422,"code":1762,"filename":1415,"language":1424,"meta":518,"style":518},"const request = await client.RestockRequests.createOne({\n  data: {\n    product: { _connect: { key: { id: lowStock[0].product.id } } },\n    quantity: 100,\n    status: 'submitted',\n    requested_by: 'restock-console',\n  },\n  fields: ['id', 'status', 'quantity'],\n});\n",[520,1764,1765,1789,1794,1821,1831,1841,1851,1856,1875],{"__ignoreMap":518},[523,1766,1767,1769,1772,1774,1776,1778,1780,1782,1784,1787],{"class":525,"line":526},[523,1768,1460],{"class":707},[523,1770,1771],{"class":529}," request",[523,1773,1466],{"class":707},[523,1775,1532],{"class":707},[523,1777,1463],{"class":703},[523,1779,325],{"class":871},[523,1781,1036],{"class":703},[523,1783,325],{"class":871},[523,1785,1786],{"class":529},"createOne",[523,1788,1472],{"class":871},[523,1790,1791],{"class":525,"line":763},[523,1792,1793],{"class":871},"  data: {\n",[523,1795,1796,1799,1802,1805,1808,1811,1813,1815,1818],{"class":525,"line":840},[523,1797,1798],{"class":871},"    product: { _connect: { key: { id: ",[523,1800,1801],{"class":703},"lowStock",[523,1803,1804],{"class":871},"[",[523,1806,1807],{"class":529},"0",[523,1809,1810],{"class":871},"].",[523,1812,1016],{"class":703},[523,1814,325],{"class":871},[523,1816,1817],{"class":703},"id",[523,1819,1820],{"class":871}," } } },\n",[523,1822,1823,1826,1829],{"class":525,"line":891},[523,1824,1825],{"class":871},"    quantity: ",[523,1827,1828],{"class":529},"100",[523,1830,903],{"class":871},[523,1832,1833,1836,1839],{"class":525,"line":906},[523,1834,1835],{"class":871},"    status: ",[523,1837,1838],{"class":533},"'submitted'",[523,1840,903],{"class":871},[523,1842,1843,1846,1849],{"class":525,"line":919},[523,1844,1845],{"class":871},"    requested_by: ",[523,1847,1848],{"class":533},"'restock-console'",[523,1850,903],{"class":871},[523,1852,1853],{"class":525,"line":927},[523,1854,1855],{"class":871},"  },\n",[523,1857,1858,1860,1862,1864,1867,1869,1872],{"class":525,"line":938},[523,1859,1550],{"class":871},[523,1861,1553],{"class":533},[523,1863,1051],{"class":871},[523,1865,1866],{"class":533},"'status'",[523,1868,1051],{"class":871},[523,1870,1871],{"class":533},"'quantity'",[523,1873,1874],{"class":871},"],\n",[523,1876,1877],{"class":525,"line":944},[523,1878,1516],{"class":871},[307,1880,723,1881,1884],{},[520,1882,1883],{},"data"," object is typed against your schema: required fields are enforced, and unknown fields are rejected.",[307,1886,1887,1888,1890],{},"Now hand your agent this prompt to wrap those two calls in a clean page. It writes the real app files — a server component and a server action — so the ",[520,1889,1415],{}," scratch can be deleted once it's done:",[983,1892,1893,1904],{},[307,1894,1895,1896,1899,1900,1903],{},"Using the generated ",[520,1897,1898],{},"@monospace\u002Fsdk"," client in ",[520,1901,1902],{},".\u002Fgenerated\u002Fmonospace",", build a single-page restock console with Next.js (App Router). Use no UI component library and only light custom CSS.",[467,1905,1906,1928,1931,1940,1946],{},[470,1907,1908,1909,1911,1912,1914,1915,1051,1917,1402,1919,1921,1922,1924,1925,1927],{},"In a server component, instantiate the client with ",[520,1910,704],{}," from the environment and query ",[520,1913,1013],{},", selecting each product's ",[520,1916,1000],{},[520,1918,1004],{},[520,1920,1007],{},"; keep the rows whose ",[520,1923,1026],{}," is below the product's ",[520,1926,1007],{},", sorted lowest stock first.",[470,1929,1930],{},"Render the results as a table: product, SKU, warehouse, and quantity on hand.",[470,1932,1933,1934,1936,1937,1939],{},"Give each row a \"Request restock\" button that files a ",[520,1935,1036],{}," item (quantity 100, status ",[520,1938,1054],{},") through a server action.",[470,1941,1942,1943,1945],{},"When a request is filed, show a brief confirmation toast (inline, no extra library) and list recently filed ",[520,1944,1036],{}," (product, quantity, status, and when they were filed) in a second table below.",[470,1947,1948],{},"Style it with a system font, generous spacing, and a clean card-and-table look.",[307,1950,1951],{},"Because the client runs in a server component, your API key stays on the server and never ships to the browser. Start the dev server:",[1203,1953,1954,1968,1979,1990],{"sync":1205},[512,1955,1957],{"className":514,"code":1956,"filename":1209,"language":517,"meta":518,"style":518},"npm run dev\n",[520,1958,1959],{"__ignoreMap":518},[523,1960,1961,1963,1965],{"class":525,"line":526},[523,1962,1209],{"class":529},[523,1964,1308],{"class":533},[523,1966,1967],{"class":533}," dev\n",[512,1969,1971],{"className":514,"code":1970,"filename":1224,"language":517,"meta":518,"style":518},"pnpm dev\n",[520,1972,1973],{"__ignoreMap":518},[523,1974,1975,1977],{"class":525,"line":526},[523,1976,1224],{"class":529},[523,1978,1967],{"class":533},[512,1980,1982],{"className":514,"code":1981,"filename":1238,"language":517,"meta":518,"style":518},"yarn dev\n",[520,1983,1984],{"__ignoreMap":518},[523,1985,1986,1988],{"class":525,"line":526},[523,1987,1238],{"class":529},[523,1989,1967],{"class":533},[512,1991,1993],{"className":514,"code":1992,"filename":1252,"language":517,"meta":518,"style":518},"bun run dev\n",[520,1994,1995],{"__ignoreMap":518},[523,1996,1997,1999,2001],{"class":525,"line":526},[523,1998,1252],{"class":529},[523,2000,1308],{"class":533},[523,2002,1967],{"class":533},[307,2004,2005,2006,2012],{},"Open ",[311,2007,2010],{"href":2008,"rel":2009},"http:\u002F\u002Flocalhost:3000",[476],[520,2011,2008],{}," and there it is: every product below its reorder threshold, each with a button that files a restock request.",[307,2014,2015],{},[554,2016],{"alt":2017,"src":2018},"The finished restock console listing low-stock products with a \"Request restock\" action","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Frestock-console-app.png",[307,2020,2021],{},"That's a working application, governed end to end, in about an hour.",[498,2023],{},[303,2025,2027],{"id":2026},"bonus-deploy-with-a-service-account","Bonus: Deploy with a Service Account",[307,2029,2030,2031,2034],{},"Your personal admin key is perfect for building. To run the console for real, give it its own identity, a ",[330,2032,2033],{},"service account",", scoped to exactly what the running application needs and nothing more.",[2036,2037,2038,2042,2045,2051,2055,2074,2127,2137,2141,2147],"steps",{},[345,2039,2041],{"id":2040},"create-a-service-account","Create a Service Account",[307,2043,2044],{},"A service account is a non-human identity that the deployed application acts as. Create one for the restock console so its access is separate from any person's login and survives you rotating your own key.",[307,2046,2047],{},[554,2048],{"alt":2049,"src":2050},"The service account creation screen in the Studio","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Fservice-accounts.png",[345,2052,2054],{"id":2053},"scope-it-with-a-role-and-policy","Scope It with a Role and Policy",[307,2056,2057,2061,2062,2065,2066,2069,2070,2073],{},[311,2058,2060],{"href":2059},"\u002Fconcepts\u002Faccess-permissions","Access in Monospace"," is built from ",[330,2063,2064],{},"roles"," (containers for policies), ",[330,2067,2068],{},"policies"," (where permissions are defined), and ",[330,2071,2072],{},"entitlements"," (system-level permissions). Assign the service account a role whose policy grants only what the console needs at runtime:",[350,2075,2076,2086],{},[353,2077,2078],{},[356,2079,2080,2083],{},[359,2081,2082],{},"Grant",[359,2084,2085],{},"Why the application needs it",[369,2087,2088,2103,2117],{},[356,2089,2090,2100],{},[374,2091,2092,2095,2096,1051,2098],{},[330,2093,2094],{},"Read"," on ",[520,2097,997],{},[520,2099,1013],{},[374,2101,2102],{},"List low-stock items",[356,2104,2105,2114],{},[374,2106,2107,315,2110,2095,2112],{},[330,2108,2109],{},"Create",[330,2111,2094],{},[520,2113,1036],{},[374,2115,2116],{},"File and display restock requests",[356,2118,2119,2124],{},[374,2120,2121],{},[520,2122,2123],{},"dataModel:read",[374,2125,2126],{},"Let the SDK generator read the schema at build time",[307,2128,2129,2130,315,2133,2136],{},"Notably absent: ",[520,2131,2132],{},"dataModel:edit",[520,2134,2135],{},"ai:mcp",". The deployed console reads and writes items through the SDK. It never mutates schema or calls the MCP server, so its identity can't either.",[345,2138,2140],{"id":2139},"mint-its-api-key","Mint Its API Key",[307,2142,2143,2144,2146],{},"Create an API key belonging to the service account, then set it as ",[520,2145,704],{}," in your deployment environment in place of your admin key.",[307,2148,2149],{},[554,2150],{"alt":2151,"src":2152},"The API key creation dialog scoped to the service account","\u002Fimages\u002Fguides\u002Fbuild-an-application\u002Fapi-keys-sa.png",[2154,2155,2156],"warning",{},"An API key grants the same access as its owner. Scope the service account to only what the application needs, keep the key in a secret store rather than source control, and rotate it if it ever leaks.",[498,2158],{},[303,2160,2162],{"id":2161},"next-steps","Next Steps",[467,2164,2165,2170,2175,2180,2185],{},[470,2166,2167,2169],{},[311,2168,16],{"href":509}," — the full Docker Compose setup for starting Monospace",[470,2171,2172,2174],{},[311,2173,94],{"href":318}," — per-client setup for Cursor, Codex, Gemini, and the OpenAI SDKs",[470,2176,2177,2179],{},[311,2178,84],{"href":323}," — codegen, the typed client, and every CRUD method",[470,2181,2182,2184],{},[311,2183,44],{"href":2059}," — roles, policies, and entitlements in depth",[470,2186,2187,2190],{},[311,2188,21],{"href":2189},"\u002Fgetting-started\u002Fuse-cases"," — other ways teams put Monospace to work",[2192,2193,2194],"style",{},"html pre.shiki code .ssBNi, html code.shiki .ssBNi{--shiki-light:#1659E9;--shiki-default:#1659E9;--shiki-dark:#94B3F5}html pre.shiki code .suKVh, html code.shiki .suKVh{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F8FAFC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sNJ9c, html code.shiki .sNJ9c{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E2E8F0}html pre.shiki code .sLVBU, html code.shiki .sLVBU{--shiki-light:#0891B2;--shiki-default:#0891B2;--shiki-dark:#22D3EE}html pre.shiki code .sTMul, html code.shiki .sTMul{--shiki-light:#1F2937;--shiki-default:#1F2937;--shiki-dark:#94A3B8}html pre.shiki code .snHjA, html code.shiki .snHjA{--shiki-light:#124BC4;--shiki-default:#124BC4;--shiki-dark:#5B8EF4}html pre.shiki code .seNfP, html code.shiki .seNfP{--shiki-light:#64748B;--shiki-default:#64748B;--shiki-dark:#94A3B8}",{"title":518,"searchDepth":763,"depth":763,"links":2196},[2197,2200,2201,2202,2203,2208,2209,2213,2218],{"id":305,"depth":763,"text":114,"children":2198},[2199],{"id":347,"depth":840,"text":348},{"id":464,"depth":763,"text":465},{"id":502,"depth":763,"text":503},{"id":593,"depth":763,"text":594},{"id":634,"depth":763,"text":635,"children":2204},[2205,2206,2207],{"id":662,"depth":840,"text":663},{"id":719,"depth":840,"text":720},{"id":787,"depth":840,"text":788},{"id":974,"depth":763,"text":975},{"id":1182,"depth":763,"text":1183,"children":2210},[2211,2212],{"id":1194,"depth":840,"text":1195},{"id":1408,"depth":840,"text":1409},{"id":2026,"depth":763,"text":2027,"children":2214},[2215,2216,2217],{"id":2040,"depth":840,"text":2041},{"id":2053,"depth":840,"text":2054},{"id":2139,"depth":840,"text":2140},{"id":2161,"depth":763,"text":2162},"An end-to-end walkthrough that starts Monospace, wires up your IDE and AI coding agent, bootstraps a schema, and ships a working application in about an hour.","md",null,{},{"icon":77},{"title":74,"description":2219},"k9kcR6-k7GNKFdZzcXBQdxVoa-tl5NoKpn0ZFH9wtKQ",[2227,2229],{"title":64,"path":65,"stem":66,"description":2228,"icon":67,"children":-1},"How Monospace's AI works — the embedded assistant and the MCP server, and the tools and permissions they share.",{"title":79,"path":80,"stem":81,"description":2230,"icon":82,"children":-1},"Read, create, filter, update, and delete data through the Monospace REST API.",1789461492901]