Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs-staging.skybridge.tech/llms.txt

Use this file to discover all available pages before exploring further.

Use skybridge/server

This guide shows you how to add skybridge/server to an existing MCP server to enable view support with full TypeScript type inference.

Prerequisites

You should already have:

Install Skybridge

pnpm add skybridge

Update your server

Replace your McpServer import with Skybridge’s enhanced version:
// Before
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

// After
import { McpServer } from "skybridge/server";
Keep your existing dependency to @modelcontextprotocol/sdk in your project, skybridge does not replaces it, but depends on it. Your existing tools, resources, and prompts will continue to work as before. With skybridge/server, registerTool provides an optional view field so you can bind a tool to a React view in a single call.

Project structure

your-project/
├── src/
│   ├── server.ts             # MCP server entry
│   └── views/
│       └── my-view.tsx     # View component
├── vite.config.ts            # Vite + Skybridge plugin
├── tsconfig.json
└── package.json
By default views are located in src/views/. This is configurable via the viewsDir option in the provided Vite plugin.

View naming convention

A view’s file name must match view.component in registerTool. See registerTool.

Set up Vite

Install the web dependencies and create vite.config.ts at the project root:
pnpm add react react-dom
pnpm add -D vite typescript @types/react @types/react-dom
// vite.config.ts
import { defineConfig } from "vite";
import { skybridge } from "skybridge/vite";

export default defineConfig({
  plugins: [skybridge()],
});
Make sure tsconfig.json includes the generated types:
{
  "include": ["src", ".skybridge/**/*.d.ts"]
}

Create your first view

Create src/views/my-view.tsx and export default a React component:
export default function MyView() {
  return (
    <div>
      <h2>Hello from Skybridge!</h2>
      <p>Your view is working!</p>
    </div>
  );
}

Register the view

In your server code, register the view with registerTool and view:
import { McpServer } from "skybridge/server";
import { z } from "zod";

const server = new McpServer({ name: "my-app", version: "1.0" }, {})
  .registerTool(
    {
      name: "my-view",
      description: "My first view",
      inputSchema: { message: z.string() },
      view: { component: "my-view" }, // must match src/views/my-view.tsx
    },
    async ({ message }) => {
      return { content: message || "Hello World" };
    },
  );

Configure your dev server

Update your server startup to serve the MCP endpoint. If you’re using Express:
import { McpServer } from "skybridge/server";
import { z } from "zod";
import express from "express";

const app = express();
const server = new McpServer({ name: "my-app", version: "1.0" }, {})
  .registerTool(
    {
      name: "my-view",
      inputSchema: { message: z.string() },
      view: { component: "my-view" },
    },
    async ({ message }) => {
      return { content: message };
    },
  );

// Serve the MCP endpoint
app.use("/mcp", server.handler());

// Start the server
app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

Type Safety

For full type inference and autocomplete, use method chaining and generateHelpers. See Type Safety for the complete setup. Quick summary:
  1. Use method chaining when registering tools
  2. Export type AppType = typeof server
  3. Create a helpers.ts file with generateHelpers<AppType>()
  4. Import typed hooks from your helper file