Reference

Plugins

Full catalog of built-in plugins with options and behaviour.

Plugin overview

PluginPackageDescription
llmPlugin@routecraft/aiRegister LLM providers for use with llm()
embeddingPlugin@routecraft/aiRegister embedding providers for use with embedding()
mcpPlugin@routecraft/aiStart an MCP server and register remote MCP clients

Core adapter defaults (cron, direct) are set via dedicated fields on CraftConfig, not via plugins. See Configuration and Merged Options.

llmPlugin

import { llmPlugin } from '@routecraft/ai'

Registers LLM provider credentials in the context store. Required when any capability uses llm(). Configure once; all llm() calls in the context share it.

import { llmPlugin } from '@routecraft/ai'
import type { CraftConfig } from '@routecraft/routecraft'

const config: CraftConfig = {
  plugins: [
    llmPlugin({
      providers: {
        anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
        openai: { apiKey: process.env.OPENAI_API_KEY },
      },
    }),
  ],
}

export default config

Options:

OptionTypeRequiredDescription
providersLlmPluginProvidersYesProvider credentials (at least one required)
defaultOptionsPartial<LlmOptions>NoDefault options applied to all llm() calls

Providers:

ProviderOptionsDescription
openai{ apiKey: string, baseURL?: string }OpenAI API
anthropic{ apiKey: string }Anthropic API
openrouter{ apiKey: string, modelId?: string }OpenRouter API
ollama{ baseURL?: string, modelId?: string }Local Ollama instance
gemini{ apiKey: string }Google Gemini API

See llm adapter for usage.

embeddingPlugin

import { embeddingPlugin } from '@routecraft/ai'

Registers embedding provider credentials in the context store. Required when any capability uses embedding(). Runs a teardown on context stop to release native ONNX resources (used by the huggingface provider).

import { embeddingPlugin } from '@routecraft/ai'
import type { CraftConfig } from '@routecraft/routecraft'

const config: CraftConfig = {
  plugins: [
    embeddingPlugin({
      providers: {
        openai: { apiKey: process.env.OPENAI_API_KEY },
      },
    }),
  ],
}

export default config

Options:

OptionTypeRequiredDescription
providersEmbeddingPluginProvidersYesProvider credentials (at least one required)
defaultOptionsPartial<EmbeddingOptions>NoDefault options applied to all embedding() calls

Providers:

ProviderOptionsDescription
huggingface{}Local ONNX inference, no API key required
ollama{ baseURL?: string }Local Ollama instance
openai{ apiKey: string, baseURL?: string }OpenAI embeddings API
mock{}Deterministic test vectors, for use in tests

See embedding adapter for usage.

mcpPlugin

import { mcpPlugin } from '@routecraft/ai'

Starts an MCP server so capabilities exposed with .from(mcp(...)) are reachable by external MCP clients. Also registers named remote MCP clients (HTTP or stdio subprocess) so capabilities can call external MCP servers by a short server id. Required when any capability uses mcp() as a source.

All tools from every source (local routes, stdio clients, HTTP clients) are collected into a unified McpToolRegistry stored in the context store under MCP_TOOL_REGISTRY.

import { mcpPlugin, jwt } from '@routecraft/ai'
import type { CraftConfig } from '@routecraft/routecraft'

const config: CraftConfig = {
  plugins: [
    mcpPlugin({
      transport: 'http',
      port: 3001,
      auth: jwt({ secret: process.env.JWT_SECRET! }),
      clients: {
        browser: {
          url: 'http://127.0.0.1:8089/mcp',
          auth: { token: process.env.BROWSER_MCP_TOKEN! },
        },
        search: { url: 'http://127.0.0.1:8090/mcp' },
        filesystem: {
          transport: 'stdio',
          command: 'npx',
          args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
        },
      },
      maxRestarts: 5,
      restartDelayMs: 1000,
      restartBackoffMultiplier: 2,
    }),
  ],
}

export default config

Options:

