Skip to content

CLI

The synapse CLI ships with @nimblebrain/synapse. Run it with npx synapse. It generates TypeScript types from your tool surface, previews an app locally, and checks a running server against what each host requires.

Generate TypeScript types from an app manifest, a running MCP server, or a directory of JSON schemas. The codegen subcommand is required, and you pass at least one source flag (--from-manifest, --from-server, or --from-schema).

Flag Argument Description
--from-manifest <path> Generate types from an app manifest JSON file
--from-server <url> Generate types from a running MCP server’s tool list
--from-schema <dir> Generate CRUD tool types from a directory of .schema.json files
--out <path> Write the generated TypeScript to this file
--app <name> Scope generation to a single app by name
Terminal window
# From an app manifest
npx synapse codegen --from-manifest ./manifest.json --out src/generated/types.ts
# From a running MCP server
npx synapse codegen --from-server http://localhost:3000 --out src/generated/types.ts
# From a directory of .schema.json files (generates CRUD tool types)
npx synapse codegen --from-schema ./schemas --out src/generated/types.ts

Serve the app in a local host shell so you can exercise the ext-apps handshake, theming, and tool calls without deploying to a host.

Terminal window
npx synapse preview

Connect to a running MCP server over Streamable HTTP and check what a host sees of it: the UI resources and their metadata, the MCP Apps extension declaration, and the OAuth discovery surface a host signs in through.

Terminal window
npx synapse check --target claude,chatgpt https://example.com/mcp
# A server that requires auth: pass a bearer token to run the checks that need a session
SYNAPSE_CHECK_TOKEN=... npx synapse check --target chatgpt https://example.com/mcp
Flag Argument Description
--target <list> Comma-separated profiles: nimblebrain, claude, chatgpt
--token <token> Bearer token for a server that requires auth. Defaults to $SYNAPSE_CHECK_TOKEN
--json Print the report as JSON

Every check runs once. Each target’s profile decides which checks count for it, and whether a failure is an error (the command exits non-zero) or a warning (reported; a requirement the host documents but is not known to enforce). A server that cannot be reached, or rejects the given token, exits non-zero without a report.

Check What it verifies nimblebrain claude chatgpt
extension-declared The server declares io.modelcontextprotocol/ui in capabilities.extensions warn error error
ui-resource-mime Every ui:// resource is listed and served as text/html;profile=mcp-app error error error
tool-resource-uri Some tool binds a UI through _meta.ui.resourceUri, and every binding reads error error error
tool-ui-meta ui.visibility is a non-empty subset of model/app; no csp or permissions on a tool error error error
resource-csp Every UI resource declares ui.csp as lists of origins — warn warn
resource-openai-csp Every UI resource declares openai/widgetCSP, with ChatGPT’s connect_domains/resource_domains spelling — — warn
resource-data-fonts No data: font in the HTML unless ui.csp.resourceDomains includes data: — error —
resource-openai-data-fonts No data: font in the HTML unless openai/widgetCSP.resource_domains includes data: — — warn
auth-challenge An unauthenticated request’s 401 carries resource_metadata in WWW-Authenticate warn error error
auth-resource-metadata The protected-resource metadata’s resource equals the server URL exactly warn error error
auth-issuer The first authorization server’s metadata issuer equals the advertised string exactly warn warn error
tool-security-schemes Every tool declares securitySchemes when the server requires auth — — error

The frame’s security policy is checked once per dialect. Claude and the NimbleBrain host read the spec’s nested ui.csp. OpenAI documents ui.csp as generally preferred for new UI and the sibling openai/widgetCSP as a legacy compatibility key, still the only way to declare redirect_domains. Neither has been observed to change what ChatGPT enforces: measured 2026-09-18 in developer mode, a frame whose resource carried both ran under ChatGPT’s own default sandbox policy. So both checks warn for chatgpt rather than fail. A server should declare both.

The auth checks run only when the server answers an unauthenticated request with 401. When it does and no token is given, the checks that need a session are skipped rather than failed. The URL is compared exactly, so pass the connector URL a host is given, including or omitting a trailing slash as it does.

  • Package exports for the @nimblebrain/synapse/codegen programmatic entry point.