SDK for building Pixie Apps that work with both OpenAI Apps and MCP Apps platforms.
npm install pixie-apps-sdkSimply import the SDK in your widget code, and window.pixie will be automatically available:
import 'pixie-apps-sdk';That's it! The SDK automatically detects the platform (OpenAI Apps or MCP Apps) and initializes window.pixie accordingly.
Once imported, you can use window.pixie throughout your application:
The SDK provides React hooks for accessing tool data and UI state:
function MyWidget() {
// Tool data
const toolInput = window.pixie.useToolInput();
const toolOutput = window.pixie.useToolOutput();
const toolResponseMetadata = window.pixie.useToolResponseMetadata();
// UI state
const theme = window.pixie.useTheme(); // "light" | "dark"
const displayMode = window.pixie.useDisplayMode(); // "pip" | "inline" | "fullscreen"
const maxHeight = window.pixie.useMaxHeight();
const safeArea = window.pixie.useSafeArea();
const userAgent = window.pixie.useUserAgent();
const locale = window.pixie.useLocale();
// Widget state (persistent across renders)
const widgetState = window.pixie.getWidgetState();
window.pixie.setWidgetState({ myData: 'value' });
return <div>My Widget</div>;
}// Call a tool
const result = await window.pixie.callTool('tool-name', { arg1: 'value' });
// Send a follow-up message
window.pixie.sendFollowupMessage('Can you show me more items?');
// Open external link
window.pixie.openExternal('https://example.com');
// Request display mode change
window.pixie.requestDisplayMode('fullscreen');
// Request modal
const modalResult = await window.pixie.requestModal({
title: 'My Modal',
params: { message: 'Hello' }
});
// Request to close widget
await window.pixie.requestClose();The SDK includes full TypeScript definitions. Import types as needed:
import type { Provider, WidgetState, Theme, DisplayMode } from 'pixie-apps-sdk';
declare global {
interface Window {
pixie: Provider;
}
}import { useEffect, useState } from 'react';
import 'pixie-apps-sdk';
type MyPayload = {
items?: Array<{ name: string; price: number }>;
};
function ShoppingWidget() {
const toolOutput = window.pixie.useToolOutput() as MyPayload | null;
const theme = window.pixie.useTheme();
const [cart, setCart] = useState<string[]>([]);
useEffect(() => {
if (toolOutput?.items) {
// Process tool output
console.log('Received items:', toolOutput.items);
}
}, [toolOutput]);
const handleAddToCart = (itemName: string) => {
setCart([...cart, itemName]);
// Persist state
window.pixie.setWidgetState({ cart });
};
const handleCheckout = () => {
window.pixie.openExternal('https://checkout.example.com');
};
return (
<div style={{
background: theme === 'dark' ? '#000' : '#fff',
color: theme === 'dark' ? '#fff' : '#000'
}}>
<h1>My Shopping Widget</h1>
{toolOutput?.items?.map(item => (
<div key={item.name}>
<span>{item.name} - ${item.price}</span>
<button onClick={() => handleAddToCart(item.name)}>
Add to Cart
</button>
</div>
))}
<button onClick={handleCheckout}>Checkout</button>
</div>
);
}All hooks are React hooks that automatically re-render when values change.
useToolInput()- Get the tool input datauseToolOutput()- Get the tool output datauseToolResponseMetadata()- Get tool response metadatauseTheme()- Get current theme ("light" | "dark")useDisplayMode()- Get current display mode ("pip" | "inline" | "fullscreen")useMaxHeight()- Get maximum widget heightuseSafeArea()- Get safe area insetsuseUserAgent()- Get user agent informationuseLocale()- Get current locale string
getWidgetState()- Get current widget state (persistent)setWidgetState(state)- Update widget state
callTool(name, args?)- Call a tool and return resultsendFollowupMessage(message)- Send a follow-up message to the assistantopenExternal(href)- Open an external URLrequestDisplayMode(mode)- Request a display mode changerequestModal(args)- Request a modal dialogrequestClose()- Request to close the widget
The SDK automatically detects and works with:
- OpenAI Apps - Uses
window.openaiAPI - MCP Apps - Uses MCP Apps protocol
No configuration needed - just import and use!
- React 18+ (peer dependency)
- React DOM 18+ (peer dependency)
See LICENSE file for details.