Skip to main content

Integration SDK Reference

API reference for @radarboard/integration-sdk — descriptors, auth, data sources, and testing utilities.

./types

TimeRange

Time range for dashboard queries. Duplicated to avoid circular dep on
type TimeRange = "today" | "7d" | "15d" | "30d" | "3m" | "1y" | "all"

IntegrationCategory

Integration category for grouping in the settings UI.
type IntegrationCategory = "revenue" | "deployment" | "analytics" | "monitoring" | "communication"

IntegrationOAuthConfig

OAuth-specific config for providers that need the redirect flow.
PropertyTypeDescription
providerstringProvider key used in route paths (e.g., “github”, “google”).
scopesstring[]Scopes to request during authorization.
setupInstructions?string | undefinedInstructions for creating the OAuth app, shown above client credential fields. Use as placeholder.
normalizeOrigin?boolean | undefinedWhether to normalize *.localhost subdomains to plain localhost when building the callback URL shown in setup instructions. Set true for Google (rejects custom subdomains), false/omit for GitHub (accepts *.localhost as-is).

IntegrationAuthField

A single credential input field in the integration’s Connection section.
PropertyTypeDescription
keystringStorage key within the credential record (e.g., “authToken”).
labelstringDisplay label (e.g., “Auth Token”).
optional?boolean | undefinedWhether the field is optional in the generic save/test UI.
type"text" | "password" | "textarea" | "file"”password” = masked, “text” = visible, “textarea” = multi-line, “file” = file upload.
placeholder?string | undefinedPlaceholder text.
helpText?string | undefinedHelp text below the input.
accept?string | undefinedAccepted file extensions for type “file” (e.g., “.p8,.pem”).

IntegrationAuth

How an integration authenticates with its external API.
PropertyTypeDescription
idstringUnique service identifier used as credential storage key.
namestringDisplay name for this service (e.g., “Vercel”, “Linear”).
type"api_key" | "oauth" | "none"Auth method: “api_key” = manual token entry, “oauth” = OAuth redirect flow, “none” = no auth.
fields?IntegrationAuthField[] | undefinedFor api_key and oauth: fields to show in the credential input UI (client ID/secret for OAuth).
testEndpoint?string | undefinedAPI route path to test credentials (POST with ).
docsUrl?string | undefinedURL to the service’s docs for obtaining credentials.
oauth?IntegrationOAuthConfig | undefinedOAuth-specific config. Required when type === “oauth”.

IntegrationMcpCredentialBinding

Maps a saved integration credential field to an MCP server auth mechanism.
PropertyTypeDescription
sourceFieldstringSaved integration credential field to reuse, e.g. “accessToken”.
target{ type: "authHeader"; } | { type: "env"; key: string; }MCP target field that receives the resolved value.
template?string | undefinedOptional template applied after resolution. Use "" as the placeholder.

IntegrationMcpTransportPresetBase

Base type for MCP transport presets.
PropertyTypeDescription
typeMcpTransportType

IntegrationMcpHttpTransportPreset

MCP transport preset for Streamable HTTP servers. Extends: IntegrationMcpTransportPresetBase
PropertyTypeDescription
type"streamable-http"
urlstring

IntegrationMcpStdioTransportPreset

MCP transport preset for stdio-based servers (local process). Extends: IntegrationMcpTransportPresetBase
PropertyTypeDescription
type"stdio"
commandstring
args?string[] | undefined
cwd?string | undefined
env?Record<string, string> | undefined

IntegrationMcpTransportPreset

Union of supported MCP transport presets.
type IntegrationMcpTransportPreset = IntegrationMcpHttpTransportPreset | IntegrationMcpStdioTransportPreset

IntegrationMcpConnectionConfig

Configuration for connecting an integration to an MCP server.
PropertyTypeDescription
serverNamestringCanonical MCP server name stored as mcp::<serverName>.
aliases?string[] | undefinedOptional alternate stored names that should also map back to this integration.
docsUrl?string | undefinedURL to server docs or homepage for assistant access setup.
transportIntegrationMcpTransportPresetDefault server transport and non-secret fields.
credentialBindings?IntegrationMcpCredentialBinding[] | undefinedSaved credential bindings applied to auth headers or env vars at runtime.

IntegrationMcpTool

