- MCP Server ToolsUpdated
- Managed MCP with chat()Updated
- Manual MCPUpdated
- MCP Type GenerationUpdated
- MCP Client InputUpdated
- MCP Server Tools: AdvancedNew
- MCP EventsNew
- MCP AppsUpdated
- Serve Tools over HTTPUpdated
- Serve Resources and PromptsUpdated
- Ask for InputUpdated
- Draft Text from a ToolUpdated
- MCP Server TasksUpdated
- MCP Server AuthUpdated
- MCP Server SessionsUpdated
- MCP Server on stdioUpdated
Persistence (Advanced)
- GenerationsUpdated
- Realtime Voice ChatUpdated
- Text-to-SpeechUpdated
- TranscriptionUpdated
- Transcription: AdvancedNew
- Voice CreationUpdated
- Audio RecordingUpdated
- Audio GenerationUpdated
- Image GenerationUpdated
- Image Generation: AdvancedNew
- Video GenerationUpdated
- Video Generation: AdvancedNew
- Live GenerationUpdated
- World GenerationUpdated
- Generation HooksUpdated
- OverviewUpdated
- Quick StartUpdated
- ProvidersUpdated
- HarnessesUpdated
- Harness AuthUpdated
- WorkspaceUpdated
- ToolsUpdated
- PolicyUpdated
- Lifecycle & SnapshotsUpdated
- Portable SnapshotsUpdated
- Keep Files After ReloadUpdated
- Save a Named VersionUpdated
- Branch From a VersionUpdated
- Send a Frozen FileUpdated
- Let the Agent Save and ForkUpdated
- Pick Which Files to KeepUpdated
- What a Snapshot StoresUpdated
- Instance DurabilityUpdated
- Durable RunsUpdated
- EventsUpdated
Sandboxes (Advanced)
- Runtime ContextUpdated
- Bring Your Own KeyUpdated
- Debug LoggingUpdated
- Multimodal ContentUpdated
- Files APIUpdated
- Per-Model Type SafetyUpdated
- Runtime Adapter SwitchingUpdated
- Tree-ShakingUpdated
- Extend AdapterUpdated
- Extend Adapter: AdvancedNew
- Typed Pre-Configured OptionsUpdated
- Test with a Fake ModelUpdated
- Prompt CachingUpdated
- Mid-Conversation ChangesUpdated
- Approval Flow ProcessingUpdated
Provider Skills
A provider skill is a hosted skill, such as a PowerPoint skill, that Anthropic or OpenAI runs in its own sandbox.
Attach the skill IDs to the execution tool of the provider. The provider installs the skills and runs them. You only give the IDs.
- Anthropic: attach skills to codeExecutionTool from @tanstack/ai-anthropic/tools.
- OpenAI: put skills inside shellTool from @tanstack/ai-openai/tools. This needs the Responses API.
A skill does nothing without its execution tool. The tool starts the sandbox, and the skills run inside it.
Portable vs hosted skills#
TanStack AI has two kinds of skills. Pick the one that fits:
- Portable skills (withSkills) show a catalog and let the model call load_skill. They work on any model that can call tools. They need no sandbox on the server, and they read SKILL.md from a folder, a bundle, or your own store. Start with these.
- Hosted skills (this page) run in the sandbox of the provider, by ID. They work with one provider only, and they need an execution tool. The provider runs them.
If you need the sandbox of the provider, for example to run code or make files, use hosted skills. For everything else, use portable skills.
Use only one kind in a chat() call. If you attach hosted skills to a code_execution or shell tool and also add withSkills, the middleware throws. The reason: the model gets two catalogs and two protocols.
Anthropic: skills on codeExecutionTool#
1. Install the package#
npm i @tanstack/ai-anthropicpnpm add @tanstack/ai-anthropicyarn add @tanstack/ai-anthropicbun add @tanstack/ai-anthropic2. Add codeExecutionTool with skills#
Import codeExecutionTool from @tanstack/ai-anthropic/tools, not from the root of the adapter. Pass a skills array as the second argument:
import {
chat,
chatParamsFromRequest,
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, threadId, runId } = await chatParamsFromRequest(request)
const stream = chat({
adapter: anthropicText('claude-opus-5-5'),
messages,
threadId,
runId,
tools: [
codeExecutionTool(
{ type: 'code_execution_20250825', name: 'code_execution' },
{
skills: [{ type: 'anthropic', skill_id: 'pptx', version: 'latest' }],
},
),
],
})
return toServerSentEventsResponse(stream)
}3. Try it#
Ask your chat "Make a three-slide deck about our Q3 results." The model loads the pptx skill and makes the file in the sandbox of Anthropic.
The adapter does the setup for you:
- It moves your skills into the top-level container.skills parameter of the request. The Anthropic API wants them there.
- It adds the code-execution-2025-08-25 beta header. When skills are present, it also adds the skills-2025-10-02 beta header.
You do not set beta headers yourself.
Skill shape#
Each item in the skills array is an AnthropicContainerSkill:
| Field | Type | Required | Notes |
|---|---|---|---|
| type | 'anthropic' | 'custom' | yes | 'anthropic' for skills that Anthropic hosts. 'custom' for your own bundles. |
| skill_id | string | yes | 1 to 64 characters. |
| version | string | no | A version string, or 'latest'. The default is 'latest'. |
You can attach at most 8 skills to a request. If you pass more, or a skill_id that is not valid, the factory throws when you call it.
OpenAI: skills in shellTool (Responses API only)#
The OpenAI shellTool takes an environment object, and that object can hold a skills array. This works only with the Responses API. The Chat Completions API does not support the shell tool.
1. Install the package#
npm i @tanstack/ai-openaipnpm add @tanstack/ai-openaiyarn add @tanstack/ai-openaibun add @tanstack/ai-openai2. Add shellTool with skills#
import {
chat,
chatParamsFromRequest,
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, threadId, runId } = await chatParamsFromRequest(request)
const stream = chat({
adapter: openaiText('gpt-6.1-sol'),
messages,
threadId,
runId,
tools: [
shellTool({
environment: {
type: 'container_auto',
skills: [
{ type: 'skill_reference', skill_id: 'skill_abc', version: '2' },
],
},
}),
],
})
return toServerSentEventsResponse(stream)
}Replace skill_abc with the ID of your skill.
Skill shape#
Each item 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 ID that OpenAI gives you. |
| version | string | no | A positive integer as a string (for example '2'), or 'latest'. |
version is a string, not a number.
Advanced#
What these factories support#
The factories wire only hosted skills that you reference by ID:
- Anthropic: type: 'anthropic' or type: 'custom'.
- OpenAI: type: 'skill_reference'.
codeExecutionTool and shellTool do not handle inline bundles, local paths, or skill creation through the upload API.
Related pages#
- Portable Agent Skills: a catalog plus load_skill, on any model that can call tools.
- Provider Tools: all native provider tools, and the type guard that stops a tool on a model that does not support it.
- Anthropic: Advanced, codeExecutionTool
- OpenAI: Advanced, shellTool
Upgrade from 0.x#
modelOptions.container.skills is not in 1.0. Pass skills to codeExecutionTool(config, { skills }).