Supyagent
Package ReferenceSDK (Node.js)

Client

The supyagent() client — fetch tools, skills, and account info from Supyagent Cloud.

Client

The supyagent() factory creates a client that connects your app to Supyagent Cloud. It provides three methods: tools(), skills(), and me().

import { supyagent } from '@supyagent/sdk';

const client = supyagent({
  apiKey: process.env.SUPYAGENT_API_KEY!,
  baseUrl: 'https://app.supyagent.com', // optional, this is the default
});

client.tools(options?)

Fetches all available integration tools and converts them to Vercel AI SDK Tool objects. Each tool maps to an API endpoint on Supyagent Cloud.

const tools = await client.tools();
// => Record<string, Tool>

// Filter to specific providers or services
const googleTools = await client.tools({ only: ['google'] });
const noSlack = await client.tools({ except: ['slack'] });

// Enable caching (recommended for production)
const tools = await client.tools({ cache: 300 }); // 5 minute TTL

Options

OptionTypeDescription
onlystring[]Only include tools matching these providers, services, or names
exceptstring[]Exclude tools matching these providers, services, or names
cacheboolean | numbertrue = 60s cache, number = custom TTL in seconds

The returned tools are ready to pass directly to streamText() or generateText():

import { streamText } from 'ai';

const result = streamText({
  model: yourModel,
  messages,
  tools: await client.tools({ cache: 300 }),
});

Tool Metadata & connected Status

Every tool returned by the API includes a metadata object with a connected field indicating whether the user has the required integration active:

{
  "metadata": {
    "provider": "google",
    "service": "gmail",
    "permission": "gmail.send",
    "method": "POST",
    "path": "/api/v1/gmail/send",
    "connected": true
  }
}

When using client.tools(), only connected tools are returned by default. To fetch all tools (connected and disconnected), use the REST API directly with ?all=true — see Tool Discovery below.

client.skills(options?)

Fetches skill documentation from Supyagent Cloud and returns a system prompt plus two tools (loadSkill and apiCall). This is the recommended approach for production — it's more token-efficient than tools() because the agent only loads documentation for skills it actually needs.

const { systemPrompt, tools } = await client.skills({ cache: 300 });
// systemPrompt: string — lists available skills for the LLM
// tools: { loadSkill: Tool, apiCall: Tool }

Use it with streamText:

const { systemPrompt, tools: skillTools } = await client.skills({ cache: 300 });

const result = streamText({
  model: yourModel,
  system: `You are a helpful assistant.\n\n${systemPrompt}`,
  messages,
  tools: skillTools,
});

How Skills Work

  1. The system prompt tells the LLM which skills are available (e.g., "Gmail", "Slack", "Calendar")
  2. The LLM calls loadSkill({ name: "Gmail" }) to get detailed API documentation
  3. The LLM calls apiCall({ method: "GET", path: "/api/v1/google/gmail/messages" }) to make authenticated requests

This two-step approach means the full API docs for every provider don't need to be in the context window — only the ones the agent actually uses.

Options

OptionTypeDescription
cacheboolean | numbertrue = 60s cache, number = custom TTL in seconds

client.me(options?)

Returns account information, connected integrations, and usage stats.

const me = await client.me({ cache: 60 });

Response

interface MeResponse {
  email: string | null;
  tier: string;
  usage: {
    current: number;
    limit: number; // -1 = unlimited (enterprise)
  };
  integrations: Array<{
    provider: string; // "google", "slack", etc.
    status: string;   // "active", "expired", etc.
  }>;
  dashboardUrl: string;
}

client.asAccount(externalId)

Returns a ScopedClient that automatically sends the X-Account-Id header on every request. Use this when acting on behalf of a connected account (the partner/platform pattern).

const userClient = client.asAccount('user_123');

// All requests include X-Account-Id: user_123
const tools = await userClient.tools({ cache: 300 });
const skills = await userClient.skills({ cache: 300 });
const me = await userClient.me();

ScopedClient

The scoped client has tools(), skills(), and me() — but not accounts or asAccount(). This prevents accidental nesting and keeps management operations on the parent client.

interface ScopedClient {
  readonly accountId: string;
  tools(options?: ToolFilterOptions): Promise<Record<string, Tool>>;
  skills(options?: SkillsOptions): Promise<SkillsResult>;
  me(options?: MeOptions): Promise<MeResponse>;
}

Each scoped client gets its own cache, separate from the parent. Scoped and unscoped calls return different data, so they don't share cache entries.

See the Partner Guide for end-to-end examples.

Tool Discovery

The client includes methods for searching and filtering tools. These return raw tool descriptors (with metadata.connected and relevance scores) — useful for building dynamic UIs, tool pickers, or letting users explore available integrations.

client.searchTools(query)

Fuzzy search across tool names and descriptions. Returns results ranked by relevance score (0–1):

const { tools, total } = await client.searchTools('send email');

for (const tool of tools) {
  console.log(tool.function.name, tool.score, tool.metadata.connected);
}
// gmail_send_message 0.42 true
// slack_send_message 0.3 false
// resend_send_email 0.6 false

client.toolsByProvider(provider)

Returns all tools for a specific provider (e.g. google, slack, linear, platform):

const { tools } = await client.toolsByProvider('google');
// All Google tools (Gmail, Calendar, Drive, Sheets, etc.)

client.toolsByService(service)

Returns all tools for a specific service (e.g. gmail, calendar, drive):

const { tools } = await client.toolsByService('gmail');
// gmail_list_messages, gmail_get_message, gmail_send_message, etc.

Response Types

import type { ToolSearchResponse, ToolListResponse, ScoredTool } from '@supyagent/sdk';

// searchTools() returns ToolSearchResponse
interface ToolSearchResponse {
  tools: ScoredTool[]; // OpenAITool + score
  total: number;
}

// toolsByProvider() and toolsByService() return ToolListResponse
interface ToolListResponse {
  tools: OpenAITool[];
  total: number;
}

All discovery methods also work on scoped clients:

const userClient = client.asAccount('user_123');
const { tools } = await userClient.searchTools('calendar');

See the Cloud API Reference for the REST API endpoints and full response schema.

Caching

All three methods support caching to avoid redundant API calls:

// No cache (default) — fetches every time
await client.tools();

// 60-second cache
await client.tools({ cache: true });

// Custom TTL (5 minutes)
await client.tools({ cache: 300 });

In a typical Next.js API route, you create the client once at module scope and use caching to keep tools fresh without fetching on every request:

app/api/chat/route.ts
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });

export async function POST(req: Request) {
  // This hits Supyagent Cloud at most once every 5 minutes
  const { systemPrompt, tools } = await client.skills({ cache: 300 });
  // ...
}

What's Next