EnglishFrançais
MGS Toolbox public API
The reference data behind the encyclopedias and the MGS Audio catalogue, as JSON, as an MCP server and as embeddable cards. Free, no key, link back.
Everything the MGS Toolbox shows is available here: 88 metals, 141 minerals, 350 ingredients, 54 potions, 58 gems, the Crafting Table rules, and the MGS Audio catalogue (tracks, composers, albums, packs, taxonomy). Every item carries url, the page to link, and embed_url, a card to iframe. Texts exist in English and French.
What you can build
Chat bot lookups
A Discord, Slack or Telegram command that answers !mineral obsidian or !metal mithral with the entry and its link. One call to /search, one to the entry.
Loot and prompt generators
/minerals/random?rarity=rare&gem_quality=true for treasure, /ingredients/random?environment=swamp for a foraging roll, /metals/random?fictional=true for a mysterious blade.
VTT and note-taking integrations
Foundry, Roll20, Owlbear Rodeo, Obsidian, Notion, World Anvil, Kanka: pull an entry into a journal, a handout or a wiki page — with the card embedded and the link kept.
Session soundtrack pickers
/audio/tracks?keyword=dungeon&era=fantasy or /audio/tracks/random?type=ambience&genre=Forest, then hand the player the track page or the album player.
Crafting helpers
Recipes and ingredient databases for your own crafting rules: essences, prices, harvest DCs, potion magnitudes, gem effects, plus the full rules text.
Encyclopedia cards on your site
Paste a link (oEmbed) or an iframe: a bilingual card with the key facts and a link back — no code, no API call.
Your AI assistant, with real data
Add the MCP server to Claude, ChatGPT, Cursor or your own agent: it looks entries and tracks up here instead of guessing, and cites the page.
Quick start
curl "https://michaelghelfistudios.com/api/v1/search?q=mithral"
curl "https://michaelghelfistudios.com/api/v1/metals/mithral?lang=fr"
curl "https://michaelghelfistudios.com/api/v1/minerals?system=cubic&gem_quality=true&limit=5"
curl "https://michaelghelfistudios.com/api/v1/audio/tracks/random?genre=Combat&type=music"
From a browser or a bot, no headers needed (CORS is open):
const res = await fetch('https://michaelghelfistudios.com/api/v1/ingredients/random?environment=swamp&lang=en');
const { data } = await res.json();
console.log(data.name, data.rarity, data.url); // "Bog Iris", "uncommon", "https://…/apps/rerum/bog_iris"
Every response is an envelope:
{
"success": true,
"data": …, // an item, an array, or an object
"meta": { "version": "v1", "lang": "en", "total": 141, "limit": 50, "offset": 0,
"license": { "name": "…", "url": "…", "attribution": "…" } },
"links": { "self": "…", "docs": "https://michaelghelfistudios.com/api/v1/docs" }
}
Conventions
| Base URL | https://michaelghelfistudios.com/api/v1 — HTTPS, GET only, JSON (UTF-8). |
|---|---|
| Language | ?lang=en (default), fr, or all to receive every text as { "en": …, "fr": … }. Identifiers, categories and other codes are never translated: they are stable keys (very_rare, cubic, feywild). |
| Pagination | limit (max 200) and offset; meta.total is the full count. |
| Filters | Comma-separated values mean "any of": ?rarity=rare,legendary. Matching is case- and accent-insensitive. /…/facets lists the values. |
| Caching | Reference data changes rarely and is served with Cache-Control: public, max-age=3600 and an ETag (send If-None-Match to get a 304); the audio catalogue with max-age=300. Please honour it. |
| Rate limit | 120 requests per minute per IP, with the standard RateLimit-* headers. Need more for a real project? Say so at michaelghelfistudios.com. |
| Identify yourself | Send a User-Agent naming your project (MyBot/1.0 (+https://example.com)). It is how we know what to keep stable, and whom to warn before a change. |
| Errors | Non-2xx responses are { "success": false, "error": "…" }. 404 for an unknown item or catalogue, 429 when rate-limited, 400 for a malformed request. |
| Audio | Metadata only. There is no audio file URL anywhere in the API: link the track page, or embed the album player. Vocabulary: genre is the theme (Combat, Forest, Taverns and Inns…), mood the musical style (Orchestral, Celtic…), era the setting (fantasy, scifi…), keyword free tags; all case-insensitive, listed by /audio/taxonomy. |
Embeds & oEmbed
Cards
Every entry, track, artist and album has a card at /apps/embed/{kind}/{id} (kinds: metal, mineral, ingredient, potion, gem, track, artist, album). Options: ?lang=fr, ?theme=light|dark (default follows the visitor). The "Share" button on every encyclopedia page copies this for you. Minerals of the Crystal Forge show their rendered specimen (also image_url in the API and oEmbed's thumbnail_url); track cards play the site's 30-second preview — the JSON API itself still returns no audio URL.
<iframe src="https://michaelghelfistudios.com/apps/embed/metal/iron?lang=en" width="100%" height="340"
style="border:0;max-width:480px" loading="lazy" title="Iron — Metal Encyclopedia"></iframe>
Cards post their height to the host page, so an iframe can fit its content:
window.addEventListener('message', (e) => {
if (e.data?.type !== 'mgs-embed') return;
document.querySelectorAll('iframe').forEach((f) => { if (f.src === e.data.href) f.height = e.data.height; });
});
oEmbed
Paste a page link into WordPress, Discord, Notion, Ghost, Discourse or any platform with oEmbed discovery and it becomes the card by itself: every page advertises https://michaelghelfistudios.com/api/v1/oembed?url=…. Integrators can call it directly:
curl "https://michaelghelfistudios.com/api/v1/oembed?url=https%3A%2F%2Fmichaelghelfistudios.com%2Fapps%2Fcrystal%2Fquartz&maxwidth=400"
Album player
Albums have a real player with a preview of every track: https://michaelghelfistudios.com/audio/embed/{albumId} (450px high). It is what oEmbed returns for an album page.
Whole encyclopedias
The encyclopedias themselves accept being framed (/apps/metals/, /apps/crystal/, /apps/rerum/), which is how the Foundry VTT module shows them inside a world.
MCP server
The same catalogues as an MCP server, for AI assistants and agents: https://michaelghelfistudios.com/api/v1/mcp (Streamable HTTP, stateless, no key, read-only). Tools: search_encyclopedia, get_entry, list_entries, random_entry, list_facets, craft_rules, search_tracks, random_track, get_track, list_composers, list_albums, audio_taxonomy. Every result carries the entries' url and the server's instructions ask the assistant to cite it.
Claude Code:
claude mcp add --transport http mgs-toolbox https://michaelghelfistudios.com/api/v1/mcp
Claude Desktop, Cursor, VS Code, Windsurf and most clients accept a remote server by URL in their MCP settings; the JSON form is:
{
"mcpServers": {
"mgs-toolbox": { "type": "http", "url": "https://michaelghelfistudios.com/api/v1/mcp" }
}
}
Clients that only speak stdio can bridge it with npx mcp-remote https://michaelghelfistudios.com/api/v1/mcp. The server is listed in the official MCP Registry as com.michaelghelfistudios/toolbox. Same rate limit and terms as the JSON API.
Your own data
Your Fantasy City Simulator settlements and Crafting Table campaigns, from your own tools: a Discord bot that posts the settlement's food and gold, a wiki page that lists its inhabitants, a script that exports a party's inventory. Read-only, under a personal API key you create in the hub (menu → API keys) and can revoke any time.
Send it as a bearer token on the /me routes and nowhere else — it is not accepted anywhere else:
curl -H "Authorization: Bearer mgsk_…" "https://michaelghelfistudios.com/api/v1/me/settlements"
curl -H "Authorization: Bearer mgsk_…" "https://michaelghelfistudios.com/api/v1/me/settlements/42/inhabitants?lang=fr"
A key carries the scopes you pick at creation: profile (who you are), fcs:read (settlements, dashboard, inhabitants, campaigns), craft:read (the Crafting Table campaigns you run and their inventories; Patreon, as on the site). Everything is read-only.
There is no audio on this surface, by design: a key never lists entitlements, never downloads, never streams. What you can do with the music catalogue is what the public endpoints offer to everyone.
Keys are stored hashed, look like mgsk_… so secret scanners recognise them, count against the same rate limit as the public API, and show their last use in the hub. Lose one? Revoke it and make another.
Endpoints
Generated from the OpenAPI description. The reference is in English in both languages.
Reference data
Metals, minerals, ingredients, potions, gems and the crafting rules.
GET/api/v1/search
Search every catalogue by name — One query across metals, minerals, ingredients, potions and gems. Exact names first, then prefixes, then substrings (aliases and synonyms count). The go-to endpoint for a chat bot's !lookup command.
| Parameter | Type | Description |
|---|---|---|
q required | string | Name search, case- and accent-insensitive. Best matches first. |
kind | string | Restrict to some catalogues, comma-separated (metal,mineral). |
limit | integer (default 20) | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /search
GET/api/v1/metals
List metals — Real elements, historical alloys, mythological and fictional metals, with physical, mechanical and chemical properties plus lore. The Metal Encyclopedia. 88 entries.
| Parameter | Type | Description |
|---|---|---|
category | string | One or more categories, comma-separated. fictional_ipfictional_ttrpgmythologicalreal_alloyreal_pure |
era | string | One or more eras, comma-separated. ancientmedievalmodernsci-fitimeless |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery rare |
fictional | boolean | true for invented metals, false for real ones. |
tag | string | One or more tags, comma-separated. |
q | string | Name search, case- and accent-insensitive. Best matches first. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /metals
GET/api/v1/metals/facets
Filter values for metals — Every distinct value of each filterable field, for building pickers.
Try it: GET /metals/facets
GET/api/v1/metals/random
A random metal — One entry at random among those matching the same filters as the listing. Loot tables, prompts, "mineral of the day".
| Parameter | Type | Description |
|---|---|---|
category | string | One or more categories, comma-separated. fictional_ipfictional_ttrpgmythologicalreal_alloyreal_pure |
era | string | One or more eras, comma-separated. ancientmedievalmodernsci-fitimeless |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery rare |
fictional | boolean | true for invented metals, false for real ones. |
tag | string | One or more tags, comma-separated. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /metals/random
GET/api/v1/metals/{id}
One metal
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /metals/iron
GET/api/v1/minerals
List minerals — Real and fantasy minerals: crystallography, physical properties, geology, arcane properties. The Crystal Encyclopedia. 141 entries.
| Parameter | Type | Description |
|---|---|---|
type | string | real or fantasy.fantasyreal |
system | string | Crystal system(s), comma-separated. amorphouscubichexagonalmonoclinicorthorhombictetragonaltriclinictrigonal |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery rare |
gem_quality | boolean | true to keep gem-quality minerals only. |
color | string | Colour(s), comma-separated. |
magic | boolean | true to keep minerals with arcane properties. |
planar_origin | string | Planar origin(s), comma-separated. abyssastral_planecelestiaelemental_plane_earthelemental_plane_firefar_realmfeywildmaterial_planenine_hellsshadowfell |
origin | string | Geological origin(s), comma-separated. glacialhydrothermaligneousmetamorphicmeteoricplanarsedimentaryvolcanic |
q | string | Name search, case- and accent-insensitive. Best matches first. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /minerals
GET/api/v1/minerals/facets
Filter values for minerals — Every distinct value of each filterable field, for building pickers.
Try it: GET /minerals/facets
GET/api/v1/minerals/random
A random mineral — One entry at random among those matching the same filters as the listing. Loot tables, prompts, "mineral of the day".
| Parameter | Type | Description |
|---|---|---|
type | string | real or fantasy.fantasyreal |
system | string | Crystal system(s), comma-separated. amorphouscubichexagonalmonoclinicorthorhombictetragonaltriclinictrigonal |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery rare |
gem_quality | boolean | true to keep gem-quality minerals only. |
color | string | Colour(s), comma-separated. |
magic | boolean | true to keep minerals with arcane properties. |
planar_origin | string | Planar origin(s), comma-separated. abyssastral_planecelestiaelemental_plane_earthelemental_plane_firefar_realmfeywildmaterial_planenine_hellsshadowfell |
origin | string | Geological origin(s), comma-separated. glacialhydrothermaligneousmetamorphicmeteoricplanarsedimentaryvolcanic |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /minerals/random
GET/api/v1/minerals/{id}
One mineral
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /minerals/quartz
GET/api/v1/ingredients
List ingredients — Alchemical ingredients for tabletop crafting: category, rarity, price, essences, environments, harvesting. Rerum Natura. 350 entries.
| Parameter | Type | Description |
|---|---|---|
category | string | One or more categories, comma-separated. creaturemineralphenomenaplantprocessed |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery_rare |
environment | string | Environment(s) the ingredient is found in, comma-separated. anyaquaticastralcavedesertdungeonfeywildforestgraveyardjunglemountainoceanplanarshadowfellswamptundraunderdarkurbanvolcanic |
essence | string | Essence type(s), comma-separated. airastraleeauempyréenneéternitéétherfeulumièremortombreprimordialetelluriqueterrevie |
tag | string | One or more tags, comma-separated. |
q | string | Name search, case- and accent-insensitive. Best matches first. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /ingredients
GET/api/v1/ingredients/facets
Filter values for ingredients — Every distinct value of each filterable field, for building pickers.
Try it: GET /ingredients/facets
GET/api/v1/ingredients/random
A random ingredient — One entry at random among those matching the same filters as the listing. Loot tables, prompts, "mineral of the day".
| Parameter | Type | Description |
|---|---|---|
category | string | One or more categories, comma-separated. creaturemineralphenomenaplantprocessed |
rarity | string | One or more rarities, comma-separated. commonlegendaryrareuncommonvery_rare |
environment | string | Environment(s) the ingredient is found in, comma-separated. anyaquaticastralcavedesertdungeonfeywildforestgraveyardjunglemountainoceanplanarshadowfellswamptundraunderdarkurbanvolcanic |
essence | string | Essence type(s), comma-separated. airastraleeauempyréenneéternitéétherfeulumièremortombreprimordialetelluriqueterrevie |
tag | string | One or more tags, comma-separated. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /ingredients/random
GET/api/v1/ingredients/{id}
One ingredient
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
GET/api/v1/potions
List potions — Potions of the Crafting Table: essences needed, crafting time, spellcaster level, effects by magnitude. 54 entries.
| Parameter | Type | Description |
|---|---|---|
essence | string | Essence type(s), comma-separated. airastraleeauempyréenneéternitéétherfeulumièremortombreprimordialetelluriqueterrevie |
q | string | Name search, case- and accent-insensitive. Best matches first. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /potions
GET/api/v1/potions/facets
Filter values for potions — Every distinct value of each filterable field, for building pickers.
Try it: GET /potions/facets
GET/api/v1/potions/random
A random potion — One entry at random among those matching the same filters as the listing. Loot tables, prompts, "mineral of the day".
| Parameter | Type | Description |
|---|---|---|
essence | string | Essence type(s), comma-separated. airastraleeauempyréenneéternitéétherfeulumièremortombreprimordialetelluriqueterrevie |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /potions/random
GET/api/v1/potions/{id}
One potion
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /potions/potion_alerte
GET/api/v1/gems
List gems — Socketable gems of the Crafting Table: colour, rarity, effect at each level. 58 entries.
| Parameter | Type | Description |
|---|---|---|
color | string | Colour(s), comma-separated. anyblackbluegreenmetaorangepurpleredwhiteyellow |
rarity | string | One or more rarities, comma-separated. legendaryrareuncommonvariablevery_rare |
temporary | boolean | true for gems whose effect is consumed. |
q | string | Name search, case- and accent-insensitive. Best matches first. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /gems
GET/api/v1/gems/facets
Filter values for gems — Every distinct value of each filterable field, for building pickers.
Try it: GET /gems/facets
GET/api/v1/gems/random
A random gem — One entry at random among those matching the same filters as the listing. Loot tables, prompts, "mineral of the day".
| Parameter | Type | Description |
|---|---|---|
color | string | Colour(s), comma-separated. anyblackbluegreenmetaorangepurpleredwhiteyellow |
rarity | string | One or more rarities, comma-separated. legendaryrareuncommonvariablevery_rare |
temporary | boolean | true for gems whose effect is consumed. |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /gems/random
GET/api/v1/gems/{id}
One gem
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /gems/gem_defense
GET/api/v1/craft/rules
The Crafting Table rules — The rules text of the crafting system (characters, essences, extraction, brewing, gem cutting, socketing) as HTML sections with stable ids — the same text the Foundry module writes into its journal.
| Parameter | Type | Description |
|---|---|---|
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Try it: GET /craft/rules
Audio catalogue
Tracks, composers, albums, packs and taxonomy of MGS Audio.
GET/api/v1/audio/tracks
List published tracks — Music, ambiences and sound effects of MGS Audio with their metadata, composer, album and pages. Metadata only: the API never serves audio bytes — link the url or iframe the album player.
| Parameter | Type | Description |
|---|---|---|
type | string | Audio type(s), comma-separated: music, ambience, sfx… |
genre | string | Theme(s), comma-separated, case-insensitive: Combat, Forest, Taverns and Inns… (see /audio/taxonomy). |
mood | string | Musical style(s), comma-separated — Orchestral, Celtic, Folk… — any of them matches. |
era | string | Era token(s), comma-separated. |
keyword | string | Keyword(s), comma-separated — any of them matches. |
composer | string | A composer id or slug. |
album | string | An album id or slug. |
pack | string | A pack id or slug. |
duration_min | number | Minimum duration in seconds. |
duration_max | number | Maximum duration in seconds. |
q | string | Text search in title, description and keywords. |
include_versions | boolean (default false) | true to list alternative versions as separate items (default: main tracks only). |
sort | string (default newest) | Order of the listing. newestoldesttitledurationrandom |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /audio/tracks
GET/api/v1/audio/tracks/random
A random track — One published track matching the filters. "Play me a battle theme" in a bot is ?genre=Combat&type=music; "a forest ambience" is ?type=ambience&genre=Forest.
| Parameter | Type | Description |
|---|---|---|
type | string | Audio type(s), comma-separated: music, ambience, sfx… |
genre | string | Theme(s), comma-separated, case-insensitive: Combat, Forest, Taverns and Inns… (see /audio/taxonomy). |
mood | string | Musical style(s), comma-separated — Orchestral, Celtic, Folk… — any of them matches. |
era | string | Era token(s), comma-separated. |
keyword | string | Keyword(s), comma-separated — any of them matches. |
composer | string | A composer id or slug. |
album | string | An album id or slug. |
pack | string | A pack id or slug. |
duration_min | number | Minimum duration in seconds. |
duration_max | number | Maximum duration in seconds. |
q | string | Text search in title, description and keywords. |
include_versions | boolean (default false) | true to list alternative versions as separate items (default: main tracks only). |
Try it: GET /audio/tracks/random
GET/api/v1/audio/tracks/{id}
One track — By id or slug (the slug from the track page URL). Includes its published alternative versions.
| Parameter | Type | Description |
|---|---|---|
id required | string |
Try it: GET /audio/tracks/
GET/api/v1/audio/composers
List composers — Every composer with at least one published track, most prolific first.
Try it: GET /audio/composers
GET/api/v1/audio/composers/{id}
One composer
| Parameter | Type | Description |
|---|---|---|
id required | string | Id or slug. |
Try it: GET /audio/composers/
GET/api/v1/audio/composers/{id}/tracks
A composer's tracks
| Parameter | Type | Description |
|---|---|---|
id required | string | |
type | string | Audio type(s), comma-separated: music, ambience, sfx… |
genre | string | Theme(s), comma-separated, case-insensitive: Combat, Forest, Taverns and Inns… (see /audio/taxonomy). |
mood | string | Musical style(s), comma-separated — Orchestral, Celtic, Folk… — any of them matches. |
era | string | Era token(s), comma-separated. |
keyword | string | Keyword(s), comma-separated — any of them matches. |
album | string | An album id or slug. |
pack | string | A pack id or slug. |
duration_min | number | Minimum duration in seconds. |
duration_max | number | Maximum duration in seconds. |
q | string | Text search in title, description and keywords. |
include_versions | boolean (default false) | true to list alternative versions as separate items (default: main tracks only). |
sort | string (default newest) | Order of the listing. newestoldesttitledurationrandom |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /audio/composers//tracks
GET/api/v1/audio/albums
List albums — Published albums (Patreon-only collections are not listed).
| Parameter | Type | Description |
|---|---|---|
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /audio/albums
GET/api/v1/audio/albums/{id}
One album
| Parameter | Type | Description |
|---|---|---|
id required | string | Id or slug. |
Try it: GET /audio/albums/
GET/api/v1/audio/albums/{id}/tracks
An album's tracks — In album order.
| Parameter | Type | Description |
|---|---|---|
id required | string | |
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /audio/albums//tracks
GET/api/v1/audio/packs
List packs — Thematic packs (the unit Patreon supporters download in bulk).
| Parameter | Type | Description |
|---|---|---|
limit | integer (default 50) | Page size (1–200, default 50). |
offset | integer (default 0) | Number of items to skip. |
Try it: GET /audio/packs
GET/api/v1/audio/taxonomy
Genres, moods, eras and keywords — Every value in use across published tracks — the vocabulary of the track filters.
Try it: GET /audio/taxonomy
Your own data
Read-only access to the account's Fantasy City Simulator and Crafting Table data, with a personal API key (Authorization: Bearer mgsk_…). No audio here, by design.
GET/api/v1/me
Who the key belongs to
GET/api/v1/me/settlements
Your Fantasy City Simulator settlements — Every settlement the account is a member of, with its role.
GET/api/v1/me/settlements/{id}
One settlement and its current game state
| Parameter | Type | Description |
|---|---|---|
id required | integer |
GET/api/v1/me/settlements/{id}/dashboard
The full FCS dashboard — Resources, jobs, buildings, construction queue, recent events… — the same object the FCS app renders. Its shape follows the app and may change.
| Parameter | Type | Description |
|---|---|---|
id required | integer |
GET/api/v1/me/settlements/{id}/inhabitants
The inhabitants of a settlement — Each with species, job, a rendered description and journal in the requested language; the GM-only secret travels for gamemasters.
| Parameter | Type | Description |
|---|---|---|
id required | integer | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
GET/api/v1/me/campaigns
Your campaigns — The hub campaigns (a GM, players, settlements, crafting tables) the account belongs to.
GET/api/v1/me/craft/campaigns
The Crafting Table campaigns you run — Patreon membership required, as on the website.
GET/api/v1/me/craft/campaigns/{id}/inventories
Every member's inventory — Potions, ingredients, essences, gems and socketed equipment of each character, rendered in the requested language. DM only, Patreon required.
| Parameter | Type | Description |
|---|---|---|
id required | string | |
lang | string (default en) | Language of the texts: en (default), fr, or all to get every text as an { "en", "fr" } object.enfrall |
Embeds
oEmbed and cards.
GET/api/v1/oembed
oEmbed provider — Turns one of our page URLs (an encyclopedia entry, a track, an artist, an album) into an embeddable card, per the oEmbed spec. Platforms that support oEmbed discovery (WordPress, Discord, Notion, Ghost, Discourse…) call this on their own when a link is pasted.
| Parameter | Type | Description |
|---|---|---|
url required | string | The page URL. |
format | string | json |
maxwidth | integer | |
maxheight | integer |
Try it: GET /oembed
Meta
Index and documents.
Terms
MGS Toolbox open data terms. Short version: use it, link back, don't clone the site, don't redistribute music.
- Free to use
- Personal, community and commercial tools alike: Discord bots, VTT modules, note-taking plugins, wikis, generators, your own website. No key, no sign-up, no fee.
- Link back
- Wherever you show an entry, show where it comes from: the
urlfield of every item is the page to link. A short mention of Michael Ghelfi Studios is enough when a link is impossible (a chat message, a voice assistant). - No mirrors
- Do not republish the catalogues as standalone browsable pages that replace the encyclopedias (a copy of every metal, mineral or ingredient with its full text). Quoting entries inside your own content, tools and games is what the API is for; cloning the site is not.
- Music stays licensed
- The audio endpoints describe the catalogue: titles, composers, moods, pages, embeddable players. They never deliver audio files, and listing a track does not grant any right to the recording. Licences for the music itself are sold on the site.
- Be reasonable
- Cache responses (they carry Cache-Control), identify your project in the User-Agent header, and stay under the published rate limit. Abusive traffic gets blocked, not throttled.
- No warranty, no lock-in
- The data is offered as is and may change as the encyclopedias grow. Breaking changes will get a new version prefix; v1 stays up for at least a year after a v2 exists.
Attribution line: Data © Michael Ghelfi Studios — https://michaelghelfistudios.com
Versioning and contact
This is v1. Fields may be added at any time; nothing is removed or renamed without a new prefix. The index lists the current catalogue sizes. Questions, a project to show, a need for a higher limit: michaelghelfistudios.com.