Connect an API or agent
Owners can open Project settings → API & agents to create a named connection. Choose a permission preset or customize the allowed actions. Copy the one-time key into your external agent's secret store. Keys expire and can be revoked at any time. One key covers every workspace in its world: Dictionary, Atlas, Encyclopedia, Ecology, and Timeline.
Connect with MCP
AI clients that support the Model Context Protocol can work in a world directly, without writing HTTP requests. Add /api/v1/projects/PROJECT_ID/mcp on this site as a Streamable HTTP server, with the header Authorization: Bearer YOUR_PROJECT_KEY. The server speaks protocol revision 2026-07-28.
claude mcp add --transport http wren-quill https://YOUR_HOST/api/v1/projects/PROJECT_ID/mcp \
--header "Authorization: Bearer YOUR_PROJECT_KEY"The agent sees tools for whatever its key permits: words, dialects and sound changes; map features, terrain, water, biomes and heightmaps; articles, species and events; images, saved versions, publishing and access. It can see the map it is working on and read or change any stored field by path. Tools run the same rules as the studio, such as inheriting dialect words and fitting region borders, and use the same conflict checks and limits as the endpoints below. Because they act on your drafts directly, review what your client allows without asking, especially publishing, access and deletion. A key belongs to one world, so creating, listing or deleting worlds stays in the studio.
Permission levels
Read only allows research across the world. Draft editor adds workspace editing, image uploads and saved-version management. Editor and publisher also permits publishing and unpublishing. World manager adds collaborator and agent-key management. Custom permissions let you grant individual read and write permissions for Dictionary, Atlas, Encyclopedia (including Ecology and Timeline), images and history, plus separate publishing, collaborator and integration permissions. Write permission includes read permission for the same resource. History read permission includes the complete saved Dictionary and Atlas documents.
Existing read/write keys retain their draft access without publishing or access management. An agent with integration management can issue only a subset of its own permissions, with an expiry no later than its own. Account security, staff administration, other worlds and browser display preferences are outside a project key. Discord setup requires a Discord server manager through the bot setup workflow.
Discover allowed actions
Start with GET /api/v1/projects/PROJECT_ID/capabilities. It returns the key’s permissions and expiry, every world operation and an allowed flag for each. The OpenAPI schema includes request shapes andx-permissions requirements. A valid key without the required permission receives 403.
Read a draft
Send GET /api/v1/projects/PROJECT_ID with the header Authorization: Bearer YOUR_PROJECT_KEY. The response contains id, revision, updatedAt, and data. The project includes its languages, lexicons, phonology, grammar, dialects, documentation, and families.
Save changes
Fetch the current draft, edit the relevant fields inside data, and preserve the rest. Send PUT to the same URL with JSON containing the current revision and the complete updated data. A successful response returns the new revision. The studio automatically refreshes when there are no unsaved local edits.
{
"revision": 1,
"data": {
"format": "wren-quill/1",
"name": "My language",
"languages": "Use the complete languages array from GET",
"families": "Preserve the families array from GET"
}
}The example above illustrates the request shape; the language and family placeholders must be replaced with actual arrays from GET. The OpenAPI schema defines every project field and can be imported into an agent's HTTP tools.
World and language settings
The project-level description describes the world. Each language keeps its owndescription and may include a font with an immutable UUID, filename, format (ttf, otf, woff or woff2), and base64 file data up to 2 MB decoded. Preserve these fields when editing a draft. Fonts affect language text visually; they do not change word spellings or IPA. Published snapshots retain their own font data.
Optional language-level fontDisplay controls scale (0.5–3, default 1), showRomanized (default false), and romanizedOpacity(0.35–0.85, default 0.6). The companion spelling uses the stored text in standard lettering when a custom font is loaded. These preferences also apply to dialect views and are saved in published snapshots.
English lookup terms and definitions
Each word may include translations, an ordered array of up to 50 English words or phrases (1–100 characters each). For example, use ["hello", "hi"]with a definition such as “A greeting used when meeting someone.” The first term is the preferred English translation. senses[].meaning remains the full definition; it does not supply translation matches. Example sentences retain their own translations. Preserve the array when editing, copying, or evolving vocabulary. Older entries without this optional field remain valid but need explicit lookup terms for word translation.
Inherited dialect entries
A dialect's inheritedWords maps its local entry IDs to entry IDs in its parent branch (parentId, or the standard language when null). Resolve the parent recursively, then use the local ID and dialect ID for each inherited entry. A full entry in language.words with that local ID overrides the inherited entry. Otherwise the parent supplies its content. Preserve these references when saving; you do not need to expand the full lexicon into duplicate entries.
To edit an inherited word, add its resolved entry to language.words with the same local ID and the target dialect ID. To delete it from a dialect, remove both its reference and any local override. Before deleting a parent entry, materialize any child references that depend on it and remove those references. Invalid dangling references are rejected. New parent words can be inherited through Copy words; existing references follow parent edits until overridden. Exports and published releases preserve the same structure.
Atlas
GET /api/v1/projects/PROJECT_ID/atlas returns the world map in the same id, revision, updatedAt, data shape. A world without a map returns revision 0 and null data. Send PUT with the latest revision and the complete atlas; use revision 0 only to create the first map. A successful save returns only the new id, revision and updatedAt; GET the atlas to read it back. Features are land, elevation, region, forest, lake, river, road, label, location, and event shapes on a 10,000 × 6,000 unit canvas. GET always returns whole features. A PUT may leave out fields at their defaults, and the points of a vector outline, which default to its bounding box. Coordinates are stored to 0.001 units.
The top-level features are the home planet's map. A world with more planets lists them in planets, each with an id, name, kilometersPerUnit and its own features; an optional atmosphere (air color and density, clouds and their color, scale, speed and seed) sets a planet's sky on the globe, the top-level one for home. Keep the planets list when you save, or those planets will be removed.
Encyclopedia, Ecology, and Timeline
GET and PUT /api/v1/projects/PROJECT_ID/index read and save one document shared by three workspaces. Encyclopedia articles and categories are entries and folders. Ecology species and biomes are entries with ecology metadata, and their relationships are in ecology.links. Timeline events are entries with timeline start and end years; eras and year systems are in the top-level timeline. Editing an entry changes it in every workspace that shows it. Entries with secret: true stay readable through the API but are left out of published releases. Entries and folders may have an icon: lucide:<icon-name> for any Lucide icon, or emoji:<emoji> for one emoji.
Events may have timeline.locations, an optional list of Atlas feature UUIDs across any planet. Places keep their own articles and lifespans. An Atlas event marker whose article refers to a Timeline entry uses that entry's dates in the map; edit the entry's timeline.start and timeline.end to change shared history. Its stored Atlas years are a fallback when no Timeline event is linked.
When a species name uses a language's script, the server copies that language's font into languageScripts on save. You may omit or preserve that field. Revision rules match the atlas.
Images and storage
GET /api/v1/projects/PROJECT_ID/media lists only this world’s ready images and the owner’s shared storage allowance. Fetch private image bytes from/media/IMAGE_ID using the same bearer header. To upload, sendPOST /media?name=Portrait&kind=image with a binary WebP body andContent-Type: image/webp. Images must be at most 200 KB and 1,600 pixels per side; kind=map allows 2 MB and 4,096 pixels. R2 must be connected.
The upload returns an id. Use /api/media/IMAGE_ID in saved article Markdown; the studio uses that stable URL. Send DELETE /media with{"mediaId":"IMAGE_ID"} to remove an unused file. References in drafts, saved versions or publications prevent deletion. Agents cannot browse another world’s library, reuse its images by ID or delete shared files; the owner manages shared images in Images & storage.
Saved versions
GET /versions lists Dictionary revisions and GET /versions/VERSION_IDreads one. Create a checkpoint with POST /versions and{"revision":1,"label":"Before changes"}. Overwrite an unpublished revision with PUT /versions/VERSION_ID and the current draft revision and saved version’s generation. Delete one with DELETE and its generation. Restore with POST /versions/VERSION_ID/restore and both values; restoration requires history write and Dictionary write. Responses acknowledge changes; GET the draft again to read restored data.
Atlas history lives at /atlas/versions. POST a complete Atlas indata, reason: "named" and a label to save one. GET or DELETE/atlas/versions/VERSION_ID to read or remove it. Before restoring, POST the current Atlas as data to /atlas/versions/VERSION_ID/restore to keep a checkpoint, then PUT the saved version’s Atlas to /atlas using the latest Atlas revision. The Encyclopedia, Ecology and Timeline share their document’s revision counter; they do not have a separate named-version library.
Publishing and access management
With publishing permission, POST {"versionId":"VERSION_ID","generation":1}to /publication to publish a Dictionary revision; set versionIdto null to unpublish. Atlas and Encyclopedia use /atlas/publication and/index/publication: POST {"action":"publish","revision":1}or {"action":"unpublish","publishedAt":"VALUE_FROM_GET"}. Secret Encyclopedia entries remain excluded from releases. Each publication endpoint’s GET returns its current status. To release all three together, GET /world/publication for the current revisions and POST them back as {"revisions":{…}}, with an optional dictionaryVersion.
With collaborator permission, GET /members to list collaborators and POST or DELETE {"email":"editor@example.com"} to add or remove one. Integration permission enables GET, POST and DELETE on /integrations. Creation uses name, kind (agent or api), scope(read or write), permissions and expiresInDays (30, 90 or 365). Any mutation permission requires write scope. The new token is returned once. Revoke a key with {"keyId":"KEY_ID"}. All paths in these sections are relative to /api/v1/projects/PROJECT_ID.
Language tools and cross-workspace links
GET /tools?tool=transcribe&languageId=LANGUAGE_ID&text=WORD uses saved romanization and sound rules. The tool can also be generate (count 1–500, min/max syllables 1–5), sound-change (text is IPA) or translate(reverse=1 for English to the language). Optional dialectId selects dialect phonology or vocabulary, including inherited entries. Tools return previews without saving; accept results into the Dictionary through its ordinary revision-protected PUT.
Article choices are available at GET /index/entries and map places atGET /atlas/places. POST title, template (article, city or event) and optional Timeline dates to /index/entries to start an article. POST feature and article (or null to unlink) to/atlas/places. GET /index/timeline for shared dates; PATCH it with entry, its current revision and date. All other feature and document fields remain available through the complete document APIs.
Conflicts and limits
409: another person or agent saved first. Fetch the newest revision, merge your intended changes, then retry. Do not simply increase the revision to overwrite another editor's work. Each document has its own revision, so a dictionary save never conflicts with an atlas save. 400: the JSON or document structure is invalid. 413: the request exceeds 4 MB in transit, or after decompression 20 MB for a dictionary draft or 12 MB for the atlas or Encyclopedia. Send large JSON with Content-Encoding: gzip; large responses also use gzip. 429: the key exceeded 120 requests per minute across all endpoints; wait for the Retry-After interval.
Access
Each key works for one project only, with the permissions its owner selected. Draft edits leave published Dictionary, Atlas and Encyclopedia snapshots unchanged until an authorized publisher publishes again. Project keys cannot edit staff documentation. Open studio tabs load an integration's saves automatically when they have no unsaved edits. A revoked or expired key returns 401.
No AI provider or agent is hosted here. Your external agent makes API requests using its project key. API keys are stored as hashes, are excluded from project exports and published releases, and cannot be retrieved after creation.