Skip to main content
A source is a unit of tool registration. Toolshed supports four source types, each with its own adapter that resolves a configuration into a set of tools.

Source types

OpenAPI

Fetches an OpenAPI/Swagger specification and auto-generates tools from each endpoint.
{
  "type": "openapi",
  "id": "billing-api",
  "namespace": "billing",
  "specUrl": "https://api.example.com/openapi.json",
  "auth": { "type": "bearer", "envVar": "BILLING_API_KEY" },
  "baseUrl": "https://api.example.com",
  "operationFilter": null
}
FieldTypeRequiredDescription
type"openapi"YesSource type
idstringYesUnique source ID
namespacestringYesTool path prefix
specUrlstringYesURL to the OpenAPI spec
authSourceAuthNoAuthentication config
baseUrlstringNoOverride base URL
operationFilterfunctionNo({ method, path, operationId? }) => boolean
Tool path generation: namespace.resource.action (e.g., billing.invoices.list). Action is derived from HTTP method: GET -> list/get, POST -> create, PUT -> update, PATCH -> patch, DELETE -> delete. Destructiveness: Derived from HTTP method. GET, HEAD, OPTIONS are safe; all others are destructive.

GraphQL

Introspects a GraphQL schema and generates tools from queries and mutations.
{
  "type": "graphql",
  "id": "cms-api",
  "namespace": "cms",
  "endpoint": "https://api.example.com/graphql",
  "auth": { "type": "bearer", "envVar": "CMS_API_KEY" },
  "headers": { "X-Custom": "value" }
}
FieldTypeRequiredDescription
type"graphql"YesSource type
idstringYesUnique source ID
namespacestringYesTool path prefix
endpointstringYesGraphQL endpoint URL
authSourceAuthNoAuthentication config
headersobjectNoAdditional HTTP headers
operationFilterfunctionNo({ name, type }) => boolean where type is "query" or "mutation"
Tool path generation: namespace.field_name (camelCase converted to snake_case). Destructiveness: Queries are safe, mutations are destructive.

MCP

Connects to an external MCP server and imports its tools.
{
  "type": "mcp",
  "id": "external-tools",
  "namespace": "external",
  "transport": {
    "type": "http",
    "url": "https://mcp.example.com",
    "headers": { "Authorization": "Bearer token" }
  }
}
FieldTypeRequiredDescription
type"mcp"YesSource type
idstringYesUnique source ID
namespacestringYesTool path prefix
transportobjectYes{ type: "http", url, headers? } or { type: "stdio", command, args?, env? }
authSourceAuthNoAuthentication config
Tool path generation: namespace.tool_name (spaces and non-alphanumeric characters converted to underscores). Destructiveness: Reads annotations.destructiveHint from MCP tool metadata.
Stdio transport is defined in the config schema but not yet implemented in the adapter.

Plugin

Wraps a hand-written definePlugin() result as a source for registry consistency.
{
  "type": "plugin",
  "id": "github",
  "namespace": "github",
  "pluginId": "github"
}
FieldTypeRequiredDescription
type"plugin"YesSource type
idstringYesUnique source ID
namespacestringYesTool path prefix
pluginIdstringYesID of the plugin to wrap

Authentication types

The auth field supports four types:
TypeFieldsDescription
oauth2provider, scopes?OAuth2 via Toolshed’s token vending
api_keyheader, envVar?API key sent as a custom header
bearerenvVar?Bearer token from environment variable
noneNo authentication needed

Registering via API

curl -X POST http://localhost:3000/api/registry/sources \
  -H "Authorization: Bearer $TOOLSHED_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "openapi",
    "id": "petstore",
    "namespace": "petstore",
    "specUrl": "https://petstore3.swagger.io/api/v3/openapi.json"
  }'
The server validates the config against SourceConfigSchema, calls resolveSource() to fetch and parse the spec, and registers all discovered tools in the catalog.