> ## Documentation Index
> Fetch the complete documentation index at: https://docs.toolshed.philo.ventures/llms.txt
> Use this file to discover all available pages before exploring further.

# @toolshed/sdk

> Plugin and tool definition SDK.

The SDK package provides functions for defining plugins, tools, and sources.

## Exports

### `definePlugin(config): Plugin`

Creates a plugin with a manifest and handler registry.

```typescript theme={null}
import { definePlugin } from "@toolshed/sdk";

const plugin = definePlugin({
  id: "my-service",
  name: "My Service",
  description: "Tools for My Service",
  authProviders: [...],
  tools: [...],
});
```

**PluginConfig:**

| Field           | Type             | Required | Description              |
| --------------- | ---------------- | -------- | ------------------------ |
| `id`            | `string`         | Yes      | Unique plugin identifier |
| `name`          | `string`         | Yes      | Human-readable name      |
| `description`   | `string`         | Yes      | Plugin description       |
| `authProviders` | `AuthProvider[]` | Yes      | Authentication providers |
| `tools`         | `ToolConfig[]`   | Yes      | Tool definitions         |

**Returns:** `Plugin` object with:

* `manifest` -- serialized `PluginManifest` (Zod schemas converted to JSON Schema)
* `handlers` -- `Map<string, handler>` keyed by tool path

<Note>
  **Handlers are wrapped with Zod parsing.** `definePlugin` doesn't store the handler reference verbatim — it wraps it in `(ctx, input) => handler(ctx, tool.inputSchema.parse(input ?? {}))`. This means **schema defaults are applied** before your handler sees the input, and invalid input throws a Zod error before any side effects. If you write `inputSchema: z.object({ calendarId: z.string().default("primary") })` and the caller omits `calendarId`, your handler reads `"primary"`, not `undefined`. Tests that compare handler references for equality won't work — invoke through the wrapper.
</Note>

### `defineTool(config): ToolConfig`

Type-safe wrapper for tool definitions. Returns the config as-is with proper generic inference.

```typescript theme={null}
import { defineTool } from "@toolshed/sdk";
import { z } from "zod";

const myTool = defineTool({
  path: "my_service.items.list",
  name: "List Items",
  description: "List items",
  inputSchema: z.object({ limit: z.number().default(10) }),
  outputSchema: z.object({ items: z.array(z.string()) }),
  async handler(ctx, input) { ... },
});
```

### `defineSource(config): SourceConfig`

Type-safe wrapper for source configurations. Returns the config as-is.

```typescript theme={null}
import { defineSource } from "@toolshed/sdk";

const source = defineSource({
  type: "openapi",
  id: "petstore",
  namespace: "petstore",
  specUrl: "https://petstore.swagger.io/v2/swagger.json",
});
```

### `elicit(ctx, request): Promise<ElicitationResponse>`

Convenience wrapper for requesting user approval. Equivalent to calling `ctx.elicit(request)` directly.

```typescript theme={null}
import { elicit } from "@toolshed/sdk";

const response = await elicit(ctx, {
  toolPath: "my_service.items.delete",
  message: "Delete this item?",
  type: "approval",
});
```

### `SourceConfigSchema`

Zod discriminated union schema for validating source configurations. Validates `openapi`, `graphql`, `mcp`, and `plugin` source types.

## Type exports

`Plugin`, `PluginConfig`, `ToolConfig`, `Source`, `SourceAdapter`, `SourceConfig`, `SourceAuth`, `OpenAPISourceConfig`, `MCPSourceConfig`, `GraphQLSourceConfig`, `PluginSourceConfig`
