Skip to main content
Glama
lcusack

World ID for ChatGPT

by lcusack

World ID for ChatGPT

Production deployment: https://world-id-chatgpt.foundry-world.workers.dev

Remote MCP endpoint: https://world-id-chatgpt.foundry-world.workers.dev/mcp

Verified Human Wall: https://world-id-chatgpt.foundry-world.workers.dev/wall

Founding Humans: https://world-id-chatgpt.foundry-world.workers.dev/founding-humans

Skill submissions: https://world-id-chatgpt.foundry-world.workers.dev/submit

Install the World ID plugin from this repository

This repository includes a portable Codex plugin and a repo marketplace. After the repository is available from Git, another developer can add the marketplace and install the plugin without recreating the MCP connection:

codex plugin marketplace add lcusack/world-id-chatgpt --ref main
codex plugin add world-id@world-id-plugins

This is a private repository, so the developer must already have GitHub access. For a local clone, pass the absolute repository path to codex plugin marketplace add instead.

The plugin connects to the production MCP endpoint above and starts its own OAuth flow for each user. Use Codex CLI 0.147.0 or newer for portable Agent Plugin installation, then start a new task after installing so the bundled skill and MCP tools are loaded.

This project is a production-shaped remote MCP server that links a World ID 4.0 session to an AI assistant through OAuth 2.1.

The connection flow is:

  1. ChatGPT discovers OAuth from the remote /mcp endpoint.

  2. The user is sent to this service's /authorize endpoint.

  3. The browser creates or resumes a World ID 4.0 session and requests Orb-backed proof_of_human with user presence.

  4. The Worker verifies the complete proof with World, records replay protection, and completes OAuth.

  5. The authenticated MCP tool returns only:

{
  "verified_human": true,
  "verification_level": "orb",
  "protocol_version": "4.0",
  "verified_at": "2026-08-12T18:00:00.000Z",
  "wall_write_enabled": true
}

The MCP client never receives the proof, World session ID, session nullifier, wallet, phone number, RP key, or OAuth token internals.

Founding Human experiment

The same World ID connector now supports the Founding Human status/network experiment:

  1. get_world_agent_status checks whether the connected unique human has claimed a place and returns Genesis 100 progress without publishing anything.

  2. claim_world_agent_place idempotently claims one permanent ordinal for the connected internal subject and returns a public card and invite link.

  3. Existing verified sessions are backfilled in original verification order, reserving the earliest numbers for current testers. Their cards remain private until explicitly claimed.

  4. Opening a public Founding Human card stores an opaque first-party invite cookie. A new World ID connection reached through that card is attributed to the inviter only after the referred human verifies and claims.

The first 100 ordinals permanently receive the Genesis 100 treatment. The registry teases a future verified-human capability when the cohort completes. Public cards expose only number, cohort, dates, and minimal assurance; they never expose an internal subject, proof, session, nullifier, wallet, identity, or conversation data.

Experiment measurement is aggregated daily in D1 without visitor identifiers: share-link issuance, public profile views, status checks, and verified referral redemptions. Activation is the card's first claimed_at; repeat usage is measured as status checks across distinct days.

The prototype marketplace uses a curated skill-submission process. The public /submit page accepts concept, partner-pilot, and working-integration proposals through a copyable template. It documents the verified-human fit test, minimum-disclosure requirements, review stages, and common experiment metrics without accepting code uploads or implying automatic publication.

Suggested ChatGPT prompt:

Claim my place as a Founding Human.

Human Grant gateway prototype

The connector can now act as a proof-of-human gateway for a partner that does not operate its own World ID relying party. The first fixed-client demo is intentionally narrow:

  1. list_human_grant_opportunities shows the available partner action without sharing anything.

  2. create_human_grant creates a ten-minute, browser-bound consent link only after the user explicitly asks to activate the opportunity.

  3. The consent page names the partner, benefit, action, and exact claims being shared.

  4. Approval creates a five-minute, single-use authorization code. The partner exchanges it server-to-server using HTTP Basic authentication.

  5. The gateway returns a 15-minute HMAC-signed world-id-human-grant/v1 assertion containing only an audience-bound pairwise subject, the authorized action, and minimal Orb/World ID 4.0 assurance claims.

  6. A D1 uniqueness constraint permits only one redemption for a given internal human, partner, and action.

