Skills — Single-Purpose Tools
Skills are atomic units of functionality. Each skill does exactly one thing: send an email, generate a PDF, create a JIRA ticket, enrich a lead record. They sit between raw Functions (general backend logic) and MCP Servers (multi-tool platform connectors) in the Aerostack hierarchy.
Skills are deployed as Cloudflare Workers and installed into Workspaces. Once installed, they are available to any bot, LLM client, or agent connected to that workspace — no additional configuration required.
How Skills Fit In
You deploy a skill once. You install it into one or more workspaces. Every consumer of that workspace — bots, Claude Desktop, Cursor, custom agents — can call it immediately.
Skills vs Functions vs MCP Servers
| Functions | Skills | MCP Servers | |
|---|---|---|---|
| Purpose | General backend logic | One tool, one job | Multi-tool platform connector |
| Tools exposed | 0 (raw HTTP) | 1 | Many (5-50+) |
| Example | Order processing pipeline | send-email | Stripe MCP (20+ tools) |
| Deploy command | aerostack deploy function | aerostack deploy skill | aerostack deploy mcp |
| Workspace role | Added as a tool | Added as a tool | Added as a server |
| Complexity | You define everything | Structured single tool | Full protocol implementation |
| Best for | Custom APIs, pipelines | Reusable atomic actions | Platform integrations |
When to use each:
- Function — you need a custom API, a multi-endpoint backend, or a pipeline that does not fit the single-tool model.
- Skill — you have one well-defined action that should be callable by any AI agent in the workspace.
- MCP Server — you are wrapping an external platform (Stripe, GitHub, Slack) and need to expose many related tools.
Use Cases
Single-purpose automation
Send a Slack alert, create a JIRA ticket, generate an invoice PDF, post to a Discord channel. One skill per action, composable across workspaces.
Workflow building block
Skills compose into multi-step bot workflows. A bot workflow might call validate-address, then calculate-shipping, then send-confirmation-email — each a separate skill.
Team utility toolkit
Build private skills for your organization: internal lookup tools, formatting utilities, data validation helpers. Install them into your team workspace and every team member’s AI tools can use them.
Bot capability extension
Need your bot to send emails? Install the send-email skill into the bot’s workspace. The bot can now call it — no code changes to the bot itself.
Cron-triggered actions
Skills can run on a schedule. A daily-digest skill aggregates data from your database and sends a summary. A weekly-report skill generates analytics and posts them to Slack.
Quick Example
A skill that sends a Slack notification:
// src/index.ts
interface Env {
SLACK_WEBHOOK_URL: string
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { channel, message } = await request.json<{
channel: string
message: string
}>()
if (!channel || !message) {
return Response.json(
{ error: 'channel and message are required' },
{ status: 400 }
)
}
const response = await fetch(env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ channel, text: message })
})
if (!response.ok) {
return Response.json(
{ error: 'Failed to send Slack message' },
{ status: 502 }
)
}
return Response.json({ success: true, channel })
}
}// aerostack.json
{
"name": "slack-notify",
"type": "skill",
"description": "Send a notification to a Slack channel",
"tool": {
"name": "send_slack_notification",
"description": "Sends a message to a specified Slack channel",
"input_schema": {
"type": "object",
"properties": {
"channel": {
"type": "string",
"description": "The Slack channel to send to (e.g. #alerts)"
},
"message": {
"type": "string",
"description": "The message text to send"
}
},
"required": ["channel", "message"]
}
}
}Deploy it, install it into a workspace, and any bot or LLM client connected to that workspace can send Slack notifications.
Platform Bindings
Skills have full access to the same edge runtime bindings as Functions:
| Binding | Access | Example |
|---|---|---|
| Database | env.DB | Store skill state, query data |
| Cache | env.CACHE | Cache expensive computations |
| Queue | env.QUEUE | Offload async work |
| AI | env.AI | Run LLM completions, embeddings |
| Vector Search | env.VECTORIZE | Semantic search |
| Storage | env.STORAGE | Store files (PDFs, images) |
Next Steps
- Create a skill — step-by-step guide with three complete examples
- Deploy and test — CLI deployment, dashboard setup, and local testing
- Publish to Hub — share your skill with the Aerostack community