mcpField
T
typespec-api-operations

typespec-api-operations

github.com/github开发40.5k8.8k 次安装今天更新
代码仓库

关于 typespec-api-operations

typespec-api-operations 是一项技能,用于为 Microsoft 365 Copilot 的现有 TypeSpec API 插件添加 REST 操作。内容涵盖 CRUD 模式、参数、确认机制、自适应卡片和测试提示词。

主要功能

  1. 01GET、POST、PATCH 和 DELETE 示例
  2. 02路径、查询、正文和标头参数
  3. 03确认机制与自适应卡片模式
  4. 04响应模型和错误响应
  5. 05路由与文档编写指南

适用场景

  1. 01为 TypeSpec API 添加 CRUD 操作
  2. 02定义筛选条件和条目标识符
  3. 03为破坏性操作添加确认
  4. 04通过提示词检查 Copilot API 操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill typespec-api-operations

安装后在 Claude Code 中输入/typespec-api-operations确认已加载。

详细介绍

添加 TypeSpec API 操作

为现有 Microsoft 365 Copilot 的 TypeSpec API 插件添加 RESTful 操作。

添加 GET 操作

简单 GET - 列出所有项目
/**
 * List all items.
 */
@route("/items")
@get op listItems(): Item[];
带查询参数的 GET - 筛选结果
/**
 * List items filtered by criteria.
 * @param userId Optional user ID to filter items
 */
@route("/items")
@get op listItems(@query userId?: integer): Item[];
带路径参数的 GET - 获取单个项目
/**
 * 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
/**
 * List items with adaptive card visualization.
 */
@route("/items")
@card(#{
  dataPath: "$",
  title: "$.title",
  file: "item-card.json"
})
@get op listItems(): Item[];

创建自适应卡片(appPackage/item-card.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}"
    }
  ]
}

添加 POST 操作

简单 POST - 创建项目
/**
 * 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
/**
 * 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;

添加 PATCH 操作

简单 PATCH - 更新项目
/**
 * 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
/**
 * 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;

添加 DELETE 操作

简单 DELETE
/**
 * Delete an item.
 * @param id The ID of the item to delete
 */
@route("/items/{id}")
@delete op deleteItem(@path id: integer): void;
带确认的 DELETE
/**
 * 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.
    """
  }
})
op deleteItem(@path id: integer): void;

完整 CRUD 示例

定义服务与模型
@service
@server("https://api.example.com")
@actions(#{
  nameForHuman: "Items API",
  descriptionForHuman: "Manage items",
  descriptionForModel: "Read, create, update, and delete items"
})
namespace ItemsAPI {
  
  // Models
  model Item {
    @visibility(Lifecycle.Read)
    id: integer;
    
    userId: integer;
    title: string;
    description?: string;
    status: "active" | "completed" | "archived";
    
    @format("date-time")
    createdAt: utcDateTime;
    
    @format("date-time")
    updatedAt?: utcDateTime;
  }

  model CreateItemRequest {
    userId: integer;
    title: string;
    description?: string;
  }

  model UpdateItemRequest {
    title?: string;
    description?: string;
    status?: "active" | "completed" | "archived";
  }

  // Operations
  @route("/items")
  @card(#{ dataPath: "$", title: "$.title", file: "item-card.json" })
  @get op listItems(@query userId?: integer): Item[];

  @route("/items/{id}")
  @card(#{ dataPath: "$", title: "$.title", file: "item-card.json" })
  @get op getItem(@path id: integer): Item;

  @route("/items")
  @post
  @capabilities(#{
    confirmation: #{
      type: "AdaptiveCard",
      title: "Create Item",
      body: "Creating: **{{ function.parameters.item.title }}**"
    }
  })
  op createItem(@body item: CreateItemRequest): Item;

  @route("/items/{id}")
  @patch
  @capabilities(#{
    confirmation: #{
      type: "AdaptiveCard",
      title: "Update Item",
      body: "Updating item #{{ function.parameters.id }}"
    }
  })
  op updateItem(@path id: integer, @body item: UpdateItemRequest): Item;

  @route("/items/{id}")
  @delete
  @capabilities(#{
    confirmation: #{
      type: "AdaptiveCard",
      title: "Delete Item",
      body: "⚠️ Delete item #{{ function.parameters.id }}?"
    }
  })
  op deleteItem(@path id: integer): void;
}

高级功能

多个查询参数
@route("/items")
@get op listItems(
  @query userId?: integer,
  @query status?: "active" | "completed" | "archived",
  @query limit?: integer,
  @query offset?: integer
): ItemList;

model ItemList {
  items: Item[];
  total: integer;
  hasMore: boolean;
}
标头参数
@route("/items")
@get op listItems(
  @header("X-API-Version") apiVersion?: string,
  @query userId?: integer
): Item[];
自定义响应模型
@route("/items/{id}")
@delete op deleteItem(@path id: integer): DeleteResponse;

model DeleteResponse {
  success: boolean;
  message: string;
  deletedId: integer;
}
错误响应
model ErrorResponse {
  error: {
    code: string;
    message: string;
    details?: string[];
  };
}

@route("/items/{id}")
@get op getItem(@path id: integer): Item | ErrorResponse;

测试提示词

添加操作后,使用以下提示词进行测试:

GET 操作:

  • “列出所有项目并以表格形式显示”
  • “显示用户 ID 1 的项目”
  • “获取项目 42 的详细信息”

POST 操作:

  • “为用户 1 创建标题为 'My Task' 的新项目”
  • “添加项目:标题 'New Feature',描述 'Add login'”

PATCH 操作:

  • “将项目 10 的标题更新为 'Updated Title'”
  • “将项目 5 的状态更改为 completed”

DELETE 操作:

  • “删除项目 99”
  • “移除 ID 为 15 的项目”

最佳实践

参数命名
  • 使用描述性参数名:userId 而不是 uid
  • 在各操作之间保持一致
  • 对筛选条件使用可选参数(?)
文档
  • 为所有操作添加 JSDoc 注释
  • 描述每个参数的作用
  • 记录预期的响应
模型
  • 对 id 等只读字段使用 @visibility(Lifecycle.Read)
  • 对日期字段使用 @format("date-time")
  • 对枚举使用联合类型:"active" | "completed"
  • 使用 ? 明确标记可选字段
确认
  • 始终为破坏性操作(DELETE、PATCH)添加确认
  • 在确认正文中显示关键详情
  • 对不可逆操作使用警告 emoji(⚠️)
自适应卡片
  • 保持卡片简洁且聚焦
  • 使用 ${if(..., ..., 'N/A')} 进行条件渲染
  • 为常见后续步骤添加操作按钮
  • 使用实际 API 响应测试数据绑定
路由
  • 使用 RESTful 约定:
    • GET /items - 列出
    • GET /items/{id} - 获取单个
    • POST /items - 创建
    • PATCH /items/{id} - 更新
    • DELETE /items/{id} - 删除
  • 将相关操作归入同一命名空间
  • 对分层资源使用嵌套路由

常见问题

问题:参数未在 Copilot 中显示

解决方案:检查参数是否正确使用了 @query、@path 或 @body 装饰

问题:自适应卡片未渲染

解决方案:验证 @card 装饰器中的文件路径,并检查 JSON 语法

问题:确认未出现

解决方案:确保 @capabilities 装饰器与 confirmation 对象格式正确

问题:模型属性未在响应中出现

解决方案:检查该属性是否需要 @visibility(Lifecycle.Read),如果应可写则移除该装饰

评论

支持 Markdown