MCP tool definition for an integration.
PropertyTypeDescription
namestringTool name — auto-namespaced as &lt;integrationId&gt;__&lt;name&gt;.
descriptionstringDescription shown to LLMs — must be clear and actionable.
parametersz.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>Zod schema for validated input parameters.
execute(params: unknown) => Promise<unknown>Execute the tool with validated params.

IntegrationEvent

A notification event produced by a webhook or delta detector. Matches EmitNotificationInput from
PropertyTypeDescription
sourcestring
sourceEventId?string | null | undefined
typestring
severity"critical" | "warning" | "info" | "success"
projectSlug?string | null | undefined
titlestring
body?string | null | undefined
metadata?Record<string, unknown> | undefinedArbitrary JSON. For in-app notification deep links, include an http(s) URL under url, permalink, html_url, or any nested key whose name contains url / link / href / permalink. Plain URLs in body or title are also detected.
occurredAt?number | undefined

WebhookHandler

Inbound webhook handler — lives in each integration’s webhook.ts. The web app’s generic /api/webhooks/[integration] route delegates to this.

DeltaDetector

Delta detector — lives in each integration’s delta.ts. Called from API route handlers after fresh data is fetched. Returns events for items that are new or changed since last call.

CommonRouteParams

Standard query params every integration data route receives.
PropertyTypeDescription
projectSlugstring | null
rangeTimeRange
timeZonestring
forceRefreshboolean
Example:
// At runtime, params look like:
const params: CommonRouteParams = {
  projectSlug: "my-saas",
  range: "30d",
  timeZone: "America/New_York",
  forceRefresh: false,
};

DataSourceContext

App-level services injected into data-source fetch functions. Avoids circular deps between packages/integrations and apps/app.
PropertyTypeDescription
resolveCredential(key: string) => Promise<Record<string, string> | null>Resolve stored credentials by service key. Returns a flat record of credential fields (e.g. { authToken: "sk-..." }), or null if no credential is saved for the given key.
getProjectIntegrations() => Promise<Record<string, Record<string, Record<string, unknown>>>>Returns all project integration configs, keyed by projectSlug -> integrationId -> configKey -> value.
getAllProjects() => Promise<Array<{ slug: string; name: string; color: string; platforms: Array<{ id: string; name: string; integrations: Record<string, unknown>; }>; [k: string]: unknown; }>>
getMcpClient?((url: string, authHeader?: string) => { callToolJson: <T>(tool: string, args: Record<string, unknown>) => Promise<T>; }) | undefined
listMcpToolsByName?((name: string) => Promise<Array<{ name: string; inputSchema?: Record<string, unknown> | null; }>>) | undefined
callMcpToolJsonByName?(<T>(name: string, tool: string, args: Record<string, unknown>) => Promise<T>) | undefined
getGitHubStarHistoryRepo?(() => GitHubStarHistoryRepository) | undefined

DataSourceDescriptor

Declares a fetchable endpoint for an integration.
PropertyTypeDescription
actionstringAction slug used in the URL path, e.g. “data”, “projects”, “open-issues”.
descriptionstringHuman-readable description of this data source.
cacheTtlSecondsnumberCache TTL in seconds for withCache.
pollingSourceId?string | undefinedOptional shared polling family used to resolve configurable TTLs.
evictPrefixes?string[] | undefinedOptional prefix for in-memory cache eviction on force refresh.
buildCacheKey?((params: TParams & CommonRouteParams) => string) | undefinedBuild the cache key from params. Defaults to <integration>:<action>:<projectSlug>:<range>:<timeZone>.
parseParams?((searchParams: URLSearchParams) => Partial<TParams>) | undefinedParse integration-specific params from the URL search params.
fetch(params: TParams & CommonRouteParams, ctx: DataSourceContext) => Promise<TData>Fetch the data. Receives merged common + integration-specific params plus injected context.
delta?{ extractData: (data: TData) => unknown; detector: DeltaDetector<TData>; shouldDetect?: (data: TData) => boolean; } | undefinedOptional delta detection on fresh data.

IntegrationDescriptor

