Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions model-context-protocol/developer-portal.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,35 @@ https://developer.world.org/api/mcp

Developer portal API keys start with `api_`.

## Authentication errors

Every method, including `initialize`, requires the API key. Authentication failures return HTTP 200 with JSON-RPC error code `-32001`, not an HTTP 401. The message distinguishes missing or malformed credentials from a key that was parsed but rejected:

```json
{"jsonrpc": "2.0", "id": 1, "error": {"code": -32001, "message": "API key is required."}}
```

For a parsed but rejected key, the message is `API key is not valid.` Check that the client sends `Authorization: Bearer <API_KEY>` and copies the complete key from secure storage. Keys are shown only once; if yours is lost, generate a new key and update every client using the old one. The endpoint only accepts `POST`; `GET` returns HTTP 405 with `allow: POST, OPTIONS`.

## Connect your client

Replace `api_...` with the API key you copied from the Developer Portal.
Replace `api_...` with the API key you copied from the Developer Portal. Codex and Cursor read the key from the `WORLD_DEVELOPER_API_KEY` environment variable at startup, so set it persistently (for example, in your shell profile, loaded from a secrets manager) rather than with a one-off `export`. VS Code prompts for the key once and stores it securely.

<Tabs>
<Tab title="Claude Code">
```bash
claude mcp add world-developer-portal \
https://developer.world.org/api/mcp \
--transport http \
--scope project \
--scope local \
--header "Authorization: Bearer api_..."
```
</Tab>
<Tab title="Codex">
```bash
codex mcp add world-developer-portal \
--env WORLD_DEVELOPER_API_KEY=api_... \
-- npx -y mcp-remote https://developer.world.org/api/mcp \
--transport http-only \
--header 'Authorization:Bearer ${WORLD_DEVELOPER_API_KEY}'
--url https://developer.world.org/api/mcp \
--bearer-token-env-var WORLD_DEVELOPER_API_KEY
```
</Tab>
<Tab title="Cursor">
Expand All @@ -58,7 +66,7 @@ Replace `api_...` with the API key you copied from the Developer Portal.
"world-developer-portal": {
"url": "https://developer.world.org/api/mcp",
"headers": {
"Authorization": "Bearer api_..."
"Authorization": "Bearer ${env:WORLD_DEVELOPER_API_KEY}"
}
}
}
Expand All @@ -70,12 +78,20 @@ Replace `api_...` with the API key you copied from the Developer Portal.

```json
{
"inputs": [
{
"type": "promptString",
"id": "world-developer-api-key",
"description": "World Developer Portal API key",
"password": true
}
],
"servers": {
"world-developer-portal": {
"type": "http",
"url": "https://developer.world.org/api/mcp",
"headers": {
"Authorization": "Bearer api_..."
"Authorization": "Bearer ${input:world-developer-api-key}"
}
}
}
Expand Down Expand Up @@ -139,9 +155,18 @@ upload_app_image { app_id, image_type: "content_card", image_base64 | source_url
upload_app_image { app_id, image_type: "showcase_1", image_base64 | source_url }
```

## Timeouts and retries

A timeout or dropped connection doesn't tell you whether a call went through, and these tools don't replay the original result. Re-read state (`get_world_id_signing_key`, `get_world_id_registration_status`, `get_app_config`) before you retry:

- `configure_world_id` and `rotate_world_id_signing_key`: the private key is only in the original response. If that response is lost, the key is unrecoverable, but the portal still applies its signer address. Retrying `configure_world_id` returns the existing registration with `signing_key: null`. Retrying `rotate_world_id_signing_key` fails with `-32004` (`rotation_in_progress`) until the registration status is `registered` again. If `get_world_id_signing_key` shows a signer address you don't hold, wait until `get_world_id_registration_status` reports `registered`, then rotate again from a trusted channel (see [Security notes](#security-notes)).
- `submit_app_for_review`: if the first call went through, a retry fails with `-32004` `Only unverified apps can be submitted.` Check `get_app_config` for the review status instead.

## Security notes

- Store generated World ID private keys immediately. They are returned once and are not recoverable from the portal.
- `configure_world_id` and `rotate_world_id_signing_key` return the private key as a tool call result, not a one-time dialog — it passes through the assistant's model context and, depending on the client, may be persisted in session transcripts or debug logs. Treat it as sensitive. If it was generated through a client whose logs aren't under your team's control, don't just rotate again from that same client — the replacement key would leak through the identical path. Rotate from the Developer Portal dashboard instead: it generates the new key in your browser and sends only the signer address.
- Keep API keys out of files you commit. Claude Code's `--scope project` writes the header to `.mcp.json`, which is meant to be committed; the examples above use local scope, an environment variable, or an input prompt instead.
- Use a separate API key per local agent or project when possible.
- Delete or rotate API keys that are no longer needed.
- Confirm destructive actions before asking the assistant to rotate a signer key or submit an app for review.
2 changes: 1 addition & 1 deletion model-context-protocol/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ World provides two MCP servers:

## Client support

Both MCP servers use streamable HTTP. Most modern MCP clients can connect directly to an HTTP MCP server. Clients that only support stdio can connect through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).
Both MCP servers use streamable HTTP. Most modern MCP clients, including Codex CLI (`codex mcp add <name> --url <endpoint>`), can connect directly to an HTTP MCP server. Clients that only support stdio can connect through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).

<Note>
Keep developer portal API keys scoped to trusted local MCP clients. The Developer Portal MCP can mutate apps in your team.
Expand Down
6 changes: 4 additions & 2 deletions model-context-protocol/world-docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The docs MCP does not require authentication.
</Tab>
<Tab title="Codex">
```bash
codex mcp add world-docs -- npx -y mcp-remote https://docs.world.org/mcp --transport http-only
codex mcp add world-docs --url https://docs.world.org/mcp
```
</Tab>
<Tab title="Cursor">
Expand Down Expand Up @@ -65,6 +65,8 @@ The docs MCP does not require authentication.
| Tool | Purpose |
| --- | --- |
| `search_world_documentation` | Search and retrieve relevant World documentation for the current task. |
| `query_docs_filesystem_world_documentation` | Run shell-like queries (`rg`, `grep`, `find`, `tree`, `ls`, `cat`, `head`, `tail`, `stat`, `wc`, `sort`, `uniq`, `cut`, `sed`, `awk`, `jq`) over the full docs corpus, including OpenAPI specs, to read a full page or spec instead of a search snippet. |
| `submit_feedback` | Submit feedback about the documentation to the World docs team. |

## Suggested prompts

Expand All @@ -78,4 +80,4 @@ Search the World docs for World ID verification and explain which endpoint this

## When to use it

Use the docs MCP for read-only documentation lookup. To create or configure apps in the developer portal, use the [Developer Portal MCP](/model-context-protocol/developer-portal).
Use the docs MCP for documentation lookup and filesystem-style queries over the docs corpus (read-only except for `submit_feedback`). To create or configure apps in the developer portal, use the [Developer Portal MCP](/model-context-protocol/developer-portal).
Loading