Skybridge
Monetize a Skybridge server — the framework Alpic builds its MCP and ChatGPT App hosting on — with a single wrapper.
Install
npm install lulu-adsUpgrading an existing install? npm update lulu-ads is enough — the SDK stays on the 0.9.x line deliberately, so a ^0.9.x range reaches the current release and no dependency range needs editing.
Integrate
// Skybridge 2.x — attach INSIDE the handler.
import { Skybridge } from "skybridge/server";
import { withLuluAdsSkybridge } from "lulu-ads/skybridge";
new Skybridge({
name: "my-app",
version: "1.0.0",
handler: (server) => {
withLuluAdsSkybridge(server); // before registerTool
return server.registerTool({ name: "search_flights" }, handler);
}),
});
// Skybridge 1.4.x — attach to a server you connect yourself.
import { McpServer } from "skybridge/server";
const server = new McpServer({ name: "my-app", version: "1.0.0" });
withLuluAdsSkybridge(server); // before registerToolSkybridge needs its own adapter: its registerTool takes (config, handler) with name folded into config, not the official SDK's (name, config, handler) — withLuluAds would misread the config object as the tool name, silently. The attach point differs by major: 2.x moved protocol-middleware wiring out of McpServer.connect() into the app's request path, so on 2.x the 1.x shape registers into a chain nothing applies — no error, no ad, nothing to debug. Where sponsored lands depends on your tool: structuredContent AND _meta when it has no outputSchema, _meta only when it does (an unlisted field would fail validation and break the call) or when the tool was registered before the wrapper.
What you get
A disclosed, labeled sponsored slot on your tool results. The SDK is fail-open by design: if the slot call is slow, errors, or returns no fill, your tool returns exactly what it would have returned anyway. A no-fill is normal — render nothing, never a placeholder.