
Typespec Api Operations
Extend a Microsoft 365 Copilot TypeSpec API plugin with REST routes, parameters, and Adaptive Card bindings.
Overview
typespec-api-operations is an agent skill for the Build phase that adds GET, POST, PATCH, and DELETE TypeSpec operations with routing, parameters, and Adaptive Cards for Microsoft 365 Copilot API plugins.
Install
npx skills add https://github.com/github/awesome-copilot --skill typespec-api-operationsWhat is this skill?
- Patterns for GET list, filtered query, and path-parameter single-item reads
- POST, PATCH, and DELETE operation templates with routing conventions
- Adaptive Card `@card` decorator with `dataPath`, `title`, and `item-card.json` packaging
- Copy-paste TypeSpec snippets aligned to Microsoft 365 Copilot plugin structure
- Documents `appPackage/` card JSON alongside API operations
Adoption & trust: 8.5k installs on skills.sh; 34.6k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have a Copilot TypeSpec plugin skeleton but no clear patterns for REST operations, parameters, or card-backed list UI.
Who is it for?
Builders extending M365 Copilot declarative plugins who work in TypeSpec and need standard CRUD plus card examples in one pass.
Skip if: Teams not using TypeSpec or Microsoft 365 Copilot plugins, or those only needing generic OpenAPI without Copilot decorators.
When should I use this skill?
Add GET, POST, PATCH, and DELETE operations to a TypeSpec API plugin with proper routing, parameters, and adaptive cards.
What do I get? / Deliverables
Your plugin gains documented, copy-ready operation definitions and matching Adaptive Card files that agents can drop into the TypeSpec and app package.
- TypeSpec operation blocks with routes and parameters
- Adaptive Card JSON under appPackage when using @card
Recommended Skills
Journey fit
Work happens while wiring Copilot declarative API surfaces—operations and cards are integration artifacts, not launch or ops tasks. TypeSpec `@route`, `@get`, `@post`, and `@card` map external HTTP semantics into Copilot plugin contracts.
How it compares
Copilot TypeSpec operation recipes—not a generic OpenAPI generator or standalone MCP server.
Common Questions / FAQ
Who is typespec-api-operations for?
Solo and indie developers building or extending Microsoft 365 Copilot API plugins with TypeSpec who want REST operations and Adaptive Cards spelled out in agent-friendly snippets.
When should I use typespec-api-operations?
Use it during Build integrations when you are adding endpoints to a Copilot plugin—listing resources, filtering by query, fetching by ID, or attaching `@card` visualizations before you ship the app package.
Is typespec-api-operations safe to install?
It is procedural documentation for your repo; review the Security Audits panel on this Prism page and inspect the skill source before letting an agent edit TypeSpec or package files.
SKILL.md
READMESKILL.md - Typespec Api Operations
# Add TypeSpec API Operations Add RESTful operations to an existing TypeSpec API plugin for Microsoft 365 Copilot. ## Adding GET Operations ### Simple GET - List All Items ```typescript /** * List all items. */ @route("/items") @get op listItems(): Item[]; ``` ### GET with Query Parameter - Filter Results ```typescript /** * List items filtered by criteria. * @param userId Optional user ID to filter items */ @route("/items") @get op listItems(@query userId?: integer): Item[]; ``` ### GET with Path Parameter - Get Single Item ```typescript /** * Get a specific item by ID. * @param id The ID of the item to retrieve */ @route("/items/{id}") @get op getItem(@path id: integer): Item; ``` ### GET with Adaptive Card ```typescript /** * List items with adaptive card visualization. */ @route("/items") @card(#{ dataPath: "$", title: "$.title", file: "item-card.json" }) @get op listItems(): Item[]; ``` **Create the Adaptive Card** (`appPackage/item-card.json`): ```json { "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "body": [ { "type": "Container", "$data": "${$root}", "items": [ { "type": "TextBlock", "text": "**${if(title, title, 'N/A')}**", "wrap": true }, { "type": "TextBlock", "text": "${if(description, description, 'N/A')}", "wrap": true } ] } ], "actions": [ { "type": "Action.OpenUrl", "title": "View Details", "url": "https://example.com/items/${id}" } ] } ``` ## Adding POST Operations ### Simple POST - Create Item ```typescript /** * Create a new item. * @param item The item to create */ @route("/items") @post op createItem(@body item: CreateItemRequest): Item; model CreateItemRequest { title: string; description?: string; userId: integer; } ``` ### POST with Confirmation ```typescript /** * Create a new item with confirmation. */ @route("/items") @post @capabilities(#{ confirmation: #{ type: "AdaptiveCard", title: "Create Item", body: """ Are you sure you want to create this item? * **Title**: {{ function.parameters.item.title }} * **User ID**: {{ function.parameters.item.userId }} """ } }) op createItem(@body item: CreateItemRequest): Item; ``` ## Adding PATCH Operations ### Simple PATCH - Update Item ```typescript /** * Update an existing item. * @param id The ID of the item to update * @param item The updated item data */ @route("/items/{id}") @patch op updateItem( @path id: integer, @body item: UpdateItemRequest ): Item; model UpdateItemRequest { title?: string; description?: string; status?: "active" | "completed" | "archived"; } ``` ### PATCH with Confirmation ```typescript /** * Update an item with confirmation. */ @route("/items/{id}") @patch @capabilities(#{ confirmation: #{ type: "AdaptiveCard", title: "Update Item", body: """ Updating item #{{ function.parameters.id }}: * **Title**: {{ function.parameters.item.title }} * **Status**: {{ function.parameters.item.status }} """ } }) op updateItem( @path id: integer, @body item: UpdateItemRequest ): Item; ``` ## Adding DELETE Operations ### Simple DELETE ```typescript /** * Delete an item. * @param id The ID of the item to delete */ @route("/items/{id}") @delete op deleteItem(@path id: integer): void; ``` ### DELETE with Confirmation ```typescript /** * Delete an item with confirmation. */ @route("/items/{id}") @delete @capabilities(#{ confirmation: #{ type: "AdaptiveCard", title: "Delete Item", body: """ ⚠️ Are you sure you want to delete item #{{ function.parameters.id }}? This action cannot be undone. """ } })