OptionTypeDefaultDescription
namestring'routecraft'Server name exposed in MCP metadata
versionstring'1.0.0'Server version
transport'http' | 'stdio''stdio'Transport protocol for the MCP server
portnumber3001HTTP port (http transport only)
hoststring'localhost'HTTP host (http transport only)
authMcpHttpAuthOptions--Auth for the HTTP endpoint (http transport only; see below)
toolsstring[] | (meta) => boolean--Allowlist of tool names to expose, or a filter function
clientsRecord<string, McpClientHttpConfig | McpClientStdioConfig>--Named remote MCP servers (see below)
maxRestartsnumber5Max automatic restarts for stdio clients before giving up
restartDelayMsnumber1000Initial delay before first restart attempt (ms)
restartBackoffMultipliernumber2Multiplier applied to delay on each successive restart
toolRefreshIntervalMsnumber60000Polling interval for HTTP client tool lists (0 = no polling)

HTTP server auth (McpHttpAuthOptions):

When auth is set and transport is 'http', every request to /mcp must include a valid Authorization: Bearer <token> header. The auth object requires a validator function that receives the raw bearer token and returns an AuthPrincipal on success or null to reject. The principal is made available on exchange headers so routes can read the caller's identity.

FieldTypeDescription
validator(token: string) => AuthPrincipal | null | Promise<AuthPrincipal | null>Validates the bearer token and returns the caller's identity, or null to reject with 401.

AuthPrincipal:

FieldTypeRequiredDescription
subjectstringYesUnique identifier for the caller (user ID, service name, API key ID)
schemestringYesAuth scheme used ('bearer', 'basic', 'api-key')
rolesstring[]NoAssigned roles
scopesstring[]NoGranted scopes / permissions
emailstringNoEmail address
namestringNoDisplay name
issuerstringNoToken issuer (JWT iss)
audiencestring[]NoIntended audience (JWT aud)
expiresAtnumberNoExpiry as epoch seconds (JWT exp)
claimsRecord<string, unknown>NoRaw claims / custom attributes

Built-in jwt() helper

The jwt() helper creates a validator that verifies JWT signatures, checks expiry, and maps standard claims to AuthPrincipal fields. Zero dependencies (uses node:crypto).

import { mcpPlugin, jwt } from '@routecraft/ai'

HMAC (HS256 / HS384 / HS512):

auth: jwt({ secret: process.env.JWT_SECRET! })

// Explicit algorithm
auth: jwt({ algorithm: 'HS384', secret: process.env.JWT_SECRET! })

RSA (RS256):

import fs from 'node:fs'

auth: jwt({
  algorithm: 'RS256',
  publicKey: fs.readFileSync('./public.pem', 'utf-8'),
})

Custom validator:

auth: {
  validator: async (token) => {
    const user = await db.verifyApiKey(token)
    if (!user) return null
    return { subject: user.id, scheme: 'api-key', roles: user.roles }
  },
}

HTTP client config (McpClientHttpConfig):

FieldTypeRequiredDescription
urlstringYesFull URL of the remote MCP server
authMcpClientAuthOptionsNoAuth credentials sent on every request to this server

McpClientAuthOptions:

FieldTypeDescription
tokenstring | string[] | (() => string | Promise<string>)Bearer token, array of tokens (round-robin), or provider function called per request
headersRecord<string, string>Additional request headers; overrides token if Authorization is set

Stdio client config (McpClientStdioConfig):

FieldTypeRequiredDescription
transport'stdio'YesMust be 'stdio' to select subprocess mode
commandstringYesExecutable to spawn (e.g. 'node', 'npx')
argsstring[]NoArguments passed to the command
envRecord<string, string>NoEnvironment variables for the child process
cwdstringNoWorking directory for the child process

Stdio clients are spawned when the context starts and stopped on teardown. If the subprocess exits unexpectedly, the plugin automatically restarts it with exponential backoff (restartDelayMs * restartBackoffMultiplier ^ attempt). The restart counter resets after a successful reconnection.

See Expose as MCP and Call an MCP for usage guides.


Plugins

How to write and register plugins.

Adapters reference

llm, embedding, and mcp adapter signatures and options.

Previous
CLI