# OnlyWorlds (remote · www.onlyworlds.com)

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

- Trust score: 62/100 (medium)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `www.onlyworlds.com`: 62/100 (this document), [markdown](https://verifymcp.io/servers/com-onlyworlds-mcp/www.md), [page](https://verifymcp.io/servers/com-onlyworlds-mcp/www)

## Channel facts

- Endpoint: `https://www.onlyworlds.com/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 57/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 11 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 66/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 2017 tokens (~183/item across 11 items; 11 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http com-onlyworlds-mcp https://www.onlyworlds.com/mcp
```

### Codex

```toml
[mcp_servers.com-onlyworlds-mcp]
url = "https://www.onlyworlds.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com-onlyworlds-mcp": {
      "type": "remote",
      "url": "https://www.onlyworlds.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com-onlyworlds-mcp --url https://www.onlyworlds.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  com-onlyworlds-mcp:
    url: "https://www.onlyworlds.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "com-onlyworlds-mcp": {
      "type": "http",
      "url": "https://www.onlyworlds.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 62, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 61, +2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 59, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-28 (score 58, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 57, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 56)

First indexed and scored.

## MCP tools (11)

### `list_element_types` (~109 tokens)

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.

### `get_element_schema` (~154 tokens)

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 parameters:

- `type` (string, required)

### `search_schema` (~115 tokens)

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 parameters:

- `query` (string, required)

### `list_elements` (~180 tokens)

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 parameters:

- `limit` (integer)
- `name_contains`
- `offset` (integer)
- `supertype`
- `type` (string, required)

### `get_element` (~134 tokens)

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 parameters:

- `id` (string, required)
- `type` (string, required)

### `search_elements` (~120 tokens)

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 parameters:

- `query` (string, required)

### `get_changes` (~244 tokens)

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 parameters:

- `limit` (integer)
- `since_cursor`

### `create_element` (~201 tokens)

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 parameters:

- `element` (object, required)
- `type` (string, required)

### `update_element` (~248 tokens)

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 parameters:

- `fields` (object, required)
- `id` (string, required)
- `type` (string, required)

### `edit_links` (~258 tokens)

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 parameters:

- `add`
- `field` (string, required)
- `id` (string, required)
- `remove`
- `type` (string, required)

### `bulk_apply` (~254 tokens)

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 parameters:

- `atomic` (boolean)
- `items` (array, required)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/com-onlyworlds-mcp/www#diagnostics

## Score history

- 2026-08-03: 62
- 2026-08-02: 62
- 2026-08-01: 61
- 2026-07-31: 61
- 2026-07-30: 59
- 2026-07-29: 58
- 2026-07-28: 58
- 2026-07-27: 57
- 2026-07-26: 56

## Links

- Remote endpoint: https://www.onlyworlds.com/mcp
- Authorisation metadata: https://www.onlyworlds.com/.well-known/oauth-protected-resource/mcp
- Website: https://www.onlyworlds.com/
- Changelog RSS feed: https://verifymcp.io/servers/com-onlyworlds-mcp/www/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/com-onlyworlds-mcp/www/changelog.json
- HTML version of this page: https://verifymcp.io/servers/com-onlyworlds-mcp/www
