Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.corsair.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Hosted SDK is generated from Corsair’s plugin catalog. That gives your editor autocomplete for plugin IDs, auth types, root credential fields, and tenant credential fields.
import {
  createClient,
  PluginIdSchema,
  InstanceDetailSchema,
  type PluginId,
  type PluginAuthTypes,
  type PluginAccountFields,
  type PluginIntegrationFields,
} from "@corsair-dev/app";

Plugin IDs

PluginId is a union of every plugin ID in the catalog.
import type { PluginId } from "@corsair-dev/app";

function installDefaultPlugin(pluginId: PluginId) {
  return inst.plugins.upsert(pluginId, { mode: "cautious" });
}

await installDefaultPlugin("slack");
await installDefaultPlugin("github");
You can validate external input with the matching Zod schema:
import { PluginIdSchema } from "@corsair-dev/app";

const pluginId = PluginIdSchema.parse(request.body.pluginId);
await inst.plugins.upsert(pluginId, { mode: "cautious" });

Auth types by plugin

PluginAuthTypes<T> narrows the auth type to what a selected plugin supports.
import type { PluginAuthTypes, PluginId } from "@corsair-dev/app";

async function installWithAuth<T extends PluginId>(
  pluginId: T,
  authType: PluginAuthTypes<T>,
) {
  await inst.plugins.upsert(pluginId, { authType });
}

await installWithAuth("github", "oauth_2");
await installWithAuth("linear", "api_key");
If you pass an unsupported auth type, TypeScript catches it before runtime.

Credential fields by plugin

Root fields are instance-level integration credentials. Account fields are tenant-level credentials.
import type {
  PluginAccountFields,
  PluginId,
  PluginIntegrationFields,
} from "@corsair-dev/app";

async function setRootCredential<T extends PluginId>(
  pluginId: T,
  field: PluginIntegrationFields<T> & string,
  value: string,
) {
  await inst.plugins.credentials.setRoot(pluginId, field, value);
}

async function setTenantCredential<T extends PluginId>(
  pluginId: T,
  field: PluginAccountFields<T> & string,
  value: string,
) {
  await tenant.plugins.credentials.set(pluginId, field, value);
}
This makes credential UIs safer. Your code can model each plugin’s setup requirements without hardcoding a separate field registry.

Runtime schemas

The package exports Zod schemas for API response shapes.
import {
  InstanceDetailSchema,
  McpApiKeyCreatedSchema,
  TenantSummarySchema,
} from "@corsair-dev/app";

const instance = InstanceDetailSchema.parse(rawInstance);
const tenant = TenantSummarySchema.parse(rawTenant);
const key = McpApiKeyCreatedSchema.parse(rawKey);
Common schemas include:
SchemaValidates
InstanceSummarySchemaInstance list items
InstanceDetailSchemaFull instance details
PluginStateSchemaInstalled plugin state
PermissionsDetailSchemaPermission mode and overrides
TenantSummarySchemaTenant metadata
McpApiKeyCreatedSchemaNewly created MCP key and one-time secret
McpConnectionInfoSchemaTenant MCP connection metadata
RuntimeStatusSchemaRuntime warm and database health state

Static catalog data

Use PLUGINS or PLUGINS_BY_ID for build-time plugin metadata.
import { PLUGINS, PLUGINS_BY_ID } from "@corsair-dev/app";

const pluginOptions = PLUGINS.map((plugin) => ({
  value: plugin.id,
  label: plugin.displayName,
  description: plugin.description,
}));

const slack = PLUGINS_BY_ID.slack;
console.log(slack.defaultAuthType);
Use the live hosted catalog when you want the server’s current view:
const { plugins } = await corsair.catalog.plugins.list();

Handling API errors

All non-2xx responses throw CorsairApiError.
import { CorsairApiError } from "@corsair-dev/app";

try {
  await inst.plugins.upsert("slack", { mode: "cautious" });
} catch (error) {
  if (error instanceof CorsairApiError) {
    console.error(error.status);
    console.error(error.code);
    console.error(error.message);
    console.error(error.details);
  }
}
CorsairApiError includes:
FieldMeaning
statusHTTP status code
codeMachine-readable error code from the API
messageHuman-readable error message
detailsOptional structured details, such as validation issues
Wrap SDK calls at your API boundary so product code gets consistent application errors.
import { CorsairApiError } from "@corsair-dev/app";

export async function withCorsairErrors<T>(operation: () => Promise<T>) {
  try {
    return await operation();
  } catch (error) {
    if (error instanceof CorsairApiError) {
      if (error.status === 401) {
        throw new Error("Corsair API key is invalid or missing");
      }

      if (error.status === 403) {
        throw new Error(`Corsair blocked the operation: ${error.message}`);
      }

      throw new Error(`Corsair API error ${error.code}: ${error.message}`);
    }

    throw error;
  }
}

Regenerating types

The SDK’s generated file is produced from the plugin catalog. When the catalog changes inside the repo, regenerate before publishing the package.
pnpm --filter @corsair-dev/app gen
pnpm --filter @corsair-dev/app build
The generated surface includes:
  • PluginId
  • PluginAuthTypes<T>
  • PluginIntegrationFields<T>
  • PluginAccountFields<T>
  • PLUGINS
  • PLUGINS_BY_ID
  • Zod schemas for API responses