🥞PancakeJS

API Reference

Complete API reference for Pancake SDK packages.

Server Package (@pancake-apps/server)

createApp

Creates a new Pancake application instance.

import { createApp } from '@pancake-apps/server';

const app = createApp({
  name: string;           // App name (required)
  version: string;        // Semantic version (required)
  views?: ViewMap;        // View definitions
  actions?: ActionMap;    // Action definitions
  data?: DataMap;         // Data endpoint definitions
  tools?: ToolMap;        // Low-level tool definitions
  middleware?: Middleware[];  // Request middleware
  plugins?: Plugin[];     // Lifecycle plugins
  config?: AppConfig;     // Configuration options
});

defineView

Type-safe helper for defining views.

import { defineView } from '@pancake-apps/server';
import { z } from 'zod';

const view = defineView({
  description: string;           // Description for AI
  input?: ZodSchema;             // Input parameters schema
  data?: ZodSchema;              // Response data schema
  handler?: (input) => Promise<Data>;  // Data fetching function
  ui: { html: string } | { component: ReactComponent };
  visibility?: 'both' | 'model' | 'app';
});

defineAction

Type-safe helper for defining actions.

import { defineAction } from '@pancake-apps/server';
import { z } from 'zod';

const action = defineAction({
  description: string;           // Description for AI
  input: ZodSchema;              // Input schema (required)
  output: ZodSchema;             // Output schema (required)
  handler: (input) => Promise<Output>;  // Handler function
});

defineData

Type-safe helper for defining data endpoints.

import { defineData } from '@pancake-apps/server';
import { z } from 'zod';

const data = defineData({
  description: string;           // Description for AI
  input: ZodSchema;              // Input schema
  output: ZodSchema;             // Output schema
  handler: (input) => Promise<Output>;  // Handler function
});

discoverViews

Auto-discover views from the filesystem.

import { discoverViews } from '@pancake-apps/server';

const views = discoverViews('./src/views');
// Returns: { viewName: ViewConfig, ... }

discoverViewsAsync

Async version of discoverViews.

import { discoverViewsAsync } from '@pancake-apps/server';

const views = await discoverViewsAsync('./src/views');

createTunnel

Create a tunnel programmatically.

import { createTunnel } from '@pancake-apps/server';

const tunnel = await createTunnel({
  provider: 'cloudflare', // or 'ngrok'
  port: 3000,
  authtoken?: string;     // For ngrok
});

console.log(tunnel.url);  // https://random.trycloudflare.com
await tunnel.close();     // Stop the tunnel

App Instance Methods

// Start the server
app.start({
  port?: number;          // Default: 3000
  host?: string;          // Default: '0.0.0.0'
  transport?: 'http' | 'stdio';
});

// Stop the server
await app.stop();

// Add middleware
app.use(middleware);

// Listen to events
app.on('app:start', (payload) => { ... });
app.on('app:shutdown', (payload) => { ... });

// Handle requests (for serverless)
const response = await app.handleRequest(request);

Configuration Options

config: {
  // Enable debug logging
  debug?: boolean;

  // Target protocol
  protocol?: 'mcp' | 'openai' | 'both';

  // Tunnel configuration
  tunnel?: {
    provider: 'cloudflare' | 'ngrok';
    authtoken?: string;  // For ngrok
  };

  // CORS settings
  cors?: {
    origin?: string | string[];
    methods?: string[];
    credentials?: boolean;
  };

  // Vite dev server settings
  devServer?: {
    vitePort?: number;
  };

  // MCP server route
  serverRoute?: string;  // Default: '/mcp'
}

Web Package (@pancake-apps/web)

React Hooks

PancakeProvider

Root provider for React views.

import { PancakeProvider } from '@pancake-apps/web';

function App() {
  return (
    <PancakeProvider>
      <YourView />
    </PancakeProvider>
  );
}

useViewParams

Access view inputs and server data.

import { useViewParams } from '@pancake-apps/web';

function MyView() {
  const { inputs, data } = useViewParams<InputType, DataType>();

  // inputs: Parameters passed to the view
  // data: Data returned by the handler
}

