mcpField
A
action-creator

action-creator

github.com/anthropics生产力2.8k173 次安装33 周前更新
代码仓库

关于 action-creator

用于编写 TypeScript Action 模板的技能,将用户特定的邮件流程定义为可复用操作,并以聊天界面的按钮触发。适合需要自动化重复邮件任务或建立个性化邮件管理流程的用户。

主要功能

  1. 01生成 TypeScript Action 模板
  2. 02定义操作参数与元数据
  3. 03通过上下文方法处理邮件
  4. 04支持 AI 分析和后续操作
  5. 05返回执行结果并提供错误处理

适用场景

  1. 01创建特定客户的付款提醒操作
  2. 02将问题邮件转发给工程团队
  3. 03归档指定来源的新闻邮件
  4. 04在聊天中触发重复邮件流程

安装

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

$npx skills add https://github.com/anthropics/claude-agent-sdk-demos --skill action-creator

安装后在 Claude Code 中输入/action-creator确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

templates/
archive-old-newsletters.ts
forward-bug-report.ts
send-payment-reminder.ts

详细介绍

Action 创建器

创建 TypeScript 操作模板文件,用于定义可重复使用、面向特定用户的操作,用户可以在聊天界面中单击一次即可执行。

何时使用此技能

当用户想要:

  • 为特定工作流创建可重复使用的操作(“我经常需要向 ACME Corp 发送付款提醒”)
  • 为供应商/客户设置一键操作(“将错误转发给工程团队”)
  • 使用特定上下文自动处理重复性电子邮件任务(“归档来自 TechCrunch/Morning Brew 的新闻简报”)
  • 为业务流程构建个性化的电子邮件管理工具

与监听器的主要区别:操作由用户触发(在聊天中单击),监听器则由事件触发(自动执行)。

操作的工作方式

操作是位于 agent/custom_scripts/actions/ 中的 TypeScript 文件,文件会:

  1. 导出一个 config 对象,用于定义模板元数据和参数架构
  2. 导出一个 handler 函数,用于使用给定参数执行操作
  3. 使用 ActionContext 方法执行操作(电子邮件 API、发送电子邮件、调用 AI 等)

Agent 会在对话期间通过提供特定参数来创建操作实例,这些实例会以可单击按钮的形式显示在聊天中。

创建操作模板

1. 了解特定用户的工作流

解析用户的请求,确定:

  • 用户上下文:他们有哪些特定的供应商/客户/团队?
  • 操作:他们需要执行什么具体操作?(发送给 ACME Corp、转发给工程团队等)
  • 参数:每次执行时哪些内容会变化?(发票编号、优先级、存放天数)
  • 频率:他们会多久使用一次?
2. 编写操作模板文件

在 agent/custom_scripts/actions/ 中创建文件,并采用以下结构:

import type { ActionTemplate, ActionContext, ActionResult } from "../types";

export const config: ActionTemplate = {
  id: "unique_action_id",                    // kebab-case, user-specific
  name: "Human Readable Name",                // For UI display
  description: "What this action does",       // Explain the operation
  icon: "📨",                                 // Optional emoji icon
  parameterSchema: {
    type: "object",
    properties: {
      paramName: {
        type: "string",                      // or "number", "boolean"
        description: "Parameter description",
        enum: ["option1", "option2"],        // Optional: restrict values
        default: "defaultValue"              // Optional: default value
      }
    },
    required: ["paramName"]                  // List required parameters
  }
};

export async function handler(
  params: Record<string, any>,
  context: ActionContext
): Promise<ActionResult> {
  const { paramName } = params;

  context.log(`Starting action: ${config.name}`);

  try {
    // 1. Perform operations using context methods
    // 2. Use AI for intelligent processing if needed
    // 3. Update emails, send emails, etc.

    context.notify("Action completed successfully", {
      type: "success",
      priority: "normal"
    });

    return {
      success: true,
      message: "Action completed successfully",
      data: { /* optional structured data */ },
      refreshInbox: true  // Optional: refresh inbox after action
    };
  } catch (error: any) {
    context.log(`Action failed: ${error}`, "error");
    return {
      success: false,
      message: `Failed: ${error.message}`
    };
  }
}
3. 文件命名约定