Describes an integration in the registry. Extends: ExtensionMeta
PropertyTypeDescription
idstringUnique identifier (kebab-case). Should match the key in PlatformIntegrations where applicable.
namestringDisplay name (e.g., “GitHub”, “Vercel”).
descriptionstringShort description of what this integration provides.
iconComponentType<{ className?: string; }>Icon component for the settings UI.
categoryIntegrationCategoryCategory for grouping in the settings panel.
authIntegrationAuthAuth configuration for this integration’s API.
mcp?IntegrationMcpConnectionConfig | undefinedOptional MCP connection metadata for integrations that can use either API or MCP.
defaultStatusPageUrl?string | undefinedSuggested public provider status page URL. Can be overridden in settings.
defaultRssFeedUrl?string | undefinedSuggested public RSS/Atom feed URL. Users may override this in settings.
apiDocsUrl?string | undefinedURL to the upstream API reference documentation.
mcpTools?IntegrationMcpTool[] | undefinedMCP tools provided by this integration.
capabilities?IntegrationCapability[] | undefinedShared widget capabilities this integration can satisfy. Each entry maps a capability ID to a concrete data-source action.
dataSources?DataSourceDescriptor<Record<string, unknown>, unknown>[] | undefinedData sources exposed by this integration for the unified /api/integrations/[id]/[action] route.
webhookHandler?WebhookHandler | undefinedInbound webhook handler for this integration (signature verification + payload parsing).
Example:
import { GitHubIcon } from "./icon";

const descriptor: IntegrationDescriptor = {
  id: "github",
  name: "GitHub",
  description: "Repositories, pull requests, and CI status",
  icon: GitHubIcon,
  category: "deployment",
  capabilities: [{ id: "stars", action: "stars" }],
  auth: { id: "github", name: "GitHub", type: "oauth", oauth: { provider: "github", scopes: ["repo"] } },
  dataSources: [openIssuesSource, pullRequestsSource],
};

Capability Governance

Radarboard now uses descriptor-level capabilities to map integrations into canonical widgets.
  • capabilities declares which shared product surface the integration can satisfy.
  • action must match a real DataSourceDescriptor.action.
  • requiredIntegrations on widgets remains an availability filter; capability ownership lives in integration and widget descriptors.
  • pnpm check:extensions warns when an integration declares a capability with no canonical widget owner, and when the canonical widget does not list the integration as a provider.

./registry

registerIntegration()

Register an integration descriptor. Call once per integration at app startup. Validates uniqueness, description length, and auto-populates the data source registry.
function registerIntegration(descriptor: IntegrationDescriptor): void

registerDataSources()

Register data sources for virtual integrations that don’t have a full IntegrationDescriptor (e.g. “shipping” aggregates Linear + GitHub + Vercel).
function registerDataSources(integration: string, dataSources: DataSourceDescriptor<any, any>[]): void

findDataSource()

Look up a data source by integration ID and action slug.
function findDataSource(integration: string, action: string): DataSourceDescriptor<any, any> | undefined

getIntegration()

Get a registered integration by ID, or undefined if not found.
function getIntegration(id: string): IntegrationDescriptor | undefined

getAllIntegrations()

Get all registered integration descriptors.
function getAllIntegrations(): IntegrationDescriptor[]

./routes

integrationRoute()

Build an integration data route path. All integration data is served via the unified route handler at /api/integrations/[integration]/[action]. This helper builds the URL so widgets and hooks don’t need to hardcode paths.
function integrationRoute(integration: string, action: string): string
Example: integrationRoute(“revenuecat”, “data”) // → “/api/integrations/revenuecat/data”

pluginRoute()

Build a plugin API route path.
function pluginRoute(plugin: string, action: string): string
Example: pluginRoute(“changelog”, “state”) // → “/api/plugins/changelog/state”

./testing

createMockDataSourceContext()

Create a mock DataSourceContext backed by an in-memory credential Map. Useful for testing integration data-source fetch functions.
function createMockDataSourceContext(credentials?: Record<string, Record<string, string>> | undefined): TrackedDataSourceContext

TrackedDataSourceContext

Extended DataSourceContext that records calls for test assertions. Extends: DataSourceContext
PropertyTypeDescription
credentialStoreMap<string, Record<string, string>>Direct access to the in-memory credential store for assertions.
resolvedCredentialKeysstring[]All credential keys requested via resolveCredential().
getProjectIntegrationsCallCountnumberNumber of times getProjectIntegrations() was called.
getAllProjectsCallCountnumberNumber of times getAllProjects() was called.
resetTracking() => voidReset all tracked state.