Browse documentation

Documentation

TypeScript SDK

Server-side, user-scoped access to Authlane capabilities and local AI tools

Install and configure

pnpm add @authlane/sdk
import { Authlane } from '@authlane/sdk';

const authlane = new Authlane({
  apiKey: process.env.AUTHLANE_API_KEY!,
  baseUrl: 'https://app.authlane.io',
});

The client sends the tenant API key as a bearer credential and is server-only. API and adapter operations return { data, error }; they do not throw for expected failures. Invalid constructor configuration still throws.

User-scoped resources

Derive externalUserId from your SaaS's authenticated server session once, then bind it:

const currentUser = await requireUser(request);
const user = authlane.user(currentUser.id);

const capabilities = await user.capabilities.get({ format: 'mcp' });
const connections = await user.connections.list();
const definitions = await user.tools.list({ format: 'openai' });

user.capabilities.get() is the hot read for status plus definitions in one versioned snapshot. The unscoped methods remain available, but authlane.user(externalUserId) makes the identity boundary explicit and avoids repeating an ID on every call.

Vercel AI SDK

Install the adapter's optional peer explicitly:

pnpm add @authlane/sdk @authlane/ai ai zod
import { vercelAI } from '@authlane/ai/vercel';
import { createTextStreamResponse, streamText, toTextStream } from 'ai';

const user = authlane.user(currentUser.id);
const { data: tools, error } = await user.tools.list({ adapter: vercelAI() });

if (error) {
  return Response.json(
    { error: { code: error.code, message: error.message } },
    { status: error.statusCode ?? 400 },
  );
}

const result = streamText({
  model: 'openai/gpt-5-mini',
  messages,
  tools,
});

return createTextStreamResponse({
  stream: toTextStream({ stream: result.stream }),
});

OpenAI Agents SDK

Install the OpenAI Agents optional peer explicitly:

pnpm add @authlane/sdk @authlane/ai @openai/agents zod
import { openAIAgents } from '@authlane/ai/openai';
import { Agent, run } from '@openai/agents';

const user = authlane.user(currentUser.id);
const { data: tools, error } = await user.tools.list({ adapter: openAIAgents() });

if (error) {
  return Response.json(
    { error: { code: error.code, message: error.message } },
    { status: error.statusCode ?? 400 },
  );
}

const agent = new Agent({
  name: 'Workspace assistant',
  instructions: 'Use only the connected services needed to answer the request.',
  tools,
});
const result = await run(agent, prompt);

return Response.json({ output: result.finalOutput });

Local MCP server

Install the MCP optional peer explicitly:

pnpm add @authlane/sdk @authlane/ai @modelcontextprotocol/sdk zod

mcpServer() creates a low-level MCP Server; your application owns and connects its transport:

import { mcpServer } from '@authlane/ai/mcp';
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';

export async function connectUserMcpServer(
  externalUserId: string,
  transport: Transport,
) {
  const user = authlane.user(externalUserId);
  const result = await user.tools.list({ adapter: mcpServer() });

  if (result.error) return result;
  await result.data.connect(transport);
  return result;
}

The caller must authenticate the user before calling this function and must close the returned server and transport together. One server is permanently bound to one externalUserId; never reuse it for another identity, connection, request context, or tenant.

Custom integration overrides

Pass an application-owned integration adapter to any framework adapter. An explicit custom adapter takes priority over Authlane's built-in adapter with the same serviceId:

import type { FrameworkAdapterOptions } from '@authlane/ai';
import { vercelAI } from '@authlane/ai/vercel';

type IntegrationAdapter = NonNullable<FrameworkAdapterOptions['integrations']>[number];

const customGithub: IntegrationAdapter = {
  serviceId: 'github',
  definitions: [],
  async execute(toolName, input, credential) {
    return executeGithubInsideOurBackend(toolName, input, credential);
  },
};

const result = await authlane.user(currentUser.id).tools.list({
  adapter: vercelAI({ integrations: [customGithub] }),
});

Custom adapters run inside your SaaS trust boundary. They receive ephemeral access-only material for the current invocation and must not log, persist, cache, or return it.

Connect sessions and raw definitions

const session = await authlane.connectSessions.create({
  externalUserId: currentUser.id,
  allowedServices: ['github'],
  allowedOrigin: 'https://app.example.com',
  expiresInSeconds: 600,
});

await authlane.services.list();
await authlane.user(currentUser.id).tools.list({ format: 'openai' });

Return only session.data?.url to the browser. Raw tool definitions contain no execution callbacks; executable toolsets from an adapter are server-only. Provider requests originate in your SaaS process and never pass through Authlane.

An empty allowedServices array snapshots every service currently enabled globally and for the organization. Authlane stores the resolved IDs on the session; later additions are not included, and later-disabled services are hidden and cannot start a new authorization.