AGENTS.md

Project summary

This val is a public DCR/CIMD interoperability demo. Its HTTP entrypoint is main.tsx, deployed at https://oauth-demos.val.run/. It supports OAuth authorization, authenticated MCP tool discovery, and an OpenAI-powered chat over each provider’s full advertised MCP toolset.

There is no local build system or package manifest. Val Town runs the files directly with Deno-compatible URL imports.

File map

  • main.tsx: all routes, HTML/CSS/JS, OAuth state, token exchange, MCP calls, and model tool calling.
  • directory-data.ts: the researched catalog (curatedEntries). Preserve evidence URLs and distinguish researched capability from runtime support. Exports directoryEntries = [...curatedEntries, ...registryScanEntries].
  • featured-apps.ts: alphabetical list of well-known apps (by MCP hostname) shown on the home page's featured table. Everything runnable not listed here appears in the full A–Z list at /apps. Display names for scan-discovered hosts are baked into registry-scan-data.ts by the generator.
  • registry-scan-data.ts: GENERATED. One entry per hostname from probing every remote URL in the official MCP registry for registration_endpoint (DCR) and client_id_metadata_document_supported (CIMD). Do not hand-edit; regenerate with https://www.val.town/x/stevekrouse/mcp-registry-oauth-scan and re-upload. Hosts already in curatedEntries are excluded by the generator.
  • code-tour.tsx: guided code tour (Shiki server-side highlighting, per-line explanations, act-grouped nav, keyboard navigation). Simplified excerpts, not executable copies of main.tsx.
  • research/probe.ts and research/test-registration.ts: diagnostic scripts. Do not import them into production.
  • README.md: public project overview.

UI invariants

  • Render only entries that produce at least one real Connect button.
  • Home (/) shows only the featured table: the apps in featured-apps.ts (featuredHosts, an alphabetical array of MCP hostnames), in that order. The full A–Z list of every runnable entry lives at /apps. To promote an app, add its MCP host to featuredHosts.
  • Keep the canonical Cloudflare whole-API entry (mcp.cloudflare.com) in the featured list; the many product-scoped *.mcp.cloudflare.com subdomains belong only in the /apps full list.
  • Table columns are App, DCR, CIMD, in that order.
  • Company marks use the company-site favicon and appear left of the name.
  • Keep the page and chat light. Dark backgrounds are reserved for syntax-highlighted code on the code-tour page.
  • The table is derived at render time. Do not manually duplicate the service list in HTML.
  • Chat tool calls render as collapsed <details> panels with arguments and raw responses. Keep trace text escaped via DOM textContent.

OAuth architecture

providers contains hand-configured integrations. resolveProvider discovers the others from the metadata URLs stored in directory-data.ts.

Routes:

  • GET /oauth/:provider/:mode/start: creates PKCE state, optionally performs DCR, then redirects to authorization.
  • GET /oauth/client-metadata.json: stable CIMD document.
  • GET /oauth/callback: exchanges the code, verifies useful access, encrypts the token, and saves the connection.
  • POST /chat: exposes each connected MCP tool to the model and executes selected calls.
  • GET /code-tour: teaching UI.

Val Town uses its official MCP endpoint at https://api.val.town/v3/mcp, exactly like the other providers. Do not reintroduce a hand-written REST adapter. Val Town OAuth scope names use underscores, and its project scope is project_rw.

Data and security

Project-scoped SQLite tables:

  • mcp_flows: short-lived OAuth state and PKCE verifier.
  • mcp_connections: encrypted access token plus discovered tool summary, keyed by browser session and provider.

The AES-GCM key is persisted in project-scoped blob storage under mcp-token-encryption-key:v1. Never log tokens, client secrets, authorization codes, or decrypted tool results.

Important: POST /chat sends user prompts and connector tool results to OpenAI. Expanding OAuth scopes expands the data that may be sent there. Require explicit user approval before broadening scopes or adding a new data source.

Editing and verification

Prefer targeted replacements for small changes and a whole-file update only for coordinated refactors. After changing main.tsx, fetch its HTTP endpoint in the same edit call. Confirm HTTP 200, inspect the rendered table order and columns, and check logs if deployment fails.

OAuth buttons cannot be fully verified non-interactively. Preserve PKCE, state, resource for MCP, token encryption, the secure session cookie, and the one-hour cleanup for abandoned flows.