registerTool adds an action the model can call to your server, optionally rendering its result through a view.
Example
search-products searches the store catalog for the signed-in user and renders the matches in the carousel view.
server.ts
Signature
Config
The first argument declares the tool.name, title, description
All three are the tool’s prompt surface: the model reads them to decide when to call it, so write each for the model. name is also the identifier the call uses, and title a short display name.
icons
The tool’s icons, a standard MCP field using the Icon type (src, mimeType, sizes, theme). Hosts choose whether and where to show them. ChatGPT asks for them on every tool with an entrypoint, as a monochrome SVG on a 20x20 viewport that draws with currentColor. Without them it falls back to the server’s icons for a local server, or to the logo registered with OpenAI for a hosted app.
inputSchema, outputSchema
Shapes of Standard Schema validators that can emit JSON Schema: Zod 4.2+ and ArkType out of the box, valibot through @valibot/to-json-schema. inputSchema validates the call arguments and types the handler’s input. Add .describe() to a field to tell the model what it’s for. outputSchema tells the model the shape to expect back, it does not type the returned value.
annotations
Standard MCP hints describing what the tool does, so the host can label it and order calls. They are hints: the host may surface or ignore them, and never gates a call on them.
view
Bind the tool to a React view to render its result instead of plain text. Each view backs exactly one tool.
csp
A view runs in a sandboxed iframe; your server’s domain is allowlisted automatically. Add external origins per directive:
openai
This is an OpenAI MCP extension, not part of MCP or MCP Apps. Only ChatGPT supports it, and other hosts ignore it.
view: Skybridge writes them to _meta["openai/ui"] on the tool and on its view resource, and throws at startup when the tool has no view.
file input. registerFileViewer is a shortcut for this:
Every field is optional, and Skybridge only emits what you set: ChatGPT applies the spec defaults for the rest. When both display-mode fields are omitted, the view supports both modes. When only
preferredDisplayMode is set, it becomes the only available mode, so pair it with availableDisplayModes to keep the other.
ChatGPT calls a tool with {} from a global or thread entrypoint, so Skybridge throws at startup when the tool’s input schema rejects {}. From a file entrypoint it passes { file: { name, resourceUri } }, which the view reads and saves with useFileResource. Skybridge also throws when a file extension doesn’t start with ..
ChatGPT opens global, thread and file entrypoints fullscreen. The display modes apply when the model calls the tool in a conversation.
settings, quickAction and preferredModelDisplayMode come from OpenAI’s reference package, not from the written spec, so their behavior in ChatGPT may change.auth
The recommended way to declare a tool’s auth. With the oauth field set, Skybridge enforces the declaration for you (anonymous or under-scoped calls are rejected before the handler runs).
Declaring any
{ allowsAnonymous: true } tool turns the server mixed: it serves anonymous callers, and every other tool stays sign-in-gated by default. Requiring sign-in ({ scopes }) needs the oauth provider and throws without it; { allowsAnonymous: true } works either way. Omit auth entirely for the secure default (sign-in required whenever the server has auth).
securitySchemes
The low-level form behind auth, for cases it can’t express (several alternative oauth2 schemes, or pure noauth that never accepts a token). Mutually exclusive with auth.
- Across the array, match any. Each entry is an alternative.
- Within an
oauth2entry’sscopes, match all. The token must carry every listed scope. noauthandoauth2together means “works anonymously, but auth unlocks more.”
_meta
Metadata on the tool. Skybridge recognizes the keys below; any other key you set is forwarded on the tool’s _meta untouched.
The
openai/* keys are read only on ChatGPT. openai/widgetAccessibleis deprecated, prefer ui.visibility instead.Handler
Runs when the tool is called. It receives the validatedinput (typed from inputSchema) and the request context extra:
extra
The request context.
Return
For a view tool, Skybridge adds a
viewUUID to _meta, a reserved key used for state persistence.Client hints
ChatGPT attaches conversation context toextra.mcpReq._meta. They are hints: tolerate their absence and never use them for authorization.
These hints are ChatGPT only.
Content helpers
skybridge/server exports helpers that build ContentBlocks for the handler’s content:
Returning plain
ContentBlock objects works too; the helpers are optional.
McpServer
The server you register tools on
useToolInfo
Read the tool’s result in the view
FileRef
Pass files in and out of a tool