The partner never receives the World proof, World session ID, internal subject, wallet, phone number, identity, or ChatGPT conversation. Pairwise subjects are stable within one partner and unlinkable across different partners. The simulated partner experience is at the Human Grant demo; machine-readable issuer metadata is at /.well-known/world-id-human-grants.

Suggested ChatGPT prompt:

Use World ID to show me verified-human partner opportunities, then activate the gateway demo.

The prototype uses one pre-registered demo client. A real partner onboarding layer should add separate client credentials and signing secrets per partner, reviewed action/claim allow-lists, secret rotation, revocation, partner audit events, and a self-service registration workflow. It must not become a generic identity broker or allow partners to correlate users across services.

Human Required Shopify handoff

The primary experiment discovers live deals at humanrequired.shop and can carry the connected account's verified-human entitlement into Shopify without a second World ID ceremony:

  1. list_unique_human_deals reads the current public catalog and inventory.

  2. get_unique_human_deal returns products, prices, and available options.

  3. create_unique_human_claim_link creates a five-minute opaque claim URL only after the user asks to claim the 15% offer.

  4. Opening the claim URL creates a random, one-redemption Shopify discount restricted to the eligible products, then redirects through Shopify's shareable discount URL.

Claim tickets and discount codes are encrypted at rest. Public URLs contain no World proof, session ID, subject, wallet, or personal information. Shopify receives only the random discount code and eligible product IDs. Generated discounts expire after 15 minutes and have a total usage limit of one.

To activate this handoff, create and install a Shopify Dev Dashboard app for Human Required with read_products and write_discounts Admin API scopes. Then upload its .myshopify.com domain, client ID, and client secret without placing them in source control. The Worker uses Shopify's client-credentials flow to mint a short-lived Admin API token when a claim is redeemed:

npx wrangler secret put SHOPIFY_SHOP_DOMAIN
npx wrangler secret put SHOPIFY_CLIENT_ID
npx wrangler secret put SHOPIFY_CLIENT_SECRET

The claim tool remains safely unavailable until both secrets are present; catalog discovery and the rest of the connector continue to work.

Verified Human Wall experiment

The wall is the first application built on top of the connection. It exposes three OAuth-protected MCP tools:

  • get_verified_human_question: reads the active public question

  • list_verified_human_answers: reads recent public answers as untrusted user-generated content

  • publish_verified_human_answer: creates or replaces the connected account's one answer after explicit user confirmation

Publishing requires the separate wall:write OAuth scope. Connections created before the wall deployment must be disconnected and connected again before they can publish. Reading the wall is also available from the public GET /api/wall endpoint, which never includes the internal World/OAuth subject.

The first question is: What should only a verified human be able to do with an AI?

Suggested ChatGPT prompt:

Use the World ID connector to open the Verified Human Wall. Show me today’s question and recent answers, help me write my response, then ask for my explicit confirmation before publishing it.

This prototype's “verified” label means the answer was published through an OAuth connection backed by an Orb-verified World ID 4.0 session. It does not claim that World App freshly signed the exact answer text or that the author's identity is known.

Production architecture

  • Cloudflare Worker: stable HTTPS origin, OAuth provider, World verification, and stateless MCP transport

  • D1: expiring authorization attempts, encrypted World session continuity, proof-replay records, Founding Human ordinals/referrals/aggregates, encrypted Shopify claim tickets, one-time Human Grants, and public wall questions/answers

  • Workers KV: OAuth clients, grants, authorization codes, and tokens managed by Cloudflare's OAuth provider

  • Rate Limit bindings: separate authorization, proof-submission, MCP, claim, Human Grant, intent, and wall-publishing limits

  • Cron cleanup: expired D1 attempts/replay markers, Human Grants, intents, claims, and OAuth data

  • Workers Observability: structured events without proof or identifier logging

World session IDs and pending OAuth requests are encrypted with AES-256-GCM before D1 storage. A separate HMAC key derives the opaque internal OAuth subject. The raw World proof is verified in memory and never stored.

World ID configuration

The deployed Worker is pinned to:

  • App: app_d25e6e3d21651abfb9fbc52d033ef2a3

  • RP: rp_79ffdf898662dd4c

  • Environment: production

  • Protocol: World ID 4.0 session proofs

