### Install Dependencies and Start Local Development
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/README.md
Run these commands to install project dependencies and start a local development server for previewing the documentation.
```bash
pnpm install
pnpm dev
```
--------------------------------
### Start Dev Server
Source: https://github.com/alpic-ai/skybridge/blob/main/skills/chatgpt-app-builder/references/run-locally.md
Installs dependencies and starts the development server in the background. Use 'deno task dev' for Deno projects. Hot reload is enabled for both server and widgets.
```bash
{pm} install && {pm} run dev
```
--------------------------------
### Start Production Server
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/build-for-production.mdx
Once your app is built, start the production server to serve your compiled application. This command runs `skybridge start` and prepares your app for live use.
```bash
npm start
```
```bash
pnpm start
```
```bash
yarn start
```
```bash
bun start
```
```bash
deno task start
```
--------------------------------
### Create Skybridge Project with Overwrite and Immediate Start
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/cli.mdx
Creates a new Skybridge project in the current directory (`.`), overwrites existing files without prompting, and automatically installs dependencies and starts the development server.
```bash
npm create skybridge@latest . --overwrite --immediate
```
--------------------------------
### Install Dependencies
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-auth0/README.md
Install project dependencies using npm, pnpm, or bun.
```bash
npm install
# or
pnpm install
# or
bun install
```
--------------------------------
### Full MCP Server Example with Widgets
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/mcp-server.mdx
A comprehensive example demonstrating the initialization of an `McpServer`, registration of widgets with input and output schemas, and type export for client-side inference. Ensure method chaining is used for type safety.
```typescript
import { McpServer } from "skybridge/server";
import { z } from "zod";
const server = new McpServer(
{ name: "hotel-booking", version: "1.0.0" },
{}
)
.registerWidget("search-hotels", {
description: "Search for hotels",
}, {
inputSchema: {
city: z.string().describe("City to search"),
checkIn: z.string().describe("Check-in date"),
checkOut: z.string().describe("Check-out date"),
guests: z.number().optional().default(2),
},
outputSchema: {
hotels: z.array(z.object({
id: z.string(),
name: z.string(),
price: z.number(),
rating: z.number(),
})),
},
}, async ({ city, checkIn, checkOut, guests }) => {
const hotels = await searchHotels({ city, checkIn, checkOut, guests });
return {
content: [{ type: "text", text: `Found ${hotels.length} hotels in ${city}` }],
structuredContent: { hotels },
};
})
.registerWidget("hotel-details", {
description: "Get hotel details",
}, {
inputSchema: {
hotelId: z.string(),
},
}, async ({ hotelId }) => {
const hotel = await getHotel(hotelId);
return {
content: [{ type: "text", text: `Showing details for ${hotel.name}` }],
structuredContent: hotel,
};
});
export type AppType = typeof server;
export default server;
```
--------------------------------
### Start Local Server
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-auth0/README.md
Start the local development server using npm, pnpm, or bun. This command launches the MCP server and the Skybridge DevTools UI.
```bash
npm run dev
# or
pnpm dev
# or
bun dev
```
--------------------------------
### Start Local Development Server
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-clerk/README.md
Run the development server to start your MCP server and Skybridge DevTools.
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
--------------------------------
### Install Dependencies with npm/yarn/pnpm/bun
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/ecom-carousel/README.md
Installs project dependencies. Choose the command corresponding to your package manager.
```bash
npm install
```
```bash
yarn install
```
```bash
pnpm install
```
```bash
bun install
```
--------------------------------
### Combined Example: Todo List with State Management
Source: https://github.com/alpic-ai/skybridge/blob/main/skills/chatgpt-app-builder/references/state-and-context.md
This example demonstrates combining `useWidgetState` for persistent task data, `useState` for ephemeral UI focus, and `data-llm` for LLM context, illustrating how different state management approaches serve distinct purposes.
```tsx
function TaskList() {
// PERSIST: All tasks with completed status
const [{ tasks }, setState] = useWidgetState({
tasks: [
{ id: 1, title: "Buy groceries", completed: false },
{ id: 2, title: "Call mom", completed: true },
]
});
// EPHEMERAL: Task user is viewing — reset on reopen
const [viewing, setViewing] = useState(null);
return (
// CONTEXT: What user is looking at — LLM answers "how should I handle this task?"
);
}
```
--------------------------------
### Install Dependencies with Bun
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Installs project dependencies using Bun. Ensure Node.js 24+ is installed.
```bash
bun install
```
--------------------------------
### Start Local Development Server with Bun
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Starts the local development server using Bun. This command launches the MCP server and Skybridge DevTools UI.
```bash
bun dev
```
--------------------------------
### Fullscreen Media Player Example
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-display-mode.mdx
An example of using the useDisplayMode hook to implement a media player that can toggle between inline and fullscreen modes.
```tsx
import { useDisplayMode } from "skybridge/web";
function MediaPlayer() {
const [displayMode, setDisplayMode] = useDisplayMode();
const isFullscreen = displayMode === "fullscreen";
return (
);
}
```
--------------------------------
### Install Dependencies with npm
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Installs project dependencies using npm. Ensure Node.js 24+ is installed.
```bash
npm install
```
--------------------------------
### Install Dependencies
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-clerk/README.md
Install project dependencies using your preferred package manager.
```bash
npm install
# or
yarn install
# or
pnpm install
# or
bun install
```
--------------------------------
### One-Time Setup for generateHelpers
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/generate-helpers.mdx
This code snippet demonstrates the one-time setup required in your web project to create typed hooks using `generateHelpers`. It imports the server type and then exports the typed `useCallTool` and `useToolInfo` hooks.
```ts
// web/src/helpers.ts
import type { AppType } from "../server"; // type-only import
import { generateHelpers } from "skybridge/web";
export const { useCallTool, useToolInfo } = generateHelpers();
```
--------------------------------
### Install Dependencies with Yarn
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Installs project dependencies using Yarn. Ensure Node.js 24+ is installed.
```bash
yarn install
```
--------------------------------
### Start Local Development Server
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/ecom-carousel/README.md
Starts the development server for both the MCP server and Skybridge DevTools. Use the command for your preferred package manager.
```bash
npm run dev
```
```bash
yarn dev
```
```bash
pnpm dev
```
```bash
bun dev
```
--------------------------------
### Install Manifest UI Component
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/manifest-ui/README.md
Installs a specific Manifest UI component, such as 'post-card', into the '/web' directory using npx. This command is run from the '/web' folder.
```bash
cd web
npx shadcn@latest add @manifest/post-card
```
--------------------------------
### Clone and Install Dependencies
Source: https://github.com/alpic-ai/skybridge/blob/main/CONTRIBUTING.md
Clone the Skybridge repository and install project dependencies using pnpm.
```bash
git clone https://github.com/alpic-ai/skybridge.git
cd skybridge
pnpm install
```
--------------------------------
### Start Skybridge Production Server
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/cli.mdx
Starts the production server using the compiled output from `skybridge build`. It sets `NODE_ENV=production` and serves the MCP endpoint at `http://localhost:3000/mcp` along with pre-built widget assets.
```bash
skybridge start
```
--------------------------------
### Loading State Example
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-tool-info.mdx
Illustrates how to display a loading indicator while the tool is executing, using the `isPending` flag.
```APIDOC
## Loading State Example
This example shows how to conditionally render a loading state using the `isPending` flag from `useToolInfo`.
```tsx
import { useToolInfo } from "skybridge/web";
function DataWidget() {
const { input, isPending, isSuccess, output } = useToolInfo<{
input: { query: string };
output: { results: string[] };
}>();
return (
Search: {input.query}
{isPending && (
Searching...
)}
{isSuccess && (
{output.results.map((result, i) => (
{result}
))}
)}
);
}
```
```
--------------------------------
### useToolInfo
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference.mdx
Get initial tool input, output and metadata.
```APIDOC
## useToolInfo
### Description
Get initial tool input, output and metadata.
### Method
N/A (Hook)
### Parameters
N/A
### Request Example
N/A
### Response
N/A
```
--------------------------------
### Start Local Development Server with pnpm
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Starts the local development server using pnpm. This command launches the MCP server and Skybridge DevTools UI.
```bash
pnpm dev
```
--------------------------------
### Install Skybridge Dependencies
Source: https://github.com/alpic-ai/skybridge/blob/main/CLAUDE.md
Run this command to set up the project dependencies using pnpm.
```bash
pnpm install
```
--------------------------------
### Start the Skybridge development server
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/create-new-app.mdx
Run this command from your project's root directory to start the development server. It includes an MCP server, a React frontend with HMR, and hot-reloading for server code.
```bash
npm run dev
```
```bash
pnpm dev
```
```bash
yarn dev
```
```bash
bun dev
```
```bash
deno task dev
```
--------------------------------
### Start Local Development Server with Yarn
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/generative-ui/README.md
Starts the local development server using Yarn. This command launches the MCP server and Skybridge DevTools UI.
```bash
yarn dev
```
--------------------------------
### Start Skybridge Development Server
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/cli.mdx
Starts the development server with hot module reloading and DevTools. The server runs on `http://localhost:3000/`, exposes the MCP server at `http://localhost:3000/mcp`, and enables file watching with automatic restarts.
```bash
skybridge dev
```
--------------------------------
### Configure Stripe Environment Variables
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/ecom-carousel/README.md
Copies the example environment file and prompts to add your Stripe test secret key.
```bash
cp .env.example .env
```
--------------------------------
### Logging Requests
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/mcp-server.mdx
This example shows how to use `mcpMiddleware` to log details of incoming requests, such as the HTTP method and parameters.
```APIDOC
## Logging Requests
### Description
Use `mcpMiddleware` to intercept and log request details.
### Method
`server.mcpMiddleware("request", (request, extra, next) => { ... });`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```typescript
server.mcpMiddleware("request", (request, extra, next) => {
console.log(`[MCP] ${request.method}`, request.params);
return next();
});
```
### Response
None directly from middleware, but `next()` is called to continue processing.
```
--------------------------------
### Set up Web Project with Vite
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/add-to-existing-app/server.mdx
Initialize a web project, add necessary dependencies, and configure Vite for skybridge.
```bash
mkdir web && cd web
pnpm init
pnpm add react react-dom skybridge
pnpm add -D vite typescript @types/react @types/react-dom
```
```typescript
import { defineConfig } from "vite";
import { skybridge } from "skybridge/web";
export default defineConfig({
plugins: [skybridge()],
});
```
--------------------------------
### Reading Theme Context
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-mcp-app-context.mdx
This example shows how to use `useMcpAppContext` to get the current theme and apply it to the component's styling. It conditionally sets background and text colors based on the theme.
```tsx
import { useMcpAppContext } from "skybridge/web";
function ThemedWidget() {
const theme = useMcpAppContext("theme");
return (
Current theme: {theme}
);
}
```
--------------------------------
### MCP Server with Method Chaining
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/generate-helpers.mdx
An example of an MCP server definition using method chaining, which is a prerequisite for `generateHelpers` to perform type inference. This setup allows `registerWidget` and `registerTool` calls to be chained.
```ts
// ✅ Works — chain registerWidget/registerTool calls
const server = new McpServer({ name: "my-app", version: "1.0" }, {})
.registerWidget("search-voyage", {}, { inputSchema: { destination: z.string() } }, async ({ destination }) => {
return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
});
export type AppType = typeof server;
```
--------------------------------
### Adapt Widget Theme with useLayout
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/guides/host-environment-context.mdx
Use the `useLayout` hook to get the host's theme and apply corresponding styles. This example shows direct style manipulation for background and text colors.
```tsx
import { useLayout } from "skybridge/web";
function ThemedWidget() {
const { theme } = useLayout();
const isDark = theme === "dark";
return (
Hello
);
}
```
--------------------------------
### Build Application for Production
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/build-for-production.mdx
Run the build command from your project root to compile widgets and server code for production. This prepares your application for deployment.
```bash
npm run build
```
```bash
pnpm build
```
```bash
yarn build
```
```bash
bun build
```
```bash
deno task build
```
--------------------------------
### Configure and run the MCP server
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-stytch/README.md
Set up environment variables for Stytch integration and run the MCP server using pnpm. This starts the MCP server, OAuth pages, and Skybridge DevTools.
```env
STYTCH_PROJECT_ID=project-test-...
STYTCH_DOMAIN=https://.stytch.com
VITE_STYTCH_PUBLIC_TOKEN=public-token-test-...
SERVER_URL=http://localhost:3000
```
```bash
pnpm install
pnpm dev
```
--------------------------------
### Interactive Tutorial with Step-by-Step Follow-ups
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-send-follow-up-message.mdx
Build an interactive tutorial where each step prompts the AI for the next piece of information or guidance. The `sendFollowUpMessage` function is used to advance the tutorial by asking specific questions.
```tsx
import { useSendFollowUpMessage } from "skybridge/web";
import { useState } from "react";
const tutorialSteps = [
{
content: "Welcome to the tutorial!",
followUp: "What will I learn in step 1?",
},
{
content: "Step 1: Getting started",
followUp: "How do I proceed to step 2?",
},
{
content: "Step 2: Advanced features",
followUp: "Can you summarize what I learned?",
},
];
function Tutorial() {
const sendFollowUpMessage = useSendFollowUpMessage();
const [step, setStep] = useState(0);
const currentStep = tutorialSteps[step];
const isLastStep = step === tutorialSteps.length - 1;
const handleNext = async () => {
await sendFollowUpMessage(currentStep.followUp);
if (!isLastStep) {
setStep((s) => s + 1);
}
};
return (
);
}
```
```
--------------------------------
### Image Upload and Preview
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-files.mdx
Uploads an image file and then uses `getDownloadUrl` to generate a preview URL. This example requires importing both `upload` and `getDownloadUrl` from `useFiles`. Error handling for the upload process is included.
```tsx
import { useFiles } from "skybridge/web";
import { useState } from "react";
function ImageUploader() {
const { upload, getDownloadUrl } = useFiles();
const [previewUrl, setPreviewUrl] = useState(null);
const [isUploading, setIsUploading] = useState(false);
const handleUpload = async (event: React.ChangeEvent) => {
const file = event.target.files?.[0];
if (!file) return;
setIsUploading(true);
try {
const { fileId } = await upload(file);
const { downloadUrl } = await getDownloadUrl({ fileId });
setPreviewUrl(downloadUrl);
} catch (error) {
console.error("Upload failed:", error);
} finally {
setIsUploading(false);
}
};
return (
{isUploading &&
Uploading...
}
{previewUrl && }
);
}
```
--------------------------------
### Initialize McpServer
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/mcp-server.mdx
Instantiate McpServer with server information and options.
```typescript
const server = new McpServer(
serverInfo: { name: string; version: string },
options: McpServerOptions
);
```
--------------------------------
### McpServer Constructor
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/mcp-server.mdx
Initializes a new McpServer instance. Requires server information and optional configuration options.
```APIDOC
## Constructor
```typescript
const server = new McpServer(
serverInfo: { name: string; version: string },
options: McpServerOptions
);
```
### Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `serverInfo.name` | `string` | Name of your MCP server |
| `serverInfo.version` | `string` | Version of your server |
| `options` | `McpServerOptions` | Configuration options |
### Options
```typescript
type McpServerOptions = {
// Additional options as needed
};
```
```
--------------------------------
### Install Skybridge Skill with deno
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/migrate.mdx
Use deno to install the Skybridge skill. This command adds the skill to your project, enabling migration capabilities.
```bash
deno run -A npm:skills add alpic-ai/skybridge -s skybridge
```
--------------------------------
### Initialize Stytch Client and Configure Login
Source: https://github.com/alpic-ai/skybridge/blob/main/examples/auth-stytch/assets/login.html
Initializes the Stytch UI client with a public token and configures OTP and OAuth login options. This setup is necessary before mounting the login component.
```javascript
import { StytchUIClient, Products, OTPMethods, OAuthProviders } from 'https://esm.sh/@stytch/vanilla-js';
const stytch = new StytchUIClient('%VITE_STYTCH_PUBLIC_TOKEN%');
const config = {
products: [Products.otp, Products.oauth],
otpOptions: {
expirationMinutes: 10,
methods: [OTPMethods.Email],
},
oauthOptions: {
providers: [{ type: OAuthProviders.Google }],
loginRedirectURL: window.location.origin + '/assets/authenticate.html',
signupRedirectURL: window.location.origin + '/assets/authenticate.html',
},
};
const callbacks = {
onEvent: (evt) => {
if (evt.type !== 'AUTHENTICATE_FLOW_COMPLETE') return;
const returnTo = sessionStorage.getItem('returnTo');
if (returnTo) {
sessionStorage.removeItem('returnTo');
window.location.href = returnTo;
} else {
window.location.href = '/';
}
},
};
// When @stytch/vanilla-js is loaded via CDN (esm.sh), the custom element
// is registered in a separate module graph and does not automatically receive the client
// instance. mountLogin registers and inserts the element, but we must call render()
// manually to pass the client. This extra step is not needed when using the npm package.
stytch.mountLogin({ elementId: '#login', config, callbacks });
await customElements.whenDefined('stytch-ui');
const el = document.querySelector('#login stytch-ui');
if (el?.render) {
el.render({ client: stytch, config, callbacks });
}
```
--------------------------------
### Install Skybridge Skill with bun
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/migrate.mdx
Use bun to install the Skybridge skill. This command adds the skill to your project, enabling migration capabilities.
```bash
bunx skills add alpic-ai/skybridge -s skybridge
```
--------------------------------
### Todo List with Actions using createStore
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/create-store.mdx
Demonstrates how to create a state store with actions for managing a todo list. This includes adding, toggling, removing, and clearing completed todos. Use this pattern for complex state logic and when actions are integral to state updates.
```tsx
import { createStore } from "skybridge/web";
import type { StateCreator } from "zustand";
type Todo = {
id: string;
text: string;
completed: boolean;
};
type TodoState = {
todos: Todo[];
addTodo: (text: string) => void;
toggleTodo: (id: string) => void;
removeTodo: (id: string) => void;
clearCompleted: () => void;
};
const useTodoStore = createStore((set) => ({
todos: [],
addTodo: (text) =>
set((state) => ({
todos: [
...state.todos,
{ id: crypto.randomUUID(), text, completed: false },
],
})),
toggleTodo: (id) =>
set((state) => ({
todos: state.todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
),
})),
removeTodo: (id) =>
set((state) => ({
todos: state.todos.filter((todo) => todo.id !== id),
})),
clearCompleted: () =>
set((state) => ({
todos: state.todos.filter((todo) => !todo.completed),
})),
}));
function TodoWidget() {
const todos = useTodoStore((state) => state.todos);
const addTodo = useTodoStore((state) => state.addTodo);
const toggleTodo = useTodoStore((state) => state.toggleTodo);
const removeTodo = useTodoStore((state) => state.removeTodo);
const clearCompleted = useTodoStore((state) => state.clearCompleted);
const [input, setInput] = useState("");
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim()) {
addTodo(input.trim());
setInput("");
}
};
return (
Todo List
{todos.map((todo) => (
toggleTodo(todo.id)}
/>
{todo.text}
))}
);
}
```
--------------------------------
### Install Skybridge Skill with yarn
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/migrate.mdx
Use yarn to install the Skybridge skill. This command adds the skill to your project, enabling migration capabilities.
```bash
yarn dlx skills add alpic-ai/skybridge -s skybridge
```
--------------------------------
### Install Skybridge Skill with pnpm
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/migrate.mdx
Use pnpm to install the Skybridge skill. This command adds the skill to your project, enabling migration capabilities.
```bash
pnpm dlx skills add alpic-ai/skybridge -s skybridge
```
--------------------------------
### Start Local Server
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/quickstart/test-your-app.mdx
Run your development server without the tunnel flag for testing with local MCP clients like VSCode or Goose. Your server will be available at http://localhost:3000/mcp.
```bash
npm run dev
```
--------------------------------
### Setting URL with Form Input
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-set-open-in-app-url.mdx
This example shows how to integrate `useSetOpenInAppUrl` with a form, allowing users to input a URL dynamically. It includes state management for the URL, error messages, and success feedback.
```tsx
import { useSetOpenInAppUrl } from "skybridge/web";
import { useState } from "react";
function UrlSetter() {
const setOpenInAppUrl = useSetOpenInAppUrl();
const [url, setUrl] = useState("");
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError(null);
setSuccess(false);
try {
await setOpenInAppUrl(url);
setSuccess(true);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to set URL");
}
};
return (
);
}
```
--------------------------------
### Install Skybridge Skill
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/devtools/skills.mdx
Add the Skybridge skill to your AI coding assistant using your preferred package manager. This command installs the skill and makes it available for use.
```bash
npx skills add alpic-ai/skybridge -s skybridge
```
```bash
pnpm dlx skills add alpic-ai/skybridge -s skybridge
```
```bash
yarn dlx skills add alpic-ai/skybridge -s skybridge
```
```bash
bunx skills add alpic-ai/skybridge -s skybridge
```
```bash
deno run -A npm:skills add alpic-ai/skybridge -s skybridge
```
--------------------------------
### Build and Start Skybridge Production Server
Source: https://context7.com/alpic-ai/skybridge/llms.txt
Use `skybridge build` to compile React widgets and transpile the TypeScript server for production. `skybridge start` then runs the compiled server with `NODE_ENV=production`.
```bash
skybridge build
```
```bash
skybridge start
```
--------------------------------
### useToolInfo Example: Loading State Handling
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-tool-info.mdx
Shows how to use the 'isPending' flag from useToolInfo to display a loading indicator while a tool is executing. It also conditionally renders results when 'isSuccess' is true.
```tsx
import { useToolInfo } from "skybridge/web";
function DataWidget() {
const { input, isPending, isSuccess, output } = useToolInfo<{
input: { query: string };
output: { results: string[] };
}>();
return (
Search: {input.query}
{isPending && (
Searching...
)}
{isSuccess && (
{output.results.map((result, i) => (
{result}
))}
)}
);
}
```
--------------------------------
### Initial Project Deployment to Alpic
Source: https://github.com/alpic-ai/skybridge/blob/main/skills/chatgpt-app-builder/references/deploy.md
Use this command for the first deployment of a project. It requires specifying a project name and the path to your project directory. Ensure the `.alpic/` folder does not exist in your project directory.
```bash
npx alpic@latest deploy --yes --project-name {project-name} {path-to-project}
```
--------------------------------
### Initiate Guided Actions with useSendFollowUpMessage
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/guides/communicating-with-model.mdx
Trigger guided actions by sending specific prompts to the LLM using `useSendFollowUpMessage`. This allows for complex requests like adding items to an order and confirming the total.
```tsx
```
--------------------------------
### Create and Configure MCP Server
Source: https://context7.com/alpic-ai/skybridge/llms.txt
Instantiate and configure the McpServer, registering protocol and HTTP middleware, and defining tools like 'search-hotels' and 'hotel-details'. Method chaining is crucial for type inference. Export AppType for helper generation.
```typescript
import { McpServer } from "skybridge/server";
import { z } from "zod";
const server = new McpServer({ name: "hotel-booking", version: "1.0.0" }, {})
// Register MCP protocol-level middleware (onion model)
.mcpMiddleware("tools/call", async (request, extra, next) => {
const token = extra.requestInfo?.headers?.["authorization"];
if (!token) throw new Error("Unauthorized");
console.log(`Tool called: ${request.params.name}`);
return next();
})
// Register Express HTTP middleware
.use(cors())
// Register a widget tool
.registerWidget(
"search-hotels",
{ description: "Search for available hotels" },
{
inputSchema: {
city: z.string().describe("City to search"),
checkIn: z.string().describe("Check-in date (YYYY-MM-DD)"),
checkOut: z.string().describe("Check-out date (YYYY-MM-DD)"),
guests: z.number().optional().default(2),
},
outputSchema: {
hotels: z.array(z.object({
id: z.string(),
name: z.string(),
price: z.number(),
rating: z.number(),
})),
},
},
async ({ city, checkIn, checkOut, guests }) => {
const hotels = await searchHotels({ city, checkIn, checkOut, guests });
return {
content: [{ type: "text", text: `Found ${hotels.length} hotels in ${city}` }],
structuredContent: { hotels },
};
},
)
.registerWidget(
"hotel-details",
{ description: "Get full details for a specific hotel" },
{ inputSchema: { hotelId: z.string() } },
async ({ hotelId }, extra) => {
const email = extra.authInfo?.extra?.email as string | undefined;
const hotel = await getHotel(hotelId);
if (!hotel) {
return {
content: [{ type: "text", text: `Hotel ${hotelId} not found` }],
structuredContent: { error: "not_found" },
};
}
return {
content: [{ type: "text", text: `Showing details for ${hotel.name}` }],
structuredContent: { ...hotel, viewedBy: email },
};
},
);
// Export type for end-to-end inference in web widgets
export type AppType = typeof server;
export default server;
```
--------------------------------
### McpServer Configuration
Source: https://context7.com/alpic-ai/skybridge/llms.txt
Demonstrates how to create and configure an MCP server using method chaining for type inference. Includes registering MCP middleware, Express middleware, and custom widgets.
```APIDOC
## McpServer — Create and configure the MCP server
The main server class. Extend the MCP SDK with Skybridge capabilities. Must use **method chaining** for end-to-end type inference to work. Export `typeof server` as `AppType` for use with `generateHelpers`.
```typescript
import { McpServer } from "skybridge/server";
import { z } from "zod";
const server = new McpServer({ name: "hotel-booking", version: "1.0.0" }, {})
// Register MCP protocol-level middleware (onion model)
.mcpMiddleware("tools/call", async (request, extra, next) => {
const token = extra.requestInfo?.headers?.["authorization"];
if (!token) throw new Error("Unauthorized");
console.log(`Tool called: ${request.params.name}`);
return next();
})
// Register Express HTTP middleware
.use(cors())
// Register a widget tool
.registerWidget(
"search-hotels",
{ description: "Search for available hotels" },
{
inputSchema: {
city: z.string().describe("City to search"),
checkIn: z.string().describe("Check-in date (YYYY-MM-DD)"),
checkOut: z.string().describe("Check-out date (YYYY-MM-DD)"),
guests: z.number().optional().default(2),
},
outputSchema: {
hotels: z.array(z.object({
id: z.string(),
name: z.string(),
price: z.number(),
rating: z.number(),
})),
},
},
async ({ city, checkIn, checkOut, guests }) => {
const hotels = await searchHotels({ city, checkIn, checkOut, guests });
return {
content: [{ type: "text", text: `Found ${hotels.length} hotels in ${city}` }],
structuredContent: { hotels },
};
},
)
.registerWidget(
"hotel-details",
{ description: "Get full details for a specific hotel" },
{ inputSchema: { hotelId: z.string() } },
async ({ hotelId }, extra) => {
const email = extra.authInfo?.extra?.email as string | undefined;
const hotel = await getHotel(hotelId);
if (!hotel) {
return {
content: [{ type: "text", text: `Hotel ${hotelId} not found` }],
structuredContent: { error: "not_found" },
};
}
return {
content: [{ type: "text", text: `Showing details for ${hotel.name}` }],
structuredContent: { ...hotel, viewedBy: email },
};
},
);
// Export type for end-to-end inference in web widgets
export type AppType = typeof server;
export default server;
```
```
--------------------------------
### Example SPEC.md for Pizza Ordering App
Source: https://github.com/alpic-ai/skybridge/blob/main/skills/chatgpt-app-builder/references/discover.md
This markdown example demonstrates the structure and content expected in a SPEC.md file after completing the discovery workflow. It includes sections for Value Proposition, Why LLM?, UI Overview, and Product Context.
```markdown
# Pizza Ordering App
## Value Proposition
Order pizza through conversation. Target: PizzaCo customers wanting quick orders. Pain: navigating menus is slower than describing what you want.
**Core actions**: Browse menu, customize order, track delivery.
## Why LLM?
**Conversational win**: "My usual but with mushrooms" = one sentence vs. multiple screens.
**LLM adds**: Intent from natural descriptions, handles modifications.
**What LLM lacks**: Real menu and pricing data, order placement.
## UI Overview
**First view**: Popular pizzas with quick "reorder last" option.
**Browsing**: Menu with categories, filters, and customization options.
**Checkout**: Order summary, confirm, and place order.
**Tracking**: Live delivery status with ETA and map.
## Product Context
- **Existing products**: Mobile app, website
- **API**: REST at api.pizzaco.com (OAuth2, 100 req/min)
- **Auth**: PizzaCo account (OAuth2)
- **Constraints**: Payment via existing account only
```
--------------------------------
### Example Usage of useCallTool in a Widget
Source: https://context7.com/alpic-ai/skybridge/llms.txt
This example demonstrates how to use the useCallTool hook within a React component to search for hotels. It showcases autocompletion for the tool name and type inference for input and output, along with handling success and error states.
```tsx
import { useCallTool, useToolInfo } from "../helpers";
export function HotelSearchWidget() {
// Tool name "search-hotels" is autocompleted; input/output shapes are inferred
const { callTool, isPending, isSuccess, data } = useCallTool("search-hotels");
const handleSearch = () => {
callTool(
{ city: "Paris", checkIn: "2025-09-01", checkOut: "2025-09-07", guests: 2 },
{
onSuccess: (response) => console.log("Hotels:", response.structuredContent.hotels),
onError: (err) => console.error("Search failed:", err),
}
);
};
return (
);
}
```
--------------------------------
### Settings Modal Example
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/use-request-modal.mdx
Demonstrates using `useRequestModal` to open a settings form. The widget's state is managed locally and displayed when `isOpen` is true.
```tsx
import { useRequestModal } from "skybridge/web";
import { useState } from "react";
function SettingsWidget() {
const { open, isOpen } = useRequestModal();
const [settings, setSettings] = useState({
notifications: true,
darkMode: false,
language: "en",
});
if (isOpen) {
return (
);
}
return (
Settings
);
}
```
--------------------------------
### ToolOutput
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/infer-utility-types.mdx
Get the output type for a specific tool.
```APIDOC
## ToolOutput
Get the output type for a specific tool:
```typescript
import type { ToolOutput } from "skybridge/server";
import type { AppType } from "../../server/src/index";
type SearchOutput = ToolOutput;
// { hotels: Array<{ id: string; name: string; price: number }> }
```
```
--------------------------------
### ToolInput
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/infer-utility-types.mdx
Get the input type for a specific tool.
```APIDOC
## ToolInput
Get the input type for a specific tool:
```typescript
import type { ToolInput } from "skybridge/server";
import type { AppType } from "../../server/src/index";
type SearchInput = ToolInput;
// { city: string; checkIn: string; checkOut: string; guests?: number }
```
```
--------------------------------
### Subsequent Project Deployments to Alpic
Source: https://github.com/alpic-ai/skybridge/blob/main/skills/chatgpt-app-builder/references/deploy.md
Execute this command for deployments after the initial setup. It assumes the `.alpic/` folder exists in your project directory and only requires the project path.
```bash
npx alpic@latest deploy --yes {path-to-project}
```
--------------------------------
### Run Skybridge Package Manager Scripts
Source: https://github.com/alpic-ai/skybridge/blob/main/docs/api-reference/cli.mdx
Demonstrates how to execute the `dev`, `build`, and `start` scripts for a Skybridge project using various package managers like npm, pnpm, yarn, bun, and deno.
```bash
npm run dev
npm run build
npm start
```
```bash
pnpm dev
pnpm build
pnpm start
```
```bash
yarn dev
yarn build
yarn start
```
```bash
bun dev
bun build
bun start
```
```bash
deno task dev
denotask build
denotask start
```