使用能体现特定用户操作的 kebab-case 名称:

  • send-payment-reminder-to-acme.ts(而不是 send-email.ts)
  • forward-bugs-to-engineering.ts(而不是 forward-email.ts)
  • archive-newsletters-from-techcrunch.ts(而不是 archive-emails.ts)
  • summarize-weekly-updates-from-ceo.ts(而不是 summarize-emails.ts)

重要:模板应针对用户实际使用的工作流、供应商、团队和流程。

4. 可用的上下文方法

ActionContext 提供以下功能:

// Email API operations
const emails = await context.emailAPI.getInbox({ limit: 30, includeRead: false });
const results = await context.emailAPI.searchEmails({ from: "[email protected]" });
const results = await context.emailAPI.searchWithGmailQuery("from:sender after:2024/01/01");
const emails = await context.emailAPI.getEmailsByIds(["id1", "id2"]);
const email = await context.emailAPI.getEmailById("email-id");

// Direct email operations
await context.archiveEmail(emailId);
await context.starEmail(emailId);
await context.unstarEmail(emailId);
await context.markAsRead(emailId);
await context.markAsUnread(emailId);
await context.addLabel(emailId, "label-name");
await context.removeLabel(emailId, "label-name");

// Send emails
const result = await context.sendEmail({
  to: "[email protected]",
  subject: "Email subject",
  body: "Email body content",
  cc: "[email protected]",           // Optional
  bcc: "[email protected]",          // Optional
  replyTo: "[email protected]"     // Optional
});

// AI-powered processing
const analysis = await context.callAgent<ResultType>({
  prompt: "Analyze this email and extract key info...",
  systemPrompt: "You are an expert at...",  // Optional
  tools: ["Read", "WebSearch"],              // Optional
  maxTokens: 2000                            // Optional
});

// Session messaging (inject into chat)
context.addUserMessage("User said this");
context.addAssistantMessage("Assistant responds");
context.addSystemMessage("System notification");

// Notifications
context.notify("Operation completed", {
  priority: "high" | "normal" | "low",
  type: "info" | "success" | "warning" | "error"
});

// External API access
const response = await context.fetch("https://api.example.com/data");
const data = await response.json();

// Logging (visible in server logs)
context.log("Info message", "info");
context.log("Warning message", "warn");
context.log("Error message", "error");

操作结果

始终返回 ActionResult 对象:

return {
  success: true,                          // Required: boolean
  message: "Human-readable result",       // Required: string
  data: { key: "value" },                // Optional: structured data
  suggestedActions: [],                   // Optional: follow-up actions
  refreshInbox: true                      // Optional: refresh inbox
};

示例和模板

常见模式可参考以下模板文件:

最佳实践

  1. 特定用户的模板:创建针对用户实际使用的供应商、客户、团队和流程的模板
  2. 描述性命名:使用体现具体操作的名称(避免使用“send-email”这类通用名称)
  3. 丰富的参数架构:定义清晰的参数类型及其说明
  4. AI 驱动:使用 context.callAgent() 进行智能处理
  5. 错误处理:始终使用 try-catch 包装操作,并返回有意义的错误信息
  6. 清晰的消息:返回易于理解的成功/失败消息
  7. 幂等性:尽可能将处理函数设计为可安全重复运行
  8. 日志记录:使用 context.log() 进行调试和记录审计轨迹

参数架构指南

使用 JSON Schema 定义参数:

parameterSchema: {
  type: "object",
  properties: {
    // String parameter
    emailId: {
      type: "string",
      description: "Email ID to process"
    },

    // Number parameter with default
    daysOld: {
      type: "number",
      description: "Number of days old",
      default: 30
    },

    // Enum parameter (dropdown)
    priority: {
      type: "string",
      description: "Priority level",
      enum: ["P0 - Critical", "P1 - High", "P2 - Medium", "P3 - Low"]
    },

    // Boolean parameter
    sendNotification: {
      type: "boolean",
      description: "Send notification when complete"
    }
  },
  required: ["emailId", "priority"]  // List required params
}

