OnlyWorlds

Read and write typed fictional worlds (22 linked element types) via the OnlyWorlds open standard.

Should I use this

Quality & Safety

A
Description quality
100%
Schema completeness
72%
Naming quality
96%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~2,551Tokens (tool definitions)
~650 BTypical response size
Moderate attention impact (1.99% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "mcp": {
      "url": "https://www.onlyworlds.com/mcp"
    }
  }
}

Remote endpoints

https://www.onlyworlds.com/mcpstreamable-http

What it can do

Tool inventory

Tools (11)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢list_element_types

List all 22 OnlyWorlds element types with a one-line shape summary of each. Every world is built from these types; each element has a stable UUID `id`, a `name`, and a `type`. Use `get_element_schema(type)` for a type's full field list. Unauthenticated — schema is public reference. Returns a mapping of the 22 type slugs (the value you pass as `type` to the data tools) to a summary string.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡get_element_schema(type)

Return the field structure of one OnlyWorlds element `type` (a slug from `list_element_types`, e.g. "character"). The result groups the type's writable fields by kind so a caller knows how to read and write them: `text` (strings), `integer`, `single_link` (one UUID), `multi_link` (an array of UUIDs), and `generic` (a type+id pair pointing at any element type). For every link field the target element type is given under `link_targets`. All link values are element UUIDs. Unauthenticated. Errors if `type` is not one of the 22 types.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    }
  },
  "required": [
    "type"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟢search_schema(query)

Search every element type's fields for `query` (case-insensitive substring), across all 22 types. Useful for "which types have a `location` field?" or finding where a concept lives in the schema. Returns a mapping of type slug -> the matching field names in that type (types with no match are omitted); a `query` that also matches a type slug lists that type with an empty field list so the type-name hit is not lost. Unauthenticated.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡list_elements(type, name_contains, supertype, limit, offset)

List elements of one `type` in the world named by your API-Key header, newest-created first. `type` is a slug from `list_element_types` (e.g. "character"). Optional `name_contains` filters by case-insensitive name substring; `supertype` filters exactly. `limit` (default 100, max 1000) and `offset` page the result. Requires a READ or WRITE API-Key. Returns `{data: [element, ...], limit, offset, has_more}` where each element is the full v2 wire shape and `id` is a UUID. Use `get_element(type, id)` for a single element.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "name_contains": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    },
    "supertype": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    },
    "limit": {
      "default": 100,
      "type": "integer"
    },
    "offset": {
      "default": 0,
      "type": "integer"
    }
  },
  "required": [
    "type"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡get_element(type, id)

Fetch one element by `type` and `id` (a UUID) from the world named by your API-Key header. `type` is a slug from `list_element_types`. Returns the full v2 wire shape (the same body as `GET /api/v2/{type}/{id}`): `type`, `id`, `name`, scalar fields, link fields as UUID arrays, and any extension fields inline. Requires a READ or WRITE API-Key. Errors if no element of that type with that id exists in the world.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "id": {
      "type": "string"
    }
  },
  "required": [
    "type",
    "id"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡search_elements(query)

Search elements by name across ALL 22 types in the world named by your API-Key header (case-insensitive substring match). Use this when you know part of a name but not the element's type. Bounded to at most 50 matches per type. Returns `{query, results: [{type, id, name, supertype, subtype}, ...]}` — `id` is a UUID; call `get_element(type, id)` for the full body. Requires a READ or WRITE API-Key.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡get_changes(since_cursor, limit)

Return the delta feed for the world named by your API-Key header: every element created/updated (`op: "upsert"`, full body) or deleted (`op: "delete"`) since `since_cursor`, in apply order, in pages of `limit` (default 25, max 1000). Entries carry FULL element bodies — a default page stays inside any client's token budget; measured worlds ran ~1.5-2k chars PER ENTRY, so raise `limit` only if you truly need bigger pages, and prefer paging with the cursor. Omit `since_cursor` (or pass "") to start from the beginning of the feed — for a big world that is a multi-page walk, not one response. Pass the returned `cursor` back as `since_cursor` to get the next page (or, later, only what changed since); treat the cursor as OPAQUE. `has_more` true means page again with the new cursor. Requires a READ or WRITE API-Key. This mirrors `GET /api/v2/changes`.

Input Schema

{
  "type": "object",
  "properties": {
    "since_cursor": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    },
    "limit": {
      "default": 25,
      "type": "integer"
    }
  },
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡create_element(type, element)

Create one new element of `type` in the world named by your API-Key header. `type` is a slug from `list_element_types` (e.g. "character"). `element` is the field payload: `name` plus any scalar, link, or extension fields for that type (call `get_element_schema(type)` for the field structure). Link fields are UUID arrays (multi) or a single UUID (single); every linked id must already exist in the world. Supply your own `id` (a UUID) to mint the element at that id, or omit `id` and the server mints a uuid7. Requires a WRITE API-Key. Returns the full created element in the v2 wire shape. Errors (naming the offending field) on an unknown field, a bad link target, or an id that already exists.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "element": {
      "additionalProperties": true,
      "type": "object"
    }
  },
  "required": [
    "type",
    "element"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🔴update_element(type, id, fields)

Update an existing element by `type` and `id`, changing ONLY the fields you pass — omitted fields are preserved. This is a server-side read-merge: the current element is loaded and only the keys in `fields` are applied, so it is safe against the raw-HTTP-PATCH hazard where sending a partial link array replaces the whole array. Semantics per field kind: a text field you pass is set (pass an empty string `""` to clear it); a multi-link field you pass REPLACES that field's array wholesale (pass an empty array `[]` to clear it) — for additive/subtractive link edits that leave the rest of the array intact, use `edit_links` instead. `type` is a slug from `list_element_types`; `id` is the element's UUID. Requires a WRITE API-Key. Returns the full updated element in the v2 wire shape. Errors if the element does not exist, or (naming the field) on an unknown field or a bad link target.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "fields": {
      "additionalProperties": true,
      "type": "object"
    }
  },
  "required": [
    "type",
    "id",
    "fields"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🔴edit_links(type, id, field, add, remove)

Add and/or remove links on ONE multi-link `field` of an element, leaving the rest of that field's array untouched. Use this for additive/subtractive link edits (unlike `update_element`, which REPLACES a link array). `type` is a slug from `list_element_types`; `id` is the element's UUID; `field` must be a multi-link field on that type (see `get_element_schema(type)`). `add` is a list of UUIDs to link (each must already exist in the world; adding an already-linked id is a no-op) and `remove` is a list of UUIDs to unlink (removing an absent id is tolerated). Requires a WRITE API-Key. Returns `{type, id, field, values}` where `values` is the field's full UUID array after the edit. Errors (naming `field`) if it is not a multi-link field of this type, if the element does not exist, or if an added target id is absent.

Input Schema

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "field": {
      "type": "string"
    },
    "add": {
      "anyOf": [
        {
          "items": {},
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    },
    "remove": {
      "anyOf": [
        {
          "items": {},
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    }
  },
  "required": [
    "type",
    "id",
    "field"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}
🟡bulk_apply(items, atomic)

Create and/or update many elements across any of the 22 types in one call. Each entry in `items` is `{"type": <slug>, "element": <payload>}` with the same payload shape `create_element` takes: an `element` with an `id` UPDATES that id (creating it if absent), an `element` without an `id` CREATES a new element. Items may reference each other by id, including a forward reference to a sibling later in the list. There is NO delete: bulk_apply never removes an element. When `atomic` is false (default), items succeed or fail independently and the response reports each outcome; when `atomic` is true, ANY item failure rolls the whole batch back and nothing is committed. Up to 1000 items. Requires a WRITE API-Key. Returns the batch response verbatim: `{errors, items: [{status, id, created_at, updated_at} | {status, id, error}, ...]}` — `errors` true means at least one item failed (and, under `atomic`, that nothing committed).

Input Schema

{
  "type": "object",
  "properties": {
    "items": {
      "items": {},
      "type": "array"
    },
    "atomic": {
      "default": false,
      "type": "boolean"
    }
  },
  "required": [
    "items"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "additionalProperties": true
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded11 tools
verifiedversion not recorded11 tools