Provider Skills are hosted, provider-managed capability bundles that the model loads on demand and runs inside the provider's server-side sandbox. You reference them by a skill ID; the provider handles installation and execution.
Not to be confused with @tanstack/ai-code-mode-skills, which are locally-generated TypeScript functions evaluated client-side. Provider Skills run entirely on the provider's infrastructure.
Skills are inert without an execution tool. The execution tool activates the sandbox; skills are additional bundles that run inside it:
You already have a chat() call working. By the end of this page you will have attached a hosted skill to the right execution tool, with the provider handling the rest.
npm install @tanstack/ai-anthropicnpm install @tanstack/ai-anthropicImport codeExecutionTool from @tanstack/ai-anthropic/tools, not from the adapter root. Pass a skills array as the second argument.
import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { codeExecutionTool } from '@tanstack/ai-anthropic/tools'
export async function POST(request: Request) {
const { messages } = await request.json()
const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
tools: [
codeExecutionTool(
{ type: 'code_execution_20250825', name: 'code_execution' },
{
skills: [{ type: 'anthropic', skill_id: 'pptx', version: 'latest' }],
},
),
],
})
return toServerSentEventsResponse(stream)
}import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { codeExecutionTool } from '@tanstack/ai-anthropic/tools'
export async function POST(request: Request) {
const { messages } = await request.json()
const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
tools: [
codeExecutionTool(
{ type: 'code_execution_20250825', name: 'code_execution' },
{
skills: [{ type: 'anthropic', skill_id: 'pptx', version: 'latest' }],
},
),
],
})
return toServerSentEventsResponse(stream)
}The adapter automatically:
You do not set beta headers manually.
Each entry in the skills array is an AnthropicContainerSkill:
| Field | Type | Required | Notes |
|---|---|---|---|
| type | 'anthropic' | 'custom' | yes | 'anthropic' for Anthropic-hosted skills; 'custom' for your own bundles. |
| skill_id | string | yes | 1–64 characters. |
| version | string | no | Specific version string, or 'latest' (default when omitted). |
Up to 8 skills per request. The factory throws at call time if you exceed this or supply an invalid skill_id.
Setting skills via modelOptions.container.skills is deprecated. Use codeExecutionTool(config, { skills }) instead — the legacy path bypasses the automatic beta-header wiring.
The OpenAI shellTool accepts an environment object that can carry a skills array. This is Responses API only; the Chat Completions API does not support the shell tool.
npm install @tanstack/ai-openainpm install @tanstack/ai-openaiimport { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { shellTool } from '@tanstack/ai-openai/tools'
export async function POST(request: Request) {
const { messages } = await request.json()
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
tools: [
shellTool({
environment: {
type: 'container_auto',
skills: [
{ type: 'skill_reference', skill_id: 'skill_abc', version: '2' },
],
},
}),
],
})
return toServerSentEventsResponse(stream)
}import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { shellTool } from '@tanstack/ai-openai/tools'
export async function POST(request: Request) {
const { messages } = await request.json()
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
tools: [
shellTool({
environment: {
type: 'container_auto',
skills: [
{ type: 'skill_reference', skill_id: 'skill_abc', version: '2' },
],
},
}),
],
})
return toServerSentEventsResponse(stream)
}Each entry in the skills array is a SkillReference:
| Field | Type | Required | Notes |
|---|---|---|---|
| type | 'skill_reference' | yes | Always 'skill_reference' for OpenAI. |
| skill_id | string | yes | The skill identifier provided by OpenAI. |
| version | string | no | A positive integer as a string (e.g. '2') or 'latest'. |
Note: version is a string, not a number.
Only hosted, managed-by-id skills are wired by these factories:
Inline bundles, local-path references, and upload-API skill creation are not handled by codeExecutionTool or shellTool.