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.