npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@orkestrate/sdk

v0.2.0

Published

Publisher HTTP handler for Orkestrate — verify, parse, build model, respond. BYOM (Bring Your Own Model) for your agent.

Readme

@orkestrate/sdk

The official SDK for building Orkestrate publisher agents.

npm version License CI


What is Orkestrate?

Orkestrate is an AI agent gateway. Coding tools like Cursor, Claude Code, and VS Code connect to it via MCP and discover agents published by companies like yours. Callers bring their own model (BYOM) — you just handle the turn.

sequenceDiagram
    participant Coder as Coding tool (Cursor, etc.)
    participant GW as Orkestrate Gateway (orkestrate.space)
    participant Agent as Your Publisher Agent
    participant LLM as LLM (caller's API key)

    Coder->>GW: MCP request (BYOM config)
    GW->>GW: Auth, routing, session management
    GW->>Agent: POST /api/orkestrate Authorization: Bearer X-Orkestrate-Action X-Orkestrate-Model (base64url)
    Agent->>Agent: verifyRequest() parseRequest() buildModel()
    Agent->>LLM: generateText() (caller's key)
    LLM-->>Agent: response
    Agent-->>GW: { reply: "..." }
    GW-->>Coder: MCP response

You deploy a single HTTP endpoint. The gateway handles everything else: caller auth, session management, rate limits, turn tracking. Your job is one function: receive a message, run your agent, return a reply.

Why use this SDK?

  • Stop managing multi-tenant API keys. Callers bring their own. You never pay for inference.
  • No session infrastructure to build. Gateway mints session ids, enforces TTLs, stores history.
  • One import, any framework. Primitives for bare-bones handlers, convenience wrapper for AI SDK users.
  • BYOM works out of the box. OpenAI, Anthropic, Google, or any OpenAI-compatible provider.

Install

npm install @orkestrate/sdk ai

ai (Vercel AI SDK) is a peer dependency — required for buildModel and createOrkestrateHandler. If you only use verifyRequest and parseRequest, you can ignore the peer dep warning.

Quick start

Primitives (any framework)

import { verifyRequest, parseRequest, buildModel, respond } from "@orkestrate/sdk";

async function handler(request: Request) {
  verifyRequest(request, process.env.ORKESTRATE_SECRET!);
  const { action, sessionId, message, modelConfig, messages } =
    await parseRequest(request);

  switch (action) {
    case "ping":
    case "end_session":
      return respond.ok();
    case "start_session":
    case "send_message": {
      const model = buildModel(modelConfig!);
      const reply = await runAgent({ message: message!, model, sessionId, messages: messages! });
      return respond.reply(reply);
    }
  }
}

AI SDK convenience wrapper

import { createOrkestrateHandler } from "@orkestrate/sdk";
import { generateText } from "ai";

export const { GET, POST } = createOrkestrateHandler({
  secret: process.env.ORKESTRATE_SECRET!,
  async onTurn({ message, model, messages, callerId }) {
    const result = await generateText({ model, messages });
    return { reply: result.text };
  },
});

Complete working example (Next.js)

// app/api/orkestrate/route.ts  ← must match gateway's path
import { createOrkestrateHandler } from "@orkestrate/sdk";
import { generateText } from "ai";

export const { GET, POST } = createOrkestrateHandler({
  secret: process.env.ORKESTRATE_SECRET!,

  async onTurn({ message, model, messages, callerId }) {
    const { text } = await generateText({
      model,
      messages,
      system: "You are a helpful product agent.",
    });
    return { reply: text };
  },
});

Deploy this to Vercel, register your domain at orkestrate.space, and you're live. The gateway calls https://<your-domain>/api/orkestrate.

API

verifyRequest(request, secret)

Authenticates the gateway request via Authorization: Bearer <secret>.
Throws OrkestrateError("UNAUTHORIZED") on failure.

parseRequest(request)

Decodes gateway headers + body into a typed ParsedRequest:

| Field | Source | Description | |-------|--------|-------------| | action | X-Orkestrate-Action | start_session / send_message / end_session / ping | | sessionId | X-Orkestrate-Session-Id | Gateway-minted session id | | callerId | X-Orkestrate-Caller-Id | Opaque caller identifier (optional) | | modelConfig | X-Orkestrate-Model | Base64url JSON — provider, model, apiKey, baseURL? | | message | body | Latest user message text | | messages | body | Full conversation history |

buildModel(config)

Constructs an AI SDK LanguageModel from the caller's BYOM config.

Supports: openai · anthropic · google · custom (OpenAI-compatible)

respond

| Method | Returns | |--------|---------| | respond.ok(extra?) | { ok: true } — ping, end_session | | respond.reply(text) | { reply: "..." } — agent response | | respond.error(code, message, status?) | { error: { code, message } } — typed error |

createOrkestrateHandler(options)

Convenience wrapper for AI SDK users. Returns { GET, POST } handlers.

Options: { secret, onTurn: (ctx: TurnContext) => TurnResult, onClose?: (ctx: CloseContext) => void }

Wire protocol

| Header | When | |--------|------| | Authorization: Bearer <secret> | all POST requests | | X-Orkestrate-Action | start_session / send_message / end_session / ping | | X-Orkestrate-Session-Id | open / send / close | | X-Orkestrate-Model | open / send — base64url JSON | | X-Orkestrate-Caller-Id | optional — opaque caller identity |

Error codes

| Code | HTTP | Meaning | |------|------|---------| | UNAUTHORIZED | 401 | Bad or missing Authorization | | BAD_REQUEST | 400 | Missing header, invalid body, bad model config | | MODEL_ERROR | 400 | buildModel rejected the config | | SESSION_NOT_FOUND | 500 | Session id does not exist | | SESSION_EXPIRED | 500 | Session idle or hard TTL | | SESSION_STALE | 500 | Session data is stale | | CONFLICT | 500 | Concurrent operation on the same session | | LIMIT_EXCEEDED | 500 | Turn or rate limit hit | | INTERNAL | 500 | onTurn threw or returned empty reply |

Limitations

| Limitation | Details | |------------|---------| | No streaming | V1 is text-turn only. SSE streaming is planned. | | custom provider | Assumes OpenAI-compatible /chat/completions API. Works with Ollama, vLLM, etc. | | Bundle size | Includes @ai-sdk/openai, @ai-sdk/anthropic, and @ai-sdk/google regardless of which provider you use. |

What the gateway handles (not in this SDK)

The gateway — not this SDK — manages session storage, conversation history persistence, rate limiting, idle timeout, absolute TTL, concurrent session limits, and caller authentication. You just handle turns.

Learn more

License

MIT