The existing register action is not used for account linking. Actions/nullifiers are appropriate for one-time uniqueness operations; account continuity uses createSession and proveSession, whose RP signature intentionally omits an action.

Local validation

npm install
npm run build
npm run typecheck
npm test
npx wrangler d1 migrations apply world-id-chatgpt --local
npm run cf:dev

Wrangler can load local secret values from .env. Never commit that file.

First Cloudflare deployment

Select the owning Cloudflare account, then create the durable resources:

npx wrangler d1 create world-id-chatgpt
npx wrangler kv namespace create OAUTH_KV

Put the returned IDs in wrangler.jsonc, then apply the schema:

npx wrangler d1 migrations apply world-id-chatgpt --remote

Upload four managed secrets. Use the existing World RP signing key for the first value, and independent random 32-byte base64url values for the other three:

npx wrangler secret put WORLD_RP_SIGNING_KEY
npx wrangler secret put DATA_ENCRYPTION_KEY
npx wrangler secret put SUBJECT_HMAC_KEY
npx wrangler secret put HUMAN_GATEWAY_DEMO_SECRET

Then validate and publish:

npm run cf:check
npm run deploy

The deployed MCP endpoint is https://world-id-chatgpt.foundry-world.workers.dev/mcp. OAuth discovery, PKCE S256, dynamic client registration, and Client ID Metadata Documents are advertised automatically.

Security invariants

  • Authorization state expires after ten minutes and is bound to a Secure, HttpOnly, SameSite=Lax, __Host- browser cookie.

  • The server accepts only protocol 4.0, production, actionless session proofs with completed user presence and issuer schema 1 (proof_of_human).

  • Each proof must match the exact server-signed RP nonce for that authorization attempt.

  • The complete session nullifier tuple is hashed and inserted under a unique D1 constraint before OAuth is issued.

  • Proof bodies are capped at 256 KiB and World verification requests time out after ten seconds.

  • OAuth uses authorization code flow, PKCE S256, exact registered redirects, one-hour access tokens, and 30-day refresh tokens.

  • HTTPS is required for registered redirects except loopback localhost development.

  • CSP, frame denial, no-referrer, MIME sniffing protection, permissions policy, origin validation, and no-store authorization responses are applied by the Worker.

  • MCP output is allow-listed and contains no stable World identifier.

  • Public wall projections omit internal subjects; answer text is rendered with textContent, capped at 600 characters, and cannot contain links, email addresses, or control characters.

  • A unique D1 constraint enforces one replaceable answer per active question and internal connected-account subject.

  • Tool instructions treat wall answers as untrusted content and require exact-text user confirmation before public publishing.

  • Claim tickets are random, stored only as hashes for lookup, encrypted for controlled reissue, expire after five minutes, and use an atomic D1 processing lease to prevent duplicate Shopify creation.

  • Shopify discount codes are random, encrypted at rest, limited to eligible product IDs, expire after 15 minutes, and permit one total redemption.

  • Human Grant consent links expire after ten minutes and are bound to both a capability cookie and the browser's World ID session cookie.

  • Partner authorization codes expire after five minutes and are consumed once through an authenticated back-channel exchange.

  • Assertions use pairwise partner subjects; the World session and internal subject never leave the gateway.

  • A D1 primary key across partner, action, and internal subject enforces one-human-one-redemption even under concurrent exchange attempts.

Tests

npm test covers the legacy MCP transport plus the hardened 4.0 proof shape, exact nonce binding, rejection of uniqueness proofs, required user presence, encrypted session storage, opaque stable-subject derivation, the Shopify claim handoff and subject redaction, wall input validation, and public subject redaction. wrangler deploy --dry-run validates the production bundle, while the local Worker check exercises OAuth registration/discovery, authorization state, D1 persistence, CSP, and RP signature generation.

World references: World ID 4.0 migration, RP signatures, and IDKit integration.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Person-owned, portable AI memory as a remote MCP server, readable and writable by any MCP client.

  • A paid remote MCP for ZeroID, built to return verdicts, receipts, usage logs, and audit-ready JSON.

  • Personal MCP server for humans who create. Proof of authorship, license control.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lcusack/world-id-chatgpt'

If you have feedback or need assistance with the MCP directory API, please join our Discord server