创建文件

当用户请求创建操作模板时:

  1. 明确用户特定的上下文:

    • 他们的供应商、客户或团队有哪些?
    • 他们的具体工作流是什么?
    • 每次执行时哪些参数会变化?
  2. 在 agent/custom_scripts/actions/ 中编写 TypeScript 文件

  3. 使用 Write 工具创建文件,并包含:

    • 从 "../types" 导入正确的类型
    • 用户特定的配置(而非通用配置)
    • 包含所有必需字段的参数架构
    • 包含错误处理的处理器
    • 清晰的成功/失败消息
  4. 测试参数:确保定义了所有必需参数

  5. 向用户确认此操作符合其工作流

常见模式

1. 向特定收件人发送电子邮件

用户特定内容 → 使用模板撰写电子邮件 → 发送 → 返回结果

const body = `Hi ${recipientName},
Your invoice ${invoiceNumber} for ${amount} is ${daysPastDue} days past due...`;

await context.sendEmail({
  to: "[email protected]",
  subject: `Payment Reminder: Invoice ${invoiceNumber}`,
  body
});
2. 批量电子邮件操作

搜索电子邮件 → 筛选 → 对每封邮件执行操作 → 返回数量

const emails = await context.emailAPI.searchWithGmailQuery(query);
for (const email of emails) {
  await context.archiveEmail(email.messageId);
}
return { success: true, message: `Archived ${emails.length} emails` };
3. AI 驱动的电子邮件处理

获取电子邮件 → 调用 AI 进行分析 → 使用 AI 结果 → 执行操作 → 返回摘要

const email = await context.emailAPI.getEmailById(emailId);
const analysis = await context.callAgent({
  prompt: `Analyze this bug report: ${email.body}...`,
  maxTokens: 1000
});
await context.sendEmail({ to: "[email protected]", ... });
4. 增强型电子邮件转发

获取电子邮件 → AI 分析 → 撰写增强版转发邮件 → 发送 → 为原邮件添加标签

const email = await context.emailAPI.getEmailById(emailId);
const analysis = await context.callAgent({ /* analyze */ });
await context.sendEmail({
  to: "[email protected]",
  subject: `[${priority}] ${email.subject}`,
  body: `AI Analysis:\n${analysis}\n\nOriginal:\n${email.body}`
});
await context.addLabel(emailId, "FORWARDED");

类型导入

始终从正确的位置导入类型:

import type { ActionTemplate, ActionContext, ActionResult } from "../types";

// ActionTemplate: Template metadata and parameter schema
// ActionContext: Runtime context with all capabilities
// ActionResult: Return type for handler function

用户如何触发操作

创建操作模板后:

  1. Agent 发现模板:在对话过程中,Agent 会读取可用操作
  2. Agent 创建实例:Agent 会根据用户的具体情况提供参数
  3. 用户看到按钮:操作实例会以可点击按钮的形式显示在聊天中
  4. 用户点击:操作会使用预填参数执行
  5. 显示结果:聊天中会显示成功/失败消息

示例流程:

User: "I need to follow up on the ACME invoice"
Agent: [searches emails, finds Invoice #2024-001 is 15 days overdue]
Agent: Creates action instance with parameters:
  {
    templateId: "send_payment_reminder_acme",
    params: { invoiceNumber: "INV-2024-001", amount: "$5,000", daysPastDue: 15 }
  }
User: [sees button "Send payment reminder to ACME Corp for Invoice #2024-001"]
User: [clicks button]
Action: Executes, sends email, returns "Payment reminder sent to ACME Corp"

参考

完整规范:请参阅项目根目录中的 ACTIONS_SPEC.md,了解以下内容的完整详情:

  • 完整的类型定义
  • ActionsManager 实现
  • WebSocket 协议
  • 前端集成
  • 高级示例
  • 日志记录和审计跟踪

评论

支持 Markdown