Skip to main content
The withKontext mixin adds Kontext capabilities to any Cloudflare Agent. It handles MCP OAuth, credential storage via Durable Objects, and exposes your integrations as ready-to-use tools.

Install

npm install @kontext-dev/js-sdk agents

Complete example

import { Agent } from "agents";
import { withKontext } from "@kontext-dev/js-sdk/cloudflare";

class MyAgent extends withKontext(Agent) {
  async onChatMessage(onFinish) {
    const tools = await this.kontextTools();
    const systemPrompt = this.kontextSystemPrompt;
    // Use tools with your LLM of choice
  }
}

export default {
  fetch(request: Request, env: Env, ctx: ExecutionContext) {
    return MyAgent.mount("/agent").fetch(request, env, ctx);
  },
};

What withKontext adds

withKontext(AgentClass) is a mixin that extends your Agent class with Kontext capabilities. It hooks into the Agent lifecycle automatically:
  • onConnect — Captures the callback host used for OAuth popup redirects.
  • onStart — Configures the OAuth callback response handler.
  • onRequest — Delegates MCP transport and OAuth callback requests to the built-in MCP handler.
The mixin adds three members to your agent:
  • this.kontextTools() — Returns a Promise<ToolSet> with all tools from connected integrations. Call this in message handlers (e.g. onChatMessage) after onConnect has fired. On first run, onConnect must set the callback host before kontextTools() can connect to Kontext.
  • this.kontextSystemPrompt — A string describing which integrations are connected and available. Pass it to your LLM as the system prompt.
  • this.createMcpOAuthProvider(callbackUrl) — Returns a KontextCloudflareOAuthProvider instance. The callbackUrl parameter is required. Override this method to customize the OAuth provider.

OAuth with Durable Object storage

KontextCloudflareOAuthProvider stores OAuth tokens and session state in Durable Objects. The mixin configures this automatically using your KONTEXT_CLIENT_ID environment variable.
import {
  withKontext,
  KontextCloudflareOAuthProvider,
} from "@kontext-dev/js-sdk/cloudflare";
If you need to customize the OAuth provider (for example, to use a different storage backend), override createMcpOAuthProvider() in your agent class:
class MyAgent extends withKontext(Agent) {
  createMcpOAuthProvider(callbackUrl: string) {
    return new KontextCloudflareOAuthProvider({
      kontextClientId: this.env.KONTEXT_CLIENT_ID,
      storage: this.ctx.storage,
      agentName: this.name,
      callbackUrl,
    });
  }
}

Wrangler configuration

Add KONTEXT_CLIENT_ID to your wrangler.toml:
[vars]
KONTEXT_CLIENT_ID = "app_your-app-id"
For production, use secrets instead of plaintext vars:
npx wrangler secret put KONTEXT_CLIENT_ID

Environment bindings

Your Env type needs to include the Kontext client ID and any Durable Object bindings the SDK uses:
interface Env {
  KONTEXT_CLIENT_ID: string;
  AI: Ai;
  // Your other bindings
}
The withKontext mixin reads KONTEXT_CLIENT_ID from the environment automatically. No additional configuration is needed beyond setting the variable. Optionally set KONTEXT_SERVER_URL to point at a non-default Kontext API host.

Using tools with an LLM

Once you have tools from kontextTools(), pass them to any LLM SDK:
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

class MyAgent extends withKontext(Agent) {
  async onChatMessage(onFinish) {
    const tools = await this.kontextTools();
    const systemPrompt = this.kontextSystemPrompt;

    const result = await generateText({
      model: openai("gpt-4o"),
      tools,
      system: systemPrompt,
      prompt: "List my recent GitHub notifications",
      maxSteps: 5,
    });

    // Send result back to the client
    this.send(result.text);
  }
}

Next steps

  • React SDK — Build a frontend that connects to your Cloudflare Agent.
  • Vercel AI SDK — Use Kontext tools with generateText and streamText.
  • How Kontext Works — Understand the Kontext architecture and credential flow.