useViewState

Persist state across re-renders.

import { useViewState } from '@pancake-apps/web';

function MyView() {
  const [count, setCount] = useViewState(0);
  // Similar to useState, but persists in the host
}

useNavigation

Navigate between views and message the AI.

import { useNavigation } from '@pancake-apps/web';

function MyView() {
  const { navigate, say } = useNavigation();

  // Navigate to another view
  navigate('other-view', { param: 'value' });

  // Send a message to the AI
  say('Help me with this');
}

useAction

Dispatch actions (write operations).

import { useAction } from '@pancake-apps/web';

function MyView() {
  const { dispatch } = useAction();

  const handleSubmit = async () => {
    const result = await dispatch<OutputType>('actionName', { input: 'value' });
  };
}

useData

Fetch data (read operations).

import { useData } from '@pancake-apps/web';

function MyView() {
  const { getData } = useData();

  const loadItems = async () => {
    const items = await getData<ItemType[]>('dataEndpoint', { limit: 10 });
  };
}

useTheme

Get current theme from host.

import { useTheme } from '@pancake-apps/web';

function MyView() {
  const theme = useTheme(); // 'light' | 'dark'
}

useDisplayMode

Get display mode from host.

import { useDisplayMode } from '@pancake-apps/web';

function MyView() {
  const mode = useDisplayMode(); // 'embedded' | 'standalone'
}

useHost

Access full host context.

import { useHost } from '@pancake-apps/web';

function MyView() {
  const host = useHost();

  // host.theme: 'light' | 'dark'
  // host.displayMode: 'embedded' | 'standalone'
}

useActionInput

For action confirmation UIs.

import { useActionInput } from '@pancake-apps/web';

function ConfirmationUI() {
  const input = useActionInput<{ amount: number }>();
  // input.amount: The action parameters to confirm
}

Vanilla JS API

For HTML views without React, use the global window.pancake object:

// Wait for pancake to initialize
const pancake = await new Promise((resolve) => {
  if (window.pancake) return resolve(window.pancake);
  const check = setInterval(() => {
    if (window.pancake) {
      clearInterval(check);
      resolve(window.pancake);
    }
  }, 50);
});

// Access view data
const data = pancake.adaptor.getToolOutput();
const inputs = pancake.adaptor.getToolInput();

// Get host context
const theme = pancake.hostContext.theme;
const displayMode = pancake.hostContext.displayMode;

// Navigate to another view
pancake.unified.navigate('view-name', { param: 'value' });

// Send message to AI
pancake.unified.say('Hello AI');

// Call an action
const result = await pancake.unified.action('actionName', { input: 'value' });

// Fetch data
const items = await pancake.unified.data('dataEndpoint', { limit: 10 });

// Persist view state
pancake.setViewState({ key: 'value' });
const state = pancake.getViewState();

Type Definitions

ViewConfig

interface ViewConfig<TInput, TData> {
  description: string;
  input?: ZodSchema<TInput>;
  data?: ZodSchema<TData>;
  handler?: (input: TInput) => Promise<TData>;
  ui: { html: string } | { component: ComponentType };
  visibility?: 'both' | 'model' | 'app';
}

ActionConfig

interface ActionConfig<TInput, TOutput> {
  description: string;
  input: ZodSchema<TInput>;
  output: ZodSchema<TOutput>;
  handler: (input: TInput) => Promise<TOutput>;
}

DataConfig

interface DataConfig<TInput, TOutput> {
  description: string;
  input: ZodSchema<TInput>;
  output: ZodSchema<TOutput>;
  handler: (input: TInput) => Promise<TOutput>;
}

StartOptions

interface StartOptions {
  port?: number;
  host?: string;
  transport?: 'http' | 'stdio';
}

TunnelConfig

interface TunnelConfig {
  provider: 'cloudflare' | 'ngrok';
  port: number;
  authtoken?: string;
}

TunnelResult

interface TunnelResult {
  url: string;
  close: () => Promise<void>;
}

Next Steps

On this page