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

# Governed tools for the AI SDK

> Let the host choose inference while mcprouter governs each tool execution.

# Governed tools for the AI SDK

> **Public documentation preview — incomplete.** The SDK and optional AI SDK peers remain private and unpublished. Direct host inference needs its own authorization; no live-provider integration is demonstrated here.

The optional `@surf-lab/mcprouter/ai-sdk` subpath requires the compatible private AI SDK peer described in [installation](/start/install). Your application selects the model for `generateText`; `policy.modelBindings` does **not** select or authorize this direct host inference. Start with the shared [servers and policy](/integrate/models-servers-policies) or your own appropriately scoped router.

## Dependency choice and package names

**The integration stays at `@surf-lab/mcprouter/ai-sdk` for both intended dependency choices.** It is part of `@surf-lab/mcprouter`, not a separate integration package. The planned opt-in replacements are **`@surf-lab/mcprouter-patch-ai`** for `ai` and **`@surf-lab/mcprouter-patch-openai-sdk`** for the `@ai-sdk/openai` provider. Neither selected name is a published, qualified release yet.

The intended default option reuses an application's supported upstream SDKs; the patched option explicitly replaces them through npm aliases while preserving the usual import names. Consumers should not need both sets. An alias changes what the whole app resolves under that dependency name, so existing app usage also needs testing. These are **planned options**, not currently interchangeable dependencies: the current manifest requires its exact private peer, and the tested upstream versions still fail the project's strict declaration check.

Read [installation and TypeScript limitations](/start/install#planned-default-or-patched-choice) before choosing dependencies. Importing this subpath does not install peers, apply patches, or select a provider. The example below targets the currently tested private graph; it does not prove support for arbitrary upstream versions or other providers.

## Build a governed ToolSet

```ts theme={null}
const router = createAppRouter();
const signal = AbortSignal.timeout(30_000);

try {
  const selected = await router.filterTools({
    prompt,
    tools: mcpServers,
    context: await getAuthenticatedContext(),
    limit: 5,
    signal,
  });

  const response = await generateText({
    model: assistantModel,
    prompt,
    tools: toAITools(router, selected, {
      getContext: () => getAuthenticatedContext(),
    }),
    abortSignal: signal,
    maxOutputTokens: 512,
    maxRetries: 0,
  });
  // Review full tool results only within trusted host code; do not log raw data.
  return response.toolResults.map(result => {
    if (result.dynamic) return { status: 'unexpected_dynamic_tool' };
    return { status: result.output.status, code: result.output.code };
  });
} finally {
  await router.close();
}
```

This is an **integration fragment**, not a standalone runnable example. `createAppRouter` and `mcpServers` are from the [configuration guide](/integrate/models-servers-policies); the host must additionally construct `assistantModel` with `createOpenAI(connection).chat(modelId)` or another compatible AI SDK language model. `generateText` comes from `ai` and `toAITools` from the optional subpath. `prompt` and `getAuthenticatedContext` are host inputs. `response.toolResults` contains the full host-visible outputs, so only an explicit status/code projection is returned above; even that needs host-approved handling. Obtain fresh trusted context for each tool invocation, not a user-claimed role. The host must approve model destinations, data exposure, costs, logging, step count and repeat-call policy separately. Model-visible tool descriptions and schemas may leave your trust boundary.

`toAITools` validates **bound** results from the same router; raw definitions do not become callable by being ranked. Each generated tool call goes through `router.call` with its captured snapshot, input validation, policy and approval. By default, model-visible output contains status/code/tool ID metadata; the host receives full execution results and should only opt into `toModelOutput` for an explicitly safe projection. One `generateText` call may yield tool calls without final prose and does **not** inherit `execute`'s one-call limit. Do not automatically repeat denied, pending-approval or unknown-effect operations.

For a full host-owned structure, repository maintainers can inspect `examples/code.ts`. No live inference, public package availability or publication approval is implied by these pages.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.