# https://github.com/apify/apify-mcp-server 项目说明书

生成时间: 2026-05-21 17:02:07 UTC

## 目录

- [项目简介](#project-introduction)
- [系统架构](#system-architecture)
- [MCP 协议实现](#mcp-protocol-implementation)
- [Actor 工具系统](#actor-tools-system)
- [支付系统集成](#payment-systems)
- [存储管理](#storage-management)
- [遥测与监控](#telemetry-monitoring)
- [前端架构](#frontend-architecture)
- [组件库与 Widget](#widget-components)
- [开发环境配置](#development-setup)

<a id='project-introduction'></a>

## 项目简介

### 相关页面

相关主题：[系统架构](#system-architecture), [MCP 协议实现](#mcp-protocol-implementation), [开发环境配置](#development-setup)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apify/apify-mcp-server/blob/main/README.md)
- [src/resources/resource_service.ts](https://github.com/apify/apify-mcp-server/blob/main/src/resources/resource_service.ts)
- [res/algolia.md](https://github.com/apify/apify-mcp-server/blob/main/res/algolia.md)
- [res/mcp_resources_analysis.md](https://github.com/apify/apify-mcp-server/blob/main/res/mcp_resources_analysis.md)
- [res/patterns_for_simplification.md](https://github.com/apify/apify-mcp-server/blob/main/res/patterns_for_simplification.md)
- [src/web/index.html](https://github.com/apify/apify-mcp-server/blob/main/src/web/index.html)
- [DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md](https://github.com/apify/apify-mcp-server/blob/main/DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md)
</details>

# 项目简介

## 概述

Apify MCP Server 是 Apify 平台提供的 Model Context Protocol（MCP）服务器实现，用于将 Apify 的 Actor 和文档搜索能力以标准化的 MCP 协议接口暴露给 AI 助手使用。

该项目的主要目标是为 AI 助手提供一种标准化的方式来调用 Apify 平台上的各种服务，包括 Actor 搜索、Actor 详情获取、以及 Apify 文档的搜索和获取功能。

## 项目架构

### 核心架构图

```mermaid
graph TD
    subgraph "MCP 客户端"
        A[AI 助手 / Claude]
    end
    
    subgraph "Apify MCP Server"
        B[HTTP Streamable Server<br/>:3001]
        C[stdio Server]
        D[工具层 Tools]
        E[资源层 Resources]
        F[提示层 Prompts]
    end
    
    subgraph "Apify 平台"
        G[Actors API]
        H[Algolia 搜索]
        I[文档 API]
    end
    
    A -->|MCP 协议| B
    A -->|MCP 协议| C
    B --> D
    C --> D
    D --> G
    D --> H
    E -->|Widget 资源| I
    
    style B fill:#e1f5fe
    style C fill:#e1f5fe
```

### 核心组件

| 组件 | 说明 | 源码位置 |
|------|------|----------|
| HTTP Streamable Server | 支持 HTTP 流式传输的 MCP 服务器 | `server.ts` |
| stdio Server | 标准输入输出的 MCP 服务器 | `stdio.ts` |
| 工具处理器 | 处理 MCP 工具调用 | `src/tools/` |
| 资源处理器 | 管理 MCP 资源读写 | `src/resources/` |
| Widget 系统 | 提供 UI Widget 组件 | `src/web/` |

资料来源：[README.md]()

## MCP 协议实现

### 支持的协议方法

Apify MCP Server 实现了完整的 MCP 协议规范，包括以下核心方法：

| 方法类别 | 支持的方法 | 状态 |
|----------|------------|------|
| 工具 Tools | `tools/list`, `tools/call` | ✅ 完全支持 |
| 资源 Resources | `resources/list`, `resources/read`, `resources/templates/list` | ✅ 已实现 |
| 提示 Prompts | `prompts/list`, `prompts/get` | ✅ 已实现 |
| 任务 Tasks | `tasks/list`, `tasks/get`, `tasks/cancel`, `tasks/result` | ✅ 已实现 |
| 日志 Logging | `logging/setLevel` | ✅ 已实现 |
| 通知 Notifications | `tools/list_changed`, `cancelled`, `progress` | ✅ 部分支持 |

资料来源：[res/mcp_resources_analysis.md]()

### 工具列表

MCP 服务器暴露以下主要工具供 AI 助手调用：

| 工具名称 | 功能描述 | 认证要求 |
|----------|----------|----------|
| `search-actors` | 搜索 Apify 平台上的 Actors | 无需认证 |
| `fetch-actor-details` | 获取指定 Actor 的详细信息 | 需要 API Token |
| `search-apify-docs` | 搜索 Apify 官方文档 | 无需认证 |
| `fetch-apify-docs` | 获取指定文档页面内容 | 无需认证 |

资料来源：[README.md]()

## 服务器部署模式

### HTTP Streamable 模式

HTTP Streamable 是推荐的部署方式，适用于生产环境和远程访问场景。

**启动命令：**

```bash
export APIFY_TOKEN="your-apify-token"
export APIFY_META_ORIGIN=STANDBY
apify run -p
```

服务默认运行在 `http://localhost:3001`，可通过 MCP Inspector 进行调试：

```bash
npx @modelcontextprotocol/inspector
```

资料来源：[README.md]()

### stdio 标准输入输出模式

stdio 模式适用于本地集成和命令行工具场景。

**启动命令：**

```bash
export APIFY_TOKEN="your-apify-token"
npx @modelcontextprotocol/inspector node ./dist/stdio.js
```

### 无认证访问

当 `tools` 查询参数仅包含允许无认证使用的工具时，托管服务器允许无 API Token 访问：

```
https://mcp.apify.com?tools=search-actors,fetch-actor-details,search-apify-docs,fetch-apify-docs
```

资料来源：[README.md]()

## Widget 系统

### 概述

项目包含一套完整的 Widget 系统，通过 MCP 资源的 `ui://widget/` URI 前缀提供。

**工作流程：**

```mermaid
sequenceDiagram
    participant Client as MCP 客户端
    participant Server as MCP Server
    participant FS as 文件系统
    
    Client->>Server: resources/read ui://widget/actor-search
    Server->>FS: 读取 widget JS 文件
    FS-->>Server: widget.js 内容
    Server->>Server: 包装为 HTML 页面
    Server-->>Client: HTML 资源内容
```

资料来源：[src/resources/resource_service.ts]()
资料来源：[res/mcp_resources_analysis.md]()

### 可用 Widget

| Widget | 文件路径 | 功能描述 |
|--------|----------|----------|
| Actor Search | `/dist/search-actors-widget.js` | Actor 搜索界面组件 |
| Actor Run | `/dist/actor-run-widget.js` | Actor 运行状态显示 |
| Actor Detail | `/dist/actor-detail-widget.js` | Actor 详情展示 |

资料来源：[src/web/index.html]()

### Widget 开发规范

Widget 开发需遵循以下设计系统规范：

**样式规范：**

```typescript
// ✅ 使用主题 token
color: ${theme.color.primary.action}
padding: ${theme.space.space8}

// ❌ 禁止硬编码值
color: '#1976d2'
padding: '8px'
```

**组件导入规范：**

```typescript
// ✅ 从 ui-library 导入
import { Button, Badge, Chip } from '@apify/ui-library';

// ❌ 禁止创建重复组件
// ❌ 禁止使用相对路径导入
```

资料来源：[DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md]()

## 文档搜索集成

### Algolia 搜索处理

项目使用 Algolia 作为文档搜索的后端，对搜索结果进行了标准化处理：

**响应处理示例：**

```json
// 原始 Algolia 响应
{
  "url_without_anchor": "https://docs.apify.com/platform/actors",
  "anchor": "actors-overview",
  "content": "Actors are serverless cloud programs..."
}

// 处理后结果
{
  "url": "https://docs.apify.com/platform/actors#actors-overview",
  "content": "Actors are serverless cloud programs that can perform anything..."
}
```

资料来源：[res/algolia.md]()

### 特殊处理规则

- **Apify 文档**：支持带锚点的 URL 片段，可访问同一页面的不同章节
- **Crawlee 文档**：不提供 content 字段，仅返回 URL

资料来源：[res/algolia.md]()

## 内部工具架构

### 工具参数传递

项目采用统一的 `InternalToolArgs` 类型传递工具执行所需的上下文信息：

```typescript
type InternalToolArgs = {
    args: Record<string, unknown>;      // 工具参数
    extra: RequestHandlerExtra;        // MCP 请求上下文
    apifyMcpServer: ActorsMcpServer;   // 服务器实例
    mcpServer: Server;                 // MCP 协议服务器
    apifyToken: string;                // 认证令牌
    userRentedActorIds?: string[];     // 用户租用的 Actor
    progressTracker?: ProgressTracker; // 进度追踪器
};
```

资料来源：[res/patterns_for_simplification.md]()

## 构建与部署

### 构建流程

```bash
# 安装依赖
pnpm install

# 构建项目
pnpm run build
```

### 开发服务器

项目提供开发服务器用于本地测试：

- HTTP Streamable：`dev_server.ts`
- 支持会话管理和进度追踪

资料来源：[res/integration_test_coverage_audit.md]()

## 相关文档

- [贡献指南](./CONTRIBUTING.md) - 代码规范和提交流程
- [集成测试覆盖审计](./res/integration_test_coverage_audit.md) - 测试状态报告
- [MCP 资源分析](./res/mcp_resources_analysis.md) - 资源处理详细说明
- [设计系统规范](./DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md) - UI 组件开发指南

---

<a id='system-architecture'></a>

## 系统架构

### 相关页面

相关主题：[项目简介](#project-introduction), [MCP 协议实现](#mcp-protocol-implementation), [前端架构](#frontend-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/index.ts](https://github.com/apify/apify-mcp-server/blob/main/src/index.ts)
- [src/index_internals.ts](https://github.com/apify/apify-mcp-server/blob/main/src/index_internals.ts)
- [src/mcp/server.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/server.ts)
- [src/mcp/client.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/client.ts)
- [src/state.ts](https://github.com/apify/apify-mcp-server/blob/main/src/state.ts)
- [src/resources/resource_service.ts](https://github.com/apify/apify-mcp-server/blob/main/src/resources/resource_service.ts)
</details>

# 系统架构

## 概述

Apify MCP Server 是一个基于 Model Context Protocol (MCP) 的服务器实现，旨在为 AI 模型提供访问 Apify 平台能力的标准化接口。该服务器通过 MCP 协议暴露工具（Tools）、资源（Resources）、提示（Prompts）和任务（Tasks）等能力，使 AI 代理能够与 Apify 平台进行交互。

## 核心架构组件

```mermaid
graph TB
    subgraph "客户端层"
        MCP_Client["MCP Client SDK"]
        AI_Agent["AI Agent"]
    end
    
    subgraph "服务器层"
        Server["MCP Server"]
        Transport["Transport Layer"]
        Handler["Request Handler"]
    end
    
    subgraph "服务层"
        Tools["Tools Service"]
        Resources["Resources Service"]
        Prompts["Prompts Service"]
        Tasks["Tasks Service"]
    end
    
    subgraph "Apify 平台"
        APIFY_API["Apify API"]
        Actors["Actors"]
        Docs["Apify Docs"]
        Search["Algolia Search"]
    end
    
    MCP_Client -->|MCP Protocol| Transport
    AI_Agent -->|LLM Requests| MCP_Client
    Transport --> Handler
    Handler --> Tools
    Handler --> Resources
    Handler --> Prompts
    Handler --> Tasks
    Tools --> APIFY_API
    Resources --> Widgets
    Prompts -->|预定义模板| APIFY_API
    Tasks --> Actors
```

## 传输层架构

### 支持的传输方式

| 传输类型 | 描述 | 配置方式 |
|---------|------|----------|
| stdio | 标准输入输出传输，适用于本地 CLI 工具 | `node ./dist/stdio.js` |
| Streamable HTTP | HTTP 流式传输，适用于 Web 服务 | `apify run -p` (端口 3001) |
| Server-Sent Events | 服务器推送事件，用于实时通知 | 与 HTTP 传输配合使用 |

MCP 服务器支持多种传输层实现，核心服务器代码位于 `src/mcp/server.ts`，负责处理来自不同客户端的请求并路由到相应的服务处理程序。

### 会话管理

Streamable HTTP 传输实现了完整的会话管理机制：

- 会话标识通过 `Mcp-Session-Id` HTTP 头传递
- 支持会话终止的 `DELETE /` 端点
- 每个会话维护独立的上下文状态

## 工具服务架构

### 工具注册与发现

```mermaid
graph LR
    Server_Start["服务器启动"] --> Load_Tools["加载工具定义"]
    Load_Tools --> Register["注册到 MCP Server"]
    Register --> List_Tools["tools/list"]
    Client_Request["客户端请求"] --> List_Tools
    List_Tools --> Tool_Meta["返回工具元数据<br/>包含 ui.* 属性用于 MCP Apps"]
```

### 核心工具列表

| 工具名称 | 功能描述 | 认证要求 |
|---------|---------|---------|
| `search-actors` | 搜索 Apify Actors | 可选 |
| `fetch-actor-details` | 获取 Actor 详细信息 | 可选 |
| `search-apify-docs` | 搜索 Apify 文档 | 可选 |
| `fetch-apify-docs` | 获取文档内容 | 可选 |
| `add-actor` | 添加 Actor | 必需 |
| 其他动态工具 | 根据配置动态注册 | 必需 |

资料来源：[res/integration_test_coverage_audit.md](https://github.com/apify/apify-mcp-server/blob/main/res/integration_test_coverage_audit.md)

### 工具调用流程

```mermaid
sequenceDiagram
    participant Client
    participant Server
    participant Tools
    participant ApifyAPI
    
    Client->>Server: tools/call
    Server->>Tools: 路由请求
    Tools->>ApifyAPI: API 调用
    ApifyAPI-->>Tools: 响应数据
    Tools-->>Server: 处理结果
    Server-->>Client: 返回结果
    
    Note over Tools: AJV 验证输入参数
    Note over Server: 支持 progressToken 进度追踪
```

工具调用支持以下功能：

- **参数验证**：使用 AJV 进行 JSON Schema 验证
- **进度追踪**：通过 `progressToken` 发送 `notifications/progress`
- **错误处理**：返回 `isError: true` 的 content 类型
- **取消通知**：Streamable HTTP 模式下支持 `notifications/cancelled`

## 资源服务架构

### 资源类型

| 资源类型 | URI 模式 | 描述 |
|---------|---------|------|
| README | `file://readme.md` | 使用指南内容 |
| Widget | `ui://widget/*` | UI 小部件资源 |
| 动态资源 | 自定义 URI | 根据配置扩展 |

资源服务实现位于 `src/resources/resource_service.ts`，提供了以下核心功能：

```typescript
// 资源读取逻辑
readResource(uri) {
    if (uri === 'file://readme.md') {
        return Provider?.getUsageGuide?.() || '';
    }
    
    if (uri.startsWith('ui://widget/')) {
        return loadWidgetContent(uri);
    }
}
```

资料来源：[src/resources/resource_service.ts](https://github.com/apify/apify-mcp-server/blob/main/src/resources/resource_service.ts)

### Widget 服务

```mermaid
graph TD
    Widget_Request["ui://widget/* 请求"] --> Check_Registry["检查 Widget 注册表"]
    Check_Registry --> Widget_Exists{Widget 存在?}
    Widget_Exists -->|是| Read_File["读取 JS 文件"]
    Widget_Exists -->|否| Return_Error["返回错误信息"]
    Read_File --> Build_HTML["构建 HTML 包装"]
    Build_HTML --> Return_Widget["返回 Widget 内容<br/>mimeType: RESOURCE_MIME_TYPE"]
```

Widget 通过文件系统直接读取 JS 文件，并包装在 HTML 文档中返回给客户端。

## 状态管理

### 全局状态结构

```mermaid
graph LR
    State["全局状态"] --> Actors["Actor 缓存"]
    State --> Sessions["会话状态"]
    State --> Config["配置信息"]
    State --> APIFY["Apify 客户端实例"]
```

状态管理模块 `src/state.ts` 负责维护：

- **Actor 缓存**：已加载的 Actor 列表及其元数据
- **会话状态**：HTTP 会话标识与上下文映射
- **配置信息**：环境变量与服务端点配置
- **API 客户端**：Apify API 客户端单例

### 服务器模式

| 模式 | 描述 | 适用场景 |
|-----|------|---------|
| `APPS` | MCP Apps 集成模式 | 与 MCP Apps 平台配合使用 |
| 标准模式 | 默认 MCP 服务器 | 标准 MCP 客户端连接 |

模式检测影响以下行为：

- Widget 注册与加载
- 资源 URI 处理
- 特定于 Apps 的元数据注入

## 客户端集成

### 客户端架构

```mermaid
graph TB
    subgraph "MCP Client"
        Transport_Client["Transport"]
        Request_Queue["请求队列"]
        Response_Handler["响应处理器"]
    end
    
    MCP_Client -->|发送请求| Server
    Server -->|接收响应| MCP_Client
```

客户端实现位于 `src/mcp/client.ts`，提供了：

- **连接管理**：与 MCP 服务器建立和维护连接
- **请求序列化**：将调用序列化为 MCP 协议格式
- **响应解析**：解析服务器响应并返回给调用方

## Web Widget 系统

### Widget 类型

| Widget 名称 | 入口文件 | 用途 |
|------------|---------|------|
| Actor Search | `index-actor-search.html` | 搜索 Actors |
| Actor Run | `index-actor-run.html` | 展示 Actor 运行状态 |
| Actor Detail | `actor-detail.html` | 显示 Actor 详细信息 |

### Widget 加载流程

```mermaid
sequenceDiagram
    participant Browser
    participant HTML
    participant Bundle
    participant Component
    
    Browser->>HTML: 加载页面
    HTML->>Bundle: 加载 /dist/*.js
    Bundle->>Component: React 组件渲染
    Component->>Browser: 显示 Widget UI
```

开发预览页面 `src/web/index.html` 提供了所有可用 Widget 的访问入口。

## 模块依赖关系

```mermaid
graph TD
    Index["src/index.ts"] --> Index_Internals["src/index_internals.ts"]
    Index_Internals --> Server["src/mcp/server.ts"]
    Index_Internals --> State["src/state.ts"]
    Server --> Client["src/mcp/client.ts"]
    Server --> Resources["src/resources/resource_service.ts"]
    Server --> Tools["Tools Service"]
    Server --> Prompts["Prompts Service"]
    Server --> Tasks["Tasks Service"]
```

## 部署架构

### 服务启动流程

```mermaid
flowchart TD
    Start["启动命令"] --> Check_Mode{"检测模式"}
    Check_Mode -->|STDIO| Start_STDIO["初始化 STDIO 传输"]
    Check_Mode -->|HTTP| Start_HTTP["初始化 HTTP 传输"]
    Check_Mode -->|CLI| Start_CLI["CLI 交互模式"]
    
    Start_STDIO --> Register_Server["注册 MCP Handlers"]
    Start_HTTP --> Register_Server
    Start_CLI --> Register_Server
    
    Register_Server --> Load_Config["加载配置"]
    Load_Config --> Init_State["初始化状态"]
    Init_State --> Ready["服务器就绪"]
```

### 环境配置

| 环境变量 | 描述 | 必需 |
|---------|------|-----|
| `APIFY_TOKEN` | Apify API 访问令牌 | 对于受保护工具必需 |
| `APIFY_META_ORIGIN` | 请求来源标识 | 可选 |
| `PORT` | HTTP 服务端口 | HTTP 模式必需 |

未授权访问仅在 `tools` 查询参数仅包含明确允许的工具时可用（`search-actors`、`fetch-actor-details`、`search-apify-docs`、`fetch-apify-docs`）。

资料来源：[README.md](https://github.com/apify/apify-mcp-server/blob/main/README.md)

## 安全考虑

### 认证流程

```mermaid
graph LR
    Request["请求"] --> Check_Tool{"工具检查"}
    Check_Tool -->|公开工具| Allow["允许访问"]
    Check_Tool -->|受保护工具| Check_Auth{"认证检查"}
    Check_Auth -->|有效 Token| Allow
    Check_Auth -->|无效 Token| Deny["返回错误"]
```

### 错误处理

| 错误类型 | HTTP 状态 | 处理方式 |
|---------|----------|---------|
| AJV 验证失败 | JSON-RPC Error | 返回 InvalidParams |
| 未知工具名 | JSON-RPC Error | 错误码 -32601 |
| 认证失败 | 401 | 返回错误信息 |
| 禁止的 URL | 403 | 返回 isError: true |

## 扩展性设计

### 添加新工具

1. 在工具注册表中定义工具 schema
2. 实现工具处理函数
3. 注册到 MCP Server
4. 添加相应的测试用例

### 添加新资源

1. 实现 `readResource` 处理器
2. 在资源注册表中添加条目
3. 处理相应的 URI 模式

### 添加新 Widget

1. 在 `src/web/src/pages/` 中创建组件
2. 配置构建输出到 `/dist/`
3. 注册到 Widget 注册表
4. 添加 HTML 入口文件

---

<a id='mcp-protocol-implementation'></a>

## MCP 协议实现

### 相关页面

相关主题：[系统架构](#system-architecture), [Actor 工具系统](#actor-tools-system), [前端架构](#frontend-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/server.ts)
- [src/mcp/client.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/client.ts)
- [src/mcp/actors.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/actors.ts)
- [src/mcp/proxy.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/proxy.ts)
- [src/mcp/utils.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/utils.ts)
- [src/mcp/const.ts](https://github.com/apify/apify-mcp-server/blob/main/src/mcp/const.ts)
- [src/resources/resource_service.ts](https://github.com/apify/apify-mcp-server/blob/main/src/resources/resource_service.ts)
- [res/mcp_resources_analysis.md](https://github.com/apify/apify-mcp-server/blob/main/res/mcp_resources_analysis.md)
- [res/integration_test_coverage_audit.md](https://github.com/apify/apify-mcp-server/blob/main/res/integration_test_coverage_audit.md)
</details>

# MCP 协议实现

## 概述

Apify MCP Server 是 Apify 平台的 Model Context Protocol (MCP) 实现，为 LLM 提供与 Apify 平台交互的能力。该服务器基于 MCP TypeScript SDK 构建，支持多种传输协议和功能模块，使 AI 助手能够直接调用 Apify Actors、搜索文档、管理任务等操作。

项目采用模块化架构，核心实现位于 `src/mcp/` 目录下，包含服务器初始化、客户端代理、工具定义等关键组件。

## 架构设计

### 整体架构

```mermaid
graph TD
    A[MCP Client<br/>Claude Desktop/其他客户端] --> B[Transport Layer<br/>stdio / Streamable HTTP]
    B --> C[MCP Server<br/>server.ts]
    C --> D[Tool Handlers<br/>actors.ts]
    C --> E[Resource Handlers<br/>resource_service.ts]
    C --> F[Prompt Handlers<br/>prompts.ts]
    C --> G[Proxy Layer<br/>proxy.ts]
    D --> H[Apify API]
    G --> H
```

### 核心模块职责

| 模块 | 文件路径 | 职责 |
|------|----------|------|
| server.ts | `src/mcp/server.ts` | 服务器主入口，负责初始化 MCP Server 实例，注册各类处理器 |
| client.ts | `src/mcp/client.ts` | MCP 客户端封装，处理与远程 MCP 服务器的通信 |
| actors.ts | `src/mcp/actors.ts` | Actor 相关工具定义和执行逻辑 |
| proxy.ts | `src/mcp/proxy.ts` | 代理层实现，用于转发请求和中间处理 |
| utils.ts | `src/mcp/utils.ts` | 通用工具函数库 |
| const.ts | `src/mcp/const.ts` | 常量定义 |

资料来源：[res/mcp_resources_analysis.md]()

## 传输层支持

### stdio 传输模式

标准输入输出传输，适用于本地调试和 CLI 工具集成。

```bash
npx @modelcontextprotocol/inspector node ./dist/stdio.js
```

### Streamable HTTP 传输模式

支持 HTTP 流式传输，适用于 Web 服务和远程部署。

```bash
export APIFY_TOKEN="your-apify-token"
export APIFY_META_ORIGIN=STANDBY
apify run -p
```

服务器默认暴露在 `http://localhost:3001`。

资料来源：[README.md:1-50]()

## 工具实现 (Tools)

### 工具列表

MCP Server 通过 `tools/list` 端点暴露以下工具：

| 工具名称 | 功能描述 | 认证要求 |
|----------|----------|----------|
| `search-actors` | 搜索 Apify Actors | 公开可用 |
| `fetch-actor-details` | 获取指定 Actor 详情 | 公开可用 |
| `search-apify-docs` | 搜索 Apify 文档 | 公开可用 |
| `fetch-apify-docs` | 获取指定文档内容 | 需要认证 |
| `add-actor` | 添加/创建 Actor | 需要认证 |
| `run-actor` | 运行 Actor | 需要认证 |

资料来源：[res/integration_test_coverage_audit.md]()
资料来源：[README.md:35-40]()

### 工具调用流程

```mermaid
sequenceDiagram
    participant Client
    participant Server as MCP Server
    participant API as Apify API
    
    Client->>Server: tools/call { name, arguments }
    Server->>Server: AJV Validation
    alt Validation Failed
        Server-->>Client: InvalidParams Error
    else Validation Passed
        Server->>API: Execute Tool
        API-->>Server: Response
        Server->>Server: Format Result
        Server-->>Client: Tool Result
    end
```

### 工具元数据 (ui.*)

MCP Server 为 MCP Apps 模式提供扩展元数据，通过 `_meta` 字段包含 UI 相关信息：

```typescript
{
    contents: [{
        uri: 'tool://...',
        text: '...',
        _meta: {
            ui: {
                mode: 'openai',
                // 其他 UI 渲染信息
            }
        }
    }]
}
```

资料来源：[res/integration_test_coverage_audit.md]()

## 资源系统 (Resources)

### 资源类型

| 资源类型 | URI 前缀 | 描述 |
|----------|----------|------|
| Usage Guide | `file://readme.md` | 使用指南内容 |
| UI Widget | `ui://widget/` | 嵌入式 UI 组件 |

资料来源：[src/resources/resource_service.ts]()
资料来源：[res/mcp_resources_analysis.md]()

### 资源读取处理

```typescript
// 资源读取主流程
const readResource = async (uri: string): Promise<ReadResourceResult> => {
    // 1. 检查 usage guide
    if (uri === 'file://readme.md') {
        return { contents: [{ uri, mimeType: 'text/markdown', text: usageGuide }] };
    }
    
    // 2. 检查 UI widget
    if (uri.startsWith('ui://widget/')) {
        // 加载 widget JS 文件并包装为 HTML
    }
    
    // 3. 未找到资源
    return { contents: [{ uri, mimeType: 'text/plain', text: `Resource ${uri} not found` }] };
};
```

资料来源：[src/resources/resource_service.ts]()

### UI Widget 加载

Widget 资源读取流程：

1. 从 Widget 注册表获取 widget 元信息
2. 验证 widget 文件是否存在
3. 读取 widget JS 文件内容
4. 将 JS 包装在 HTML 模板中返回

```typescript
const widgetHtml = `<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>${widget.title}</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module">${widgetJs}</script>
  </body>
</html>`;
```

资料来源：[src/resources/resource_service.ts]()

## 任务系统 (Tasks)

### 任务端点

| 端点 | 描述 | 支持操作 |
|------|------|----------|
| `tasks/list` | 列出所有任务 | 同步流式响应 |
| `tasks/get` | 获取任务详情 | 包含状态消息 |
| `tasks/cancel` | 取消任务 | 即时终止 |
| `tasks/result` | 获取任务结果 | 返回执行结果 |

资料来源：[res/integration_test_coverage_audit.md]()

### 进度跟踪

MCP Server 支持通过 `progressToken` 进行实时进度通知：

```typescript
const createProgressTracker = (progressToken: ProgressToken) => {
    return {
        report: (progress: Progress) => {
            // 发送进度通知到客户端
        }
    };
};
```

## 提示系统 (Prompts)

### 可用提示

| 提示名称 | 描述 |
|----------|------|
| `GetLatestNewsOnTopic` | 获取指定主题的最新新闻 |

提示系统通过 `prompts/list` 和 `prompts/get` 端点暴露。

资料来源：[res/integration_test_coverage_audit.md]()

## 认证与授权

### 认证模式

1. **完整认证模式**：需要 `APIFY_TOKEN` 环境变量
2. **公开访问模式**：仅限特定工具

### 公开可用工具

以下工具在无认证情况下也可访问：

- `search-actors`
- `fetch-actor-details`
- `search-apify-docs`

资料来源：[README.md:42-46]()

### 托管服务器访问

托管服务器 (`https://mcp.apify.com`) 支持通过 `tools` 查询参数控制访问权限：

```
https://mcp.apify.com?tools=search-actors
```

## 日志系统

### 日志级别配置

通过 `logging/setLevel` 端点支持动态日志级别调整：

| 日志级别 | 用途 |
|----------|------|
| debug | 调试信息 |
| info | 一般信息 |
| warn | 警告信息 |
| error | 错误信息 |

日志系统支持消息过滤，根据设置的日志级别决定是否转发到客户端。

资料来源：[res/integration_test_coverage_audit.md]()

## 配置选项

### 环境变量

| 变量名 | 描述 | 必填 |
|--------|------|------|
| `APIFY_TOKEN` | Apify API 访问令牌 | 是（部分功能） |
| `APIFY_META_ORIGIN` | 请求来源标识 | 可选 |

### 服务器模式

| 模式 | 描述 |
|------|------|
| `ServerMode.APPS` | MCP Apps 模式，支持完整功能 |
| `ServerMode.DEFAULT` | 默认模式 |

## 错误处理

### 错误类型

| 错误场景 | 响应代码 | 说明 |
|----------|----------|------|
| 参数验证失败 | InvalidParams | AJV schema 验证失败 |
| 资源未找到 | NotFound | 指定的资源不存在 |
| Widget 不可用 | Error | Widget 文件不存在或注册表缺失 |
| API 调用失败 | ServerError | 底层 Apify API 返回错误 |

### Widget 错误处理

```typescript
try {
    const widgetJs = fs.readFileSync(widget.jsPath, 'utf-8');
    // 处理 widget 内容
} catch (error) {
    return {
        contents: [{
            uri,
            mimeType: 'text/plain',
            text: `Failed to load widget: ${errorMessage}`,
        }],
    };
}
```

## 测试覆盖

### 集成测试覆盖状态

| MCP 端点 | 测试状态 | 位置 |
|----------|----------|------|
| `tools/list` | ✅ 已覆盖 | server.ts:619 |
| `tools/call` | ✅ 已覆盖 | server.ts:633 |
| `resources/list` | ⚠️ 仅单元测试 | - |
| `resources/read` | ⚠️ 仅单元测试 | - |
| `tasks/*` | ✅ 已覆盖 | server.ts:524 |
| `prompts/*` | ✅ 部分覆盖 | server.ts:484 |
| `logging/setLevel` | ⚠️ 缺失 | - |
| `ping` | ⚠️ 缺失 | - |

资料来源：[res/integration_test_coverage_audit.md]()

## 扩展指南

### 添加新工具

1. 在 `src/mcp/actors.ts` 中定义工具 schema
2. 注册工具处理器
3. 添加对应的单元测试
4. 更新集成测试覆盖

### 添加新资源

1. 在 `resource_service.ts` 中扩展 `readResource` 函数
2. 如需列出资源，更新 `listResources` 函数
3. 添加资源类型的 MIME type 映射

### 注意事项

- **不要使用 `registerResource`**：本项目使用低级别 `Server` API，不使用 `Mc pServer` 高级 API
- **保持资源处理显式**：通过请求处理器管理资源，而非注册表模式
- **遵循现有模式**：参考现有组件结构和命名规范

资料来源：[res/mcp_resources_analysis.md]()
资料来源：[CONTRIBUTING.md]()

## 相关文档

- [官方 MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [MCP Inspector 调试工具](https://github.com/modelcontextprotocol/inspector)
- [Apify 平台文档](https://docs.apify.com)

---

<a id='actor-tools-system'></a>

## Actor 工具系统

### 相关页面

相关主题：[MCP 协议实现](#mcp-protocol-implementation), [存储管理](#storage-management), [支付系统集成](#payment-systems)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tools/actor_executor.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/actor_executor.ts)
- [src/tools/core/actor_tools_factory.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/core/actor_tools_factory.ts)
- [src/tools/core/call_actor_common.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/core/call_actor_common.ts)
- [src/tools/default/call_actor.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/default/call_actor.ts)
- [src/tools/default/search_actors.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/default/search_actors.ts)
- [src/tools/default/fetch_actor_details.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/default/fetch_actor_details.ts)
- [src/tools/index.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/index.ts)
- [src/tools/build.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/build.ts)
</details>

# Actor 工具系统

## 概述

Actor 工具系统是 apify-mcp-server 的核心子系统，负责将 Apify 平台上的 Actor（无服务器云程序）封装为 MCP（Model Context Protocol）工具，供 LLM（大语言模型）调用和执行。

该系统的主要职责包括：

- **工具注册**：将 Actor 动态注册为 MCP 可调用工具
- **参数转换**：将 LLM 生成的 JSON 参数转换为 Actor 输入 schema
- **执行管理**：启动 Actor 运行、跟踪进度、获取结果
- **响应构建**：将 Actor 执行结果转换为 MCP 协议格式返回

资料来源：[src/tools/index.ts:1-30]()

## 系统架构

### 整体架构图

```mermaid
graph TD
    subgraph "MCP Server Layer"
        A[MCP Server] --> B[Tools Index]
        B --> C[Actor Executor]
    end

    subgraph "Tool Factory Layer"
        C --> D[Actor Tools Factory]
        D --> E[Call Actor Common]
        D --> F[Search Actors]
        D --> G[Fetch Actor Details]
    end

    subgraph "Execution Layer"
        E --> H[Apify Client]
        H --> I[Actor Run Management]
        I --> J[Dataset Retrieval]
    end

    subgraph "Widget Layer"
        E --> K[Call Actor Widget]
    end
```

### 目录结构

```
src/tools/
├── index.ts                    # 工具导出索引
├── build.ts                    # 工具构建配置
├── actor_executor.ts           # Actor 执行器
├── core/
│   ├── actor_tools_factory.ts  # Actor 工具工厂
│   └── call_actor_common.ts    # 调用 Actor 通用逻辑
├── default/
│   ├── call_actor.ts           # call-actor 工具实现
│   ├── search_actors.ts        # search-actors 工具实现
│   └── fetch_actor_details.ts  # fetch-actor-details 工具实现
└── apps/
    ├── call_actor_widget.ts    # call-actor 小部件模式
    └── ...
```

资料来源：[src/tools/index.ts]()

## 核心组件

### 1. Actor Executor

`ActorExecutor` 是 Actor 工具系统的核心执行器，负责协调 Actor 的启动、进度跟踪和结果获取。

```typescript
// 伪代码结构
class ActorExecutor {
    async execute(
        actorName: string,
        input: Record<string, unknown>,
        options: RunOptions
    ): Promise<ActorExecutionResult>
    
    async getRunResult(runId: string): Promise<RunResult>
    
    trackProgress(runId: string, callback: ProgressCallback): void
}
```

**关键职责**：

| 职责 | 描述 |
|------|------|
| 运行启动 | 使用 Apify Client 启动 Actor |
| 进度跟踪 | 实时监听 Actor 执行进度 |
| 结果获取 | 从 Dataset 获取结构化输出 |
| 错误处理 | 处理超时、失败等异常情况 |

资料来源：[src/tools/actor_executor.ts:1-80]()

### 2. Actor Tools Factory

`ActorToolsFactory` 是工具工厂类，负责根据 Actor 定义动态生成 MCP 工具配置。

```typescript
interface ActorToolConfig {
    name: string;
    description: string;
    inputSchema: z.ZodSchema;
    execute: ToolExecutor;
}

class ActorToolsFactory {
    createActorTool(actorDefinition: ActorDefinition): ActorToolConfig
    
    createMCPActorTool(mcpServerUrl: string, mcpToolName: string): ActorToolConfig
}
```

**工具命名规范**：遵循 `actor-{name}-by-{author}` 格式

资料来源：[src/tools/core/actor_tools_factory.ts:1-60]()

### 3. Call Actor Common

`call_actor_common.ts` 包含所有 call-actor 工具共享的通用逻辑，包括参数解析、Actor 解析和小部件渲染。

```typescript
// 主要导出函数
export async function callActorPreExecute(
    toolArgs: InternalToolArgs,
    options: { route: HelperTools }
): Promise<PreExecuteResult>

export async function resolveAndValidateActor(
    params: ResolveActorParams
): Promise<ActorResolutionResult>

export function buildMCPResponse(
    response: ResponseBuilderInput
): ToolResponse
```

**预处理流程**：

```mermaid
graph TD
    A[输入参数] --> B[参数验证]
    B --> C[Actor 名称解析]
    C --> D[输入 Schema 合并]
    D --> E[Prefill 值注入]
    E --> F[解析结果]
```

资料来源：[src/tools/core/call_actor_common.ts:1-120]()

## 默认工具实现

### search-actors

搜索 Apify 商店中的 Actors，返回匹配的工具列表供 LLM 选择。

```typescript
interface SearchActorsParams {
    query: string;           // 搜索关键词
    maxResults?: number;     // 最大返回数量，默认 10
}

interface SearchActorsResult {
    actors: Actor[];
    total: number;
}
```

**工具配置**：

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| query | string | ✅ | - | 搜索查询字符串 |
| maxResults | integer | ❌ | 10 | 最大结果数量 |

资料来源：[src/tools/default/search_actors.ts:1-80]()

### fetch-actor-details

获取指定 Actor 的详细信息，包括输入 schema、统计信息和定价信息。

```typescript
interface FetchActorDetailsParams {
    actorId: string;         // Actor ID 或 username/actorName
}

interface ActorDetails {
    id: string;
    name: string;
    username: string;
    title: string;
    description: string;
    inputSchema: object;
    stats: ActorStats;
    pricingInfo: PricingInfo;
}
```

资料来源：[src/tools/default/fetch_actor_details.ts:1-60]()

### call-actor

执行指定的 Actor，是系统中最核心的工具。

```typescript
interface CallActorParams {
    actor: string;           // Actor 标识 (username/actorName)
    input?: object;         // Actor 输入参数
    build?: string;         // Actor 构建版本
    timeout?: number;       // 超时时间（秒）
    memory?: number;        // 内存限制（MB）
    waitSecs?: number;      // 等待运行完成的秒数
}
```

**执行流程**：

```mermaid
graph TD
    A[call-actor 调用] --> B[参数预处理]
    B --> C[Actor 解析验证]
    C --> D[Schema 验证]
    D --> E[启动 Actor Run]
    E --> F{waitSecs > 0?}
    F -->|是| G[等待运行完成]
    F -->|否| H[立即返回 Run ID]
    G --> I[获取 Dataset 结果]
    H --> J[返回 Run ID 和状态]
    I --> K[构建 MCP 响应]
    J --> K
```

资料来源：[src/tools/default/call_actor.ts:1-150]()

## 输入 Schema 处理

### Schema 转换流程

Actor 工具系统使用 Zod 进行 schema 验证和转换：

```mermaid
graph LR
    A[Actor JSON Schema] --> B[Zod Schema]
    B --> C[MCP Tool Schema]
    C --> D[参数验证]
```

### 必填字段处理

系统会自动过滤 Actor schema 中的必填字段：

1. **保留的必填字段**：无默认值且用户必须提供的参数
2. **移除的必填字段**：有默认值或 prefill 的参数

| 字段类型 | required | 处理方式 |
|----------|----------|----------|
| 无默认值 | ✅ | 保留在 required 中 |
| 有默认值 | ❌ | 从 required 移除 |
| 有 prefill | ❌ | 从 required 移除 |
| proxyConfiguration | ❌ | 强制移除（平台提供） |

资料来源：[res/actor_input_schema_required_fields.md]()

## 工具注册与构建

### 工具构建配置

`build.ts` 定义了所有可用工具的构建配置：

```typescript
export const TOOL_CONFIGS: Record<string, ToolConfig> = {
    actors: {
        tools: ['search-actors', 'fetch-actor-details', 'call-actor'],
    },
    runs: {
        tools: ['get-actor-run-list', 'get-actor-log'],
    },
    storage: {
        tools: ['get-dataset', 'get-dataset-items', 'get-key-value-store'],
    },
};
```

### 注册流程

```mermaid
graph TD
    A[Server 初始化] --> B[加载工具配置]
    B --> C[创建 ToolRegistry]
    C --> D[注册默认工具]
    D --> E[注册 Actor MCP 工具]
    E --> F[发布 toolsChanged 事件]
    F --> G[MCP Server 就绪]
```

资料来源：[src/tools/build.ts:1-50]()

## Widget 模式

Actor 工具系统支持 MCP Apps Widget 渲染模式，通过 `call-actor-widget` 工具实现。

### Widget 渲染流程

```mermaid
graph TD
    A[Widget 模式启用] --> B[UI_MODE=true]
    B --> C[加载 Widget JS]
    C --> D[生成 Widget HTML]
    D --> E[嵌入 MCP 响应]
    E --> F[App 渲染 Widget]
```

**Widget HTML 结构**：

```html
<div class="widget-container">
  <div id="root"></div>
  <script type="module">${widgetJs}</script>
</div>
```

资料来源：[src/tools/apps/call_actor_widget.ts:1-100]()

### Widget 与标准模式对比

| 特性 | 标准模式 | Widget 模式 |
|------|----------|-------------|
| 返回格式 | 纯文本 | HTML + 交互组件 |
| LLM 可见性 | 直接显示结果 | 渲染后显示 |
| 用户交互 | 文本反馈 | 可视化组件 |
| 适用场景 | CLI 工具 | MCP Apps |

## 错误处理

### 错误类型

| 错误类型 | 代码 | 处理方式 |
|----------|------|----------|
| Actor 不存在 | `ACTOR_NOT_FOUND` | 返回友好错误信息 |
| 参数验证失败 | `INVALID_INPUT` | 返回 schema 错误详情 |
| 运行超时 | `RUN_TIMEOUT` | 支持自定义超时时间 |
| 认证失败 | `AUTH_FAILED` | 提示配置 APIFY_TOKEN |
| 网络错误 | `NETWORK_ERROR` | 重试机制 |

### 错误响应格式

```json
{
  "content": [
    {
      "type": "text",
      "text": "Error: Actor 'xxx' not found or access denied"
    }
  ],
  "isError": true
}
```

## 配置选项

### 环境变量

| 变量名 | 必填 | 默认值 | 说明 |
|--------|------|--------|------|
| APIFY_TOKEN | ✅ | - | Apify API Token |
| APIFY_META_ORIGIN | ❌ | - | 请求来源标识 |
| UI_MODE | ❌ | false | 启用 Widget 模式 |

### 工具参数

| 参数 | 工具 | 说明 |
|------|------|------|
| build | call-actor | Actor 构建标签 |
| timeout | call-actor | 超时秒数 |
| memory | call-actor | 内存限制 MB |
| waitSecs | call-actor | 等待完成秒数 |

## 相关文件索引

| 文件路径 | 用途 |
|----------|------|
| `src/tools/index.ts` | 工具模块导出 |
| `src/tools/build.ts` | 工具构建配置 |
| `src/tools/actor_executor.ts` | Actor 执行引擎 |
| `src/tools/core/actor_tools_factory.ts` | 工具工厂 |
| `src/tools/core/call_actor_common.ts` | 通用调用逻辑 |
| `src/tools/default/call_actor.ts` | call-actor 实现 |
| `src/tools/default/search_actors.ts` | search-actors 实现 |
| `src/tools/default/fetch_actor_details.ts` | fetch-actor-details 实现 |
| `src/tools/apps/call_actor_widget.ts` | Widget 模式实现 |

---

<a id='payment-systems'></a>

## 支付系统集成

### 相关页面

相关主题：[Actor 工具系统](#actor-tools-system), [系统架构](#system-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/payments/index.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/index.ts)
- [src/payments/x402.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/x402.ts)
- [src/payments/skyfire.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/skyfire.ts)
- [src/payments/resolve.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/resolve.ts)
- [src/payments/helpers.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/helpers.ts)
- [src/payments/types.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/types.ts)
- [src/payments/const.ts](https://github.com/apify/apify-mcp-server/blob/main/src/payments/const.ts)
</details>

# 支付系统集成

> **⚠️ 重要提示**：本页面所需的支付系统相关源码文件（`src/payments/` 目录下的所有文件）未包含在当前检索的上下文范围内。以下内容基于预期文件结构进行描述，实际实现细节可能与本文档有所差异。建议开发者直接查阅 `src/payments/` 目录下的源码以获取准确信息。

## 概述

支付系统集成是 Apify MCP Server 中的核心模块之一，负责处理与 HTTP 402 Payment Required 协议相关的支付验证、费用计算和支付解决逻辑。该系统允许 MCP Server 在执行需要付费的操作前验证用户的支付状态。

## 架构设计

### 模块结构

| 模块文件 | 功能描述 |
|---------|---------|
| `index.ts` | 主入口，导出支付系统公共 API |
| `x402.ts` | HTTP 402 协议实现 |
| `skyfire.ts` | Skyfire 支付网关集成 |
| `resolve.ts` | 支付解析与验证逻辑 |
| `helpers.ts` | 支付相关辅助函数 |
| `types.ts` | 类型定义 |
| `const.ts` | 常量定义 |

### 核心类型

根据项目结构推测，支付系统应包含以下核心类型定义：

```typescript
// types.ts (推测)
interface PaymentContext {
  userId: string;
  actorId: string;
  paymentRequired: boolean;
  price?: number;
  currency?: string;
}

interface PaymentResult {
  success: boolean;
  transactionId?: string;
  error?: string;
}
```

## HTTP 402 协议实现

`x402.ts` 模块负责实现 HTTP 402 Payment Required 规范，这是处理付费请求的标准协议。

### 请求流程

```mermaid
graph TD
    A[客户端请求] --> B{检查支付状态}
    B -->|已付费| C[执行操作]
    B -->|未付费| D[返回 402 响应]
    D --> E[包含价格信息]
    E --> F[等待客户端支付]
    F --> G{支付成功?}
    G -->|是| C
    G -->|否| H[拒绝请求]
```

## Skyfire 支付网关

Skyfire 是本系统集成的支付网关之一，负责实际的资金处理。

### 主要功能

- **支付初始化**：创建支付会话
- **支付验证**：确认支付状态
- **退款处理**：处理退款请求
- **交易记录**：记录所有交易详情

## 支付解析模块

`resolve.ts` 负责解析和验证支付相关的请求参数。

### 解析逻辑

| 步骤 | 描述 |
|-----|------|
| 1 | 提取支付信息头 |
| 2 | 验证签名有效性 |
| 3 | 检查支付金额 |
| 4 | 返回解析结果 |

## 配置常量

`const.ts` 中定义的常量包括：

- 支付超时时间
- 重试次数限制
- 货币类型定义
- HTTP 状态码常量

## 集成方式

### 初始化支付系统

```typescript
import { createPaymentProvider } from '@apify/mcp-server';

// 在服务器配置中启用支付
const paymentProvider = createPaymentProvider({
  mode: 'production',
  // 其他配置...
});
```

## 错误处理

支付系统可能返回以下错误类型：

| 错误码 | 描述 |
|-------|------|
| `PAYMENT_REQUIRED` | 需要支付才能继续 |
| `PAYMENT_FAILED` | 支付处理失败 |
| `INVALID_PAYMENT` | 支付信息无效 |
| `TIMEOUT` | 支付超时 |

## 安全考虑

1. **签名验证**：所有支付请求必须包含有效签名
2. **超时机制**：防止无限等待支付
3. **重试限制**：防止恶意重复请求
4. **日志审计**：记录所有支付相关操作

## 相关资源

- [资源服务文档](./resource_service.md)
- [工具开发指南](./tools_development.md)
- [错误处理规范](./error_handling.md)

---

> **维护说明**：本页面基于仓库源码结构自动生成。如发现内容与实际实现不符，请提交 Issue 或 Pull Request 进行更正。

---

<a id='storage-management'></a>

## 存储管理

### 相关页面

相关主题：[Actor 工具系统](#actor-tools-system), [遥测与监控](#telemetry-monitoring)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tools/common/get_dataset.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset.ts)
- [src/tools/common/get_dataset_items.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset_items.ts)
- [src/tools/common/get_dataset_schema.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset_schema.ts)
- [src/tools/common/dataset_collection.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/dataset_collection.ts)
- [src/tools/common/get_key_value_store.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store.ts)
- [src/tools/common/get_key_value_store_keys.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store_keys.ts)
- [src/tools/common/get_key_value_store_record.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store_record.ts)
- [src/tools/common/key_value_store_collection.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/key_value_store_collection.ts)
- [src/apify_client.ts](https://github.com/apify/apify-mcp-server/blob/main/src/apify_client.ts)
</details>

# 存储管理

## 概述

存储管理是 Apify MCP Server 提供的核心功能模块之一，用于通过 MCP 协议与 Apify 平台的数据存储服务进行交互。该模块支持两种主要存储类型：

| 存储类型 | 用途 | 数据格式 |
|---------|------|---------|
| **Dataset（数据集）** | 结构化表格数据存储 | JSON 数组 |
| **Key-Value Store（键值存储）** | 键值对文件存储 | 任意文件类型 |

资料来源：[src/apify_client.ts](https://github.com/apify/apify-mcp-server/blob/main/src/apify_client.ts)

## 架构设计

### 存储管理模块结构

```mermaid
graph TD
    A[MCP Tools] --> B[存储管理模块]
    B --> C[数据集工具]
    B --> D[键值存储工具]
    
    C --> C1[get_dataset]
    C --> C2[get_dataset_items]
    C --> C3[get_dataset_schema]
    C --> C4[dataset_collection]
    
    D --> D1[get_key_value_store]
    D --> D2[get_key_value_store_keys]
    D --> D3[get_key_value_store_record]
    D --> D4[key_value_store_collection]
    
    C1 & C2 & C3 & C4 --> E[Apify API Client]
    D1 & D2 & D3 & D4 --> E
    
    E --> F[Apify Cloud]
    F --> G[Dataset Storage]
    F --> H[Key-Value Storage]
```

### 客户端初始化

所有存储工具通过统一的 Apify 客户端实例进行操作，客户端在初始化时从环境变量读取认证信息：

```typescript
// 资料来源：src/apify_client.ts
const apifyClient = new ApifyClient({
    token: process.env.APIFY_TOKEN,
});
```

## 数据集（Dataset）管理

数据集用于存储 Actor 运行产生的结构化数据，类似于关系型数据库表或电子表格。

资料来源：[src/tools/common/get_dataset.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset.ts)

### 获取数据集信息

`get_dataset` 工具用于获取特定数据集的元数据信息。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `datasetId` | string | 是 | 数据集唯一标识符 |

**返回字段**：

| 字段 | 说明 |
|------|------|
| `id` | 数据集 ID |
| `name` | 数据集名称 |
| `createdAt` | 创建时间 |
| `modifiedAt` | 最后修改时间 |
| `itemCount` | 数据项总数 |
| `username` | 所有者用户名 |

资料来源：[src/tools/common/get_dataset.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset.ts)

### 获取数据集项

`get_dataset_items` 工具用于读取数据集中的实际数据内容。

| 参数 | 类型 | 必需 | 默认值 | 说明 |
|------|------|------|--------|------|
| `datasetId` | string | 是 | - | 数据集 ID |
| `offset` | number | 否 | 0 | 数据偏移量 |
| `limit` | number | 否 | 100 | 返回数据条数限制 |
| `clean` | boolean | 否 | true | 返回干净数据（非脏数据） |
| `fields` | string[] | 否 | - | 指定返回的字段 |
| `unwind` | string | 否 | - | 展开字段（用于嵌套数组） |
| `flatten` | string[] | 否 | - | 展平的字段列表 |
| `skipEmpty` | boolean | 否 | - | 跳过空值项 |
| `skipHidden` | boolean | 否 | - | 跳过隐藏字段 |
| `desc` | boolean | 否 | false | 降序排列 |

资料来源：[src/tools/common/get_dataset_items.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset_items.ts)

### 获取数据集 Schema

`get_dataset_schema` 工具用于获取数据集的数据结构定义，即所有字段及其类型信息。

**返回结构示例**：

```json
{
  "fields": [
    { "name": "url", "type": "string" },
    { "name": "title", "type": "string" },
    { "name": "count", "type": "number" }
  ]
}
```

资料来源：[src/tools/common/get_dataset_schema.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_dataset_schema.ts)

### 数据集集合操作

`dataset_collection` 工具用于列出当前用户拥有的所有数据集。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `offset` | number | 否 | 列表偏移量 |
| `limit` | number | 否 | 返回条数限制 |
| `Clean` | boolean | 否 | 过滤脏数据集 |

资料来源：[src/tools/common/dataset_collection.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/dataset_collection.ts)

### 数据集操作流程

```mermaid
sequenceDiagram
    participant LLM as 大语言模型
    participant MCP as MCP Server
    participant API as Apify API
    participant DS as Dataset Storage
    
    LLM->>MCP: 调用 get_dataset_items
    MCP->>API: 请求数据集内容
    API->>DS: 查询存储
    DS-->>API: 返回 JSON 数据
    API-->>MCP: 格式化响应
    MCP-->>LLM: 返回数据项
```

## 键值存储（Key-Value Store）管理

键值存储用于管理 Actor 运行产生的文件数据，支持任意文件类型的读写操作。

资料来源：[src/tools/common/get_key_value_store.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store.ts)

### 获取键值存储信息

`get_key_value_store` 工具用于获取特定键值存储的元数据。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `storeId` | string | 是 | 键值存储 ID |

资料来源：[src/tools/common/get_key_value_store.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store.ts)

### 获取键列表

`get_key_value_store_keys` 工具用于列出键值存储中的所有键。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `storeId` | string | 是 | 键值存储 ID |

**返回字段**：

| 字段 | 说明 |
|------|------|
| `keys` | 键名数组 |
| `count` | 键总数 |
| `total` | 符合条件的总数 |

资料来源：[src/tools/common/get_key_value_store_keys.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store_keys.ts)

### 获取键值记录

`get_key_value_store_record` 工具用于读取特定键对应的值。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `storeId` | string | 是 | 键值存储 ID |
| `key` | string | 是 | 数据键名 |

**返回字段**：

| 字段 | 说明 |
|------|------|
| `key` | 键名 |
| `contentType` | 内容 MIME 类型 |
| `value` | 存储的值（根据 contentType 解码） |

资料来源：[src/tools/common/get_key_value_store_record.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/get_key_value_store_record.ts)

### 键值存储集合操作

`key_value_store_collection` 工具用于列出当前用户拥有的所有键值存储。

| 参数 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `offset` | number | 否 | 列表偏移量 |
| `limit` | number | 否 | 返回条数限制 |

资料来源：[src/tools/common/key_value_store_collection.ts](https://github.com/apify/apify-mcp-server/blob/main/src/tools/common/key_value_store_collection.ts)

### 键值存储数据结构

```mermaid
graph LR
    subgraph Key-Value Store [storeId]
        A[键值存储元数据]
        subgraph Keys
            B[key1] --> C[值 + Content-Type]
            D[key2] --> E[值 + Content-Type]
            F[key3] --> G[值 + Content-Type]
        end
    end
```

## 存储类型对比

| 特性 | Dataset | Key-Value Store |
|------|---------|-----------------|
| 数据结构 | 结构化记录（表格） | 键值对 |
| 访问方式 | 按偏移量/范围 | 按键名 |
| 适用场景 | 爬取结果、批量数据 | 配置、状态、文件 |
| 数据格式 | JSON 数组 | 任意类型 |
| Schema | 支持自动推断 | 无固定结构 |

## 工具清单

| 工具名称 | 描述 | 主要参数 |
|---------|------|---------|
| `get_dataset` | 获取数据集元数据 | `datasetId` |
| `get_dataset_items` | 获取数据集内容 | `datasetId`, `offset`, `limit` |
| `get_dataset_schema` | 获取数据集结构 | `datasetId` |
| `dataset_collection` | 列出数据集 | `offset`, `limit` |
| `get_key_value_store` | 获取键值存储元数据 | `storeId` |
| `get_key_value_store_keys` | 获取键列表 | `storeId` |
| `get_key_value_store_record` | 获取键值记录 | `storeId`, `key` |
| `key_value_store_collection` | 列出键值存储 | `offset`, `limit` |

## 使用场景

### 场景一：读取爬取结果

```mermaid
graph LR
    A[Actor 爬取网页] --> B[存储到 Dataset]
    B --> C[MCP 调用 get_dataset_items]
    C --> D[LLM 分析数据]
```

### 场景二：获取 Actor 状态

```mermaid
graph LR
    A[Actor 运行] --> B[保存状态到 KVS]
    B --> C[MCP 调用 get_key_value_store_record]
    C --> D[读取运行时状态]
```

## 错误处理

存储工具返回错误时，遵循 MCP 协议的标准错误格式：

```json
{
  "contents": [{
    "uri": "...",
    "mimeType": "text/plain",
    "text": "错误描述信息"
  }]
}
```

常见错误场景：
- 数据集/键值存储不存在
- 无权限访问指定存储
- API 请求超时
- 存储 ID 格式错误

## 认证要求

所有存储操作需要有效的 `APIFY_TOKEN`，该令牌通过环境变量配置：

```bash
APIFY_TOKEN="your-apify-token"
```

无认证令牌时，存储管理工具将无法正常执行。

## 最佳实践

1. **分页读取大数据集**：使用 `offset` 和 `limit` 参数分批获取数据
2. **指定返回字段**：使用 `fields` 参数减少传输数据量
3. **检查 Schema**：首次访问新数据集时，先调用 `get_dataset_schema` 了解数据结构
4. **使用 Content-Type**：读取键值存储记录时，注意解析对应的 MIME 类型

---

<a id='telemetry-monitoring'></a>

## 遥测与监控

### 相关页面

相关主题：[存储管理](#storage-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/telemetry.ts](https://github.com/apify/apify-mcp-server/blob/main/src/telemetry.ts)
- [src/utils/logging.ts](https://github.com/apify/apify-mcp-server/blob/main/src/utils/logging.ts)
- [src/utils/progress.ts](https://github.com/apify/apify-mcp-server/blob/main/src/utils/progress.ts)
- [.sentryclirc](https://github.com/apify/apify-mcp-server/blob/main/.sentryclirc)
</details>

# 遥测与监控

## 概述

Apify MCP Server 的遥测与监控系统负责收集、传输和分析服务器运行过程中的关键指标数据。该系统包含三个核心子模块：

- **工具遥测（Tool Telemetry）**：收集工具执行结果和状态信息，用于 Segment 分析
- **日志系统（Logging）**：多级别日志记录，支持 Mezmo（LogDNA）集成
- **进度追踪（Progress Tracking）**：支持长时间运行任务的进度通知

遥测系统采用分层设计，`toolTelemetry` 仅在服务器内部流转，最终被 `extractToolTelemetry()` 提取后剥离，不会暴露给 MCP 客户端。

## 架构概览

```mermaid
graph TD
    subgraph "客户端层"
        A[MCP Client]
    end
    
    subgraph "MCP Server"
        B[工具执行]
        C[buildMCPResponse]
        D[工具遥测收集]
        E[进度追踪器]
    end
    
    subgraph "日志系统"
        F[SoftFail]
        G[Exception]
        H[Warn]
        I[Info]
        J[Debug]
    end
    
    subgraph "外部服务"
        K[Segment]
        L[Mezmo LogDNA]
        M[Sentry]
    end
    
    B --> C
    C --> D
    D -->|toolTelemetry| K
    B --> E
    E -->|sendNotification| A
    F --> L
    G --> L
    G --> M
    H --> L
    I --> L
    J --> L
```

## 工具遥测

### 工具响应构建

`buildMCPResponse` 函数是构建 MCP 工具响应的核心，它将文本内容、错误标记、遥测数据和结构化内容整合为统一响应格式。

**函数签名：**

```typescript
export function buildMCPResponse(options: {
    texts: string[];
    isError?: boolean;
    telemetry?: ToolTelemetryContext;
    structuredContent?: unknown;
    _meta?: Record<string, unknown>;
})
```

**返回值结构：**

| 字段 | 类型 | 说明 |
|------|------|------|
| `content` | `Array<{ type: 'text'; text: string }>` | 文本内容数组 |
| `isError` | `boolean` | 是否为错误响应（默认 `false`） |
| `toolTelemetry` | `ToolTelemetryContext` | 工具遥测数据（内部使用） |
| `structuredContent` | `unknown` | 结构化响应数据 |
| `_meta` | `Record<string, unknown>` | 元数据 |

### 遥测数据结构

工具遥测包含以下关键指标：

| 字段 | 说明 |
|------|------|
| `toolStatus` | 工具执行状态 |
| `failureCategory` | 失败分类（用于分析错误类型） |

### 响应大小计算

`computeToolResponseSizeBytes` 函数计算工具响应的字节大小，用于限流和监控：

```typescript
export function computeToolResponseSizeBytes(result: unknown): number
```

**计算规则：**
- 统计 `content[]` 数组中所有文本项的 UTF-8 字节长度
- 统计 JSON 序列化的 `structuredContent` 字节长度
- 其他字段（`isError`、`_meta` 等）不计入

## 日志系统

### 日志级别

系统使用五个日志级别，从高到低排列：

| 级别 | 使用场景 | 示例 |
|------|----------|------|
| `softFail` | 客户端错误 | 无效输入、权限不足 |
| `exception` / `error` | 服务器错误 | 内部异常、系统故障 |
| `warn` | 可疑但非关键行为 | 异常配置、降级处理 |
| `info` | 重要状态变更 | 工具注册、连接建立 |
| `debug` | 本地开发调试 | 请求详情、中间状态 |

### Mezmo LogDNA 集成规则

Mezmo（LogDNA）会自动将包含 `"error"` 关键字的日志提升为 error 级别，可能导致误报。系统制定了以下规则：

```typescript
// ✅ 正确：使用 errMessage 作为键名
log.softFail('Client disconnected', { 
    errMessage: err.message.replace(/ error:/gi, ' failure:') 
});

// ❌ 错误：message 中包含 "error" 会触发误报
log.softFail('Client disconnected', { 
    error: err.message 
});
```

**规则汇总：**

| 规则 | 说明 |
|------|------|
| 使用 `errMessage` 替代 `error` 作为数据键 | 避免自动提升为 error 级别 |
| 清理错误消息中的 "error" 字符串 | `.replace(/ error:/gi, ' failure:')` |
| 避免在消息字符串中使用 "error" | 直接使用友好的错误描述 |

## 进度追踪

### 进度追踪器

`ProgressTracker` 用于长时间运行的任务，通过 `sendNotification` 向客户端推送进度更新。

```mermaid
sequenceDiagram
    participant C as Client
    participant S as Server
    participant P as ProgressTracker
    participant A as Apify API
    
    C->>S: tools/call with progressToken
    S->>P: createProgressTracker
    P->>A: 启动 Actor
    A-->>P: 状态更新
    P-->>C: 进度通知 (progress)
    A-->>P: 完成
    P-->>C: 最终结果
```

### 进度通知格式

进度通知通过 MCP 的 `notifications/progress` 发送，包含：

| 字段 | 说明 |
|------|------|
| `progressToken` | 客户端提供的追踪令牌 |
| `progress` | 0-1 之间的进度值 |
| `message` | 当前步骤描述 |

## Sentry 集成

### 配置

`.sentryclirc` 文件定义了 Sentry 的项目配置：

```ini
[defaults]
project=apify-mcp-server
org=apify
```

### 错误上报

服务器错误通过 Sentry 自动上报，包含：

- 堆栈跟踪信息
- 请求上下文
- 用户环境数据

## 数据流与处理

```mermaid
graph LR
    subgraph "输入"
        A[用户请求]
        B[工具执行]
    end
    
    subgraph "处理"
        C[参数验证]
        D[业务逻辑]
        E[错误处理]
    end
    
    subgraph "输出"
        F[响应构建]
        G[遥测收集]
        H[日志记录]
    end
    
    A --> C
    C -->|验证通过| D
    C -->|验证失败| E
    D --> F
    E --> F
    D --> G
    E --> G
    D --> H
    E --> H
```

## 最佳实践

### 日志记录

1. **选择合适级别**：根据错误的严重程度选择 `softFail`、`error` 或 `warn`
2. **敏感数据保护**：在记录日志前进行数据脱敏
3. **错误消息格式化**：使用友好的用户消息，避免暴露内部实现细节

### 遥测数据

1. **填充必填字段**：确保 `toolStatus` 和 `failureCategory` 正确设置
2. **响应大小控制**：使用 `computeToolResponseSizeBytes` 监控响应大小
3. **避免泄露内部信息**：遥测数据仅供服务端分析，不暴露给客户端

### 进度追踪

1. **及时更新**：长时间操作应定期发送进度通知
2. **提供上下文**：进度消息应清晰说明当前步骤
3. **优雅终止**：支持客户端取消时正确清理资源

## 相关文件

| 文件路径 | 用途 |
|----------|------|
| `src/telemetry.ts` | 工具遥测定义与响应构建 |
| `src/utils/logging.ts` | 日志系统实现 |
| `src/utils/progress.ts` | 进度追踪器实现 |
| `src/utils/mcp.ts` | MCP 响应工具函数 |
| `.sentryclirc` | Sentry 配置 |

---

<a id='frontend-architecture'></a>

## 前端架构

### 相关页面

相关主题：[组件库与 Widget](#widget-components), [系统架构](#system-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/web/src/pages/ActorSearch/ActorSearch.skeleton.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/pages/ActorSearch/ActorSearch.skeleton.tsx)
- [src/web/src/pages/ActorSearch/ActorSearch.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/pages/ActorSearch/ActorSearch.tsx)
- [src/web/src/pages/ActorRun/ActorRun.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/pages/ActorRun/ActorRun.tsx)
- [src/web/src/context/mcp-app-context.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/context/mcp-app-context.tsx)
- [src/resources/resource_service.ts](https://github.com/apify/apify-mcp-server/blob/main/src/resources/resource_service.ts)
- [DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md](https://github.com/apify/apify-mcp-server/blob/main/DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md)
</details>

# 前端架构

## 概述

Apify MCP Server 的前端架构是一套基于 React 的嵌入式 Widget 系统，设计用于在 MCP（Model Context Protocol）环境中提供可交互的 Actors 搜索、运行状态查看和详情展示功能。前端采用组件化架构，遵循设计系统规范，支持动态加载和独立运行。

主要技术栈：

- **React 18** - UI 组件框架
- **Styled Components** - 样式解决方案
- **@apify/ui-library** - 共享组件库
- **Tailwind CSS** - 工具类样式（配置于 `tailwind.config.js`）

## 架构分层

```
┌─────────────────────────────────────────────────────────────┐
│                     MCP Server Layer                         │
│  (resource_service.ts - Widget 动态加载与资源服务)            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Widget Bundle Layer                       │
│  (actor-run-widget.js, actor-detail-widget.js,              │
│   search-actors-widget.js)                                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                   React Component Layer                      │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐            │
│  │ ActorSearch │ │  ActorRun   │ │ ActorDetail │            │
│  └─────────────┘ └─────────────┘ └─────────────┘            │
│  ┌─────────────────────────────────────────────────┐        │
│  │         Shared Components & Context             │        │
│  └─────────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────────┘
```

## Widget 系统

### Widget 类型

| Widget 名称 | 入口文件 | 用途 |
|------------|---------|------|
| Actor Search Widget | `src/web/index-actor-search.html` | 搜索和浏览 Actors |
| Actor Run Widget | `src/web/index-actor-run.html` | 查看 Actor 运行状态 |
| Actor Detail Widget | `src/web/actor-detail.html` | 展示 Actor 详细信息 |

### Widget 动态加载机制

Widget 通过 MCP Resource 协议动态加载。核心逻辑位于 `src/resources/resource_service.ts`：

1. **URI 模式识别**：检测 `ui://widget/` 前缀的 URI
2. **Widget 注册表查询**：通过 `getAvailableWidgets()` 获取可用 Widget 列表
3. **文件系统读取**：使用 `node:fs` 模块读取 Widget 的 JS 文件
4. **HTML 模板生成**：将 JS 包装在 HTML 模板中返回

```typescript
// 资料来源：src/resources/resource_service.ts:55-70
if (getMode() === ServerMode.APPS && uri.startsWith('ui://widget/')) {
    const widget = getAvailableWidgets().get(uri);

    if (!widget || !widget.exists) {
        return {
            contents: [{
                uri,
                mimeType: 'text/plain',
                text: `Widget ${uri} is not available. ${!widget ? 'Not found in registry.' : `File not found at ${widget.jsPath}`}`,
            }],
        };
    }

    try {
        log.debug('Reading widget file', { uri, jsPath: widget.jsPath });
        const fs = await import('node:fs');
        const widgetJs = fs.readFileSync(widget.jsPath, 'utf-8');

        const widgetHtml = `<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>${widget.title}</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module">${widgetJs}</script>
  </body>
</html>`;
```

### Widget Bundle 体积优化

根据 `res/web-widget-bundle-size.md`，生产环境 Widget Bundle 体积已优化至：

| Widget | 优化前 | 优化后 |
|--------|-------|-------|
| actor-run-widget | ~1.86 MB | ~1.16 MB |
| actor-detail-widget | ~1.86 MB | ~1.52 MB |
| search-actors-widget | ~1.87 MB | ~1.53 MB |

剩余较大体积主要来自 Markdown 解析依赖。

## 组件架构

### 页面组件

#### ActorSearch 组件

ActorSearch 页面负责展示 Actor 搜索结果列表，采用以下结构：

- **ActorSearchResults** - 结果列表容器
- **ActorContainer** - 单个 Actor 卡片容器
- **ActorCard** - Actor 信息卡片
- **EmptyState** - 空状态提示组件

```typescript
// 资料来源：src/web/src/pages/ActorSearch/ActorSearch.tsx
const EmptyState: React.FC<EmptyStateProps> = (props: EmptyStateProps) => {
    const { title, description } = props;
    return (
        <Message type="info" caption={title}>
            {description ?? ""}
        </Message>
    );
};
```

#### ActorRun 组件

ActorRun 页面展示单个 Actor 的运行状态，包含以下关键元素：

- **ActorHeader** - 头部信息区
- **ActorInfoRow** - Actor 基本信息和状态
- **StatusMetadataContainer** - 状态徽章和元数据
- **TableContainer** - 运行数据表格

```typescript
// 资料来源：src/web/src/pages/ActorRun/ActorRun.tsx
<ActorInfoRow>
    <ActorNameWithIcon>
        <ActorAvatar size={20} name={runData.actorName} url={pictureUrl} />
        <ActorNameLink onClick={handleOpenActor}>
            {runData.actorName}
        </ActorNameLink>
    </ActorNameWithIcon>

    <StatusMetadataContainer>
        <Badge variant={getStatusVariant(runData.status)} size="small" LeadingIcon={getStatusVariantLeadingIcon(runData.status)}>
            {runData.status.charAt(0) + runData.status.slice(1).toLowerCase()}
        </Badge>
    </StatusMetadataContainer>
</ActorInfoRow>
```

### Skeleton 加载组件

为每个页面提供骨架屏加载状态，提升用户体验。Skeleton 组件遵循统一的设计模式：

```typescript
// 资料来源：src/web/src/pages/ActorSearch/ActorSearch.skeleton.tsx
const SectionHeaderWrapper = styled(Box)`
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: ${theme.color.neutral.background};
    border-top: 1px solid ${theme.color.neutral.separatorSubtle};
`;

const SectionHeaderSkeleton: React.FC = () => {
    return (
        <SectionHeaderWrapper px="space16" py="space12">
            <SkeletonBlock style={{ height: '24px', width: '96px' }} />
            <SkeletonBlock style={{ height: '16px', width: '64px' }} />
        </SectionHeaderWrapper>
    );
};
```

## 设计系统规范

### 主题令牌

前端使用统一的设计令牌系统，所有样式必须使用 `theme.*` 令牌，禁止硬编码颜色和间距值。

#### 颜色令牌

| 类别 | 用途 | 示例 |
|------|------|------|
| `neutral` | 中性色 | `theme.color.neutral.text` |
| `primary` | 主色调 | `theme.color.primary.action` |
| `success` | 成功状态 | `theme.color.success.background` |
| `warning` | 警告状态 | `theme.color.warning.action` |
| `danger` | 危险状态 | `theme.color.danger.text` |

#### 间距令牌

| 令牌 | 用途 |
|------|------|
| `space4`, `space8` | 元素间间隙 |
| `space12`, `space16` | 组件内边距 |
| `space24`, `space32` | 区域间距 |
| `space40`, `space64`, `space80` | 大型布局间距 |

#### 圆角令牌

| 令牌 | 用途 |
|------|------|
| `radius4` | 小型元素 |
| `radius6`, `radius8` | 按钮、输入框 |
| `radius12` | 卡片 |
| `radiusFull` | 圆形元素 |

### 组件导入规范

```typescript
// ✅ 正确：从 ui-library 导入
import { Button, Badge, Chip } from '@apify/ui-library';

// ❌ 错误：创建重复组件
// ❌ 错误：从相对路径导入非 ui-library 组件
```

### 样式组件编写模式

```typescript
// 资料来源：DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md
import styled from 'styled-components';
import { theme } from '@apify/ui-library';

const StyledComponent = styled.div<{ $variant?: string }>`
    color: ${theme.color.neutral.text};
    padding: ${theme.space.space16};

    ${({ $variant }) => $variant === 'primary' && css`
        background: ${theme.color.primary.background};
    `}
`;
```

**注意**：使用 `$` 前缀标记瞬态 props（如 `$variant`、`$isActive`）。

## 组件结构规范

组件代码遵循统一的组织顺序：

```typescript
// 1. Imports (按功能分组)
import { forwardRef } from 'react';
import styled from 'styled-components';
import { theme } from '@apify/ui-library';

// 2. 常量与类型定义
export const COMPONENT_VARIANTS = { ... } as const;
type ComponentVariants = ValueOf<typeof COMPONENT_VARIANTS>;

// 3. Styled Components
const StyledWrapper = styled.div`...`;

// 4. 组件实现
export const Component = forwardRef<HTMLElement, Props>((props, ref) => {
    // implementation
});

// 5. Display Name
Component.displayName = 'Component';
```

## 状态与上下文

前端使用 React Context 管理全局状态，核心上下文包括：

- **MCP App Context** - 管理 MCP 连接状态和应用配置
- **Theme Context** - 提供主题令牌访问

### 自定义 Hooks

| Hook | 用途 |
|------|------|
| `use-max-height` | 计算元素最大高度 |
| `use-widget-props` | 解析 Widget 配置属性 |

## 静态资源结构

```
src/web/
├── index.html                    # 入口页面
├── index-actor-search.html       # Actor 搜索 Widget 入口
├── index-actor-run.html          # Actor 运行 Widget 入口
├── actor-detail.html             # Actor 详情 Widget 入口
├── common.css                    # 共享样式
└── src/
    ├── index.css                 # 全局样式
    ├── types.ts                  # TypeScript 类型定义
    ├── context/                  # React Context
    │   └── mcp-app-context.tsx
    ├── hooks/                    # 自定义 Hooks
    │   ├── use-max-height.ts
    │   └── use-widget-props.ts
    └── pages/                    # 页面组件
        ├── ActorSearch/
        │   ├── ActorSearch.tsx
        │   └── ActorSearch.skeleton.tsx
        └── ActorRun/
            └── ActorRun.tsx
```

## 开发预览

开发环境下，Widget 通过独立 HTML 文件预览。每个 Widget 入口页面结构相同：

```html
<!-- 资料来源：src/web/index-actor-search.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Actor Search Widget - Test</title>
    <link rel="stylesheet" href="/common.css" />
  </head>
  <body>
    <div class="widget-container">
      <h2>Actor Search Widget</h2>
      <div id="root"></div>
    </div>

    <script type="module" src="/dist/search-actors-widget.js"></script>
  </body>
</html>
```

主入口页面 `index.html` 提供所有 Widget 的链接导航：

```html
<!-- 资料来源：src/web/index.html -->
<h1>Apify Widgets - Dev Preview</h1>
<div class="widget-list">
  <a href="/index-actor-search.html" target="_blank">Actor Search Widget</a>
  <a href="/index-actor-run.html" target="_blank">Actor Run Widget</a>
</div>
```

## 验证协议

提交前端代码前，必须通过以下检查清单：

### Token 审计

使用正则表达式搜索，禁止硬编码值：

| 检查项 | 正则表达式 | 预期结果 |
|--------|----------|---------|
| 颜色值 | `['"]#[0-9a-fA-F]{3,8}['"]` | 零匹配 |
| 像素值 | `['"][0-9]+px['"]` | 零匹配 |

### 导入检查

- 所有 styled-components 必须从 `@apify/ui-library` 导入 `theme`
- 不得存在重复的组件实现

### 模式匹配

- 组件结构与现有组件保持一致
- Props 命名遵循项目约定
- Variant 模式保持统一

## 常见问题

### 禁止的写法

```typescript
// ❌ 混用硬编码和令牌
padding: ${theme.space.space16} 10px;

// ❌ 使用不存在的颜色属性
theme.color.neutral.textLight
theme.color.primary.main

// ❌ 创建重复组件
// 应该从 @apify/ui-library 导入
```

### 正确做法

```typescript
// ✅ 所有值使用令牌
padding: ${theme.space.space16} ${theme.space.space10};
background: ${theme.color.primary.action};

// ✅ 使用实际存在的属性名
theme.color.neutral.textMuted
theme.color.primary.action

---

<a id='widget-components'></a>

## 组件库与 Widget

### 相关页面

相关主题：[前端架构](#frontend-architecture), [MCP 协议实现](#mcp-protocol-implementation)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/web/src/components/ui/Button.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/ui/Button.tsx)
- [src/web/src/components/ui/Card.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/ui/Card.tsx)
- [src/web/src/components/ui/Badge.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/ui/Badge.tsx)
- [src/web/src/components/ui/Alert.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/ui/Alert.tsx)
- [src/web/src/components/ui/JsonPreview.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/ui/JsonPreview.tsx)
- [src/web/src/components/actor/ActorCard.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/actor/ActorCard.tsx)
- [src/web/src/components/actor/ActorStats.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/actor/ActorStats.tsx)
- [src/web/src/components/layout/WidgetLayout.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/components/layout/WidgetLayout.tsx)
- [src/web/src/widgets/actor-detail-widget.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/widgets/actor-detail-widget.tsx)
- [src/web/src/widgets/actor-run-widget.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/widgets/actor-run-widget.tsx)
- [src/web/src/widgets/search-actors-widget.tsx](https://github.com/apify/apify-mcp-server/blob/main/src/web/src/widgets/search-actors-widget.tsx)
</details>

# 组件库与 Widget

## 概述

Apify MCP Server 的前端组件体系由两层核心架构组成：**通用 UI 组件库** 和 **业务 Widget**。这两层相互协作，共同支撑 MCP 服务器在 APPS 模式下的可视化交互能力。

**UI 组件库** 位于 `src/web/src/components/ui/`，提供按钮、卡片、徽章、警告框等基础原子组件，所有样式遵循 Apify Design System 的设计规范。

**Widget** 位于 `src/web/src/widgets/`，是针对特定业务场景（如 Actor 搜索、Actor 运行状态）封装的完整功能单元，每个 Widget 都是一个独立的 React 应用。

资料来源：[DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md](DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md)

---

## 架构分层

Mermaid 架构图展示了组件体系的分层结构：

```mermaid
graph TB
    subgraph "应用层 (Widgets)"
        W1[search-actors-widget]
        W2[actor-run-widget]
        W3[actor-detail-widget]
    end
    
    subgraph "页面层 (Pages)"
        P1[ActorSearch]
        P2[ActorRun]
        P3[ActorSearchDetail]
    end
    
    subgraph "业务组件 (Business Components)"
        C1[ActorCard]
        C2[ActorStats]
    end
    
    subgraph "通用 UI 组件 (Base Components)"
        B1[Button]
        B2[Card]
        B3[Badge]
        B4[Alert]
        B5[JsonPreview]
        B6[WidgetLayout]
    end
    
    subgraph "外部依赖"
        E1[@apify/ui-library]
        E2[styled-components]
    end
    
    W1 --> P1
    W2 --> P2
    W3 --> P3
    
    P1 --> C1
    P3 --> C1
    P1 --> C2
    P2 --> C2
    
    C1 --> B1
    C1 --> B2
    C1 --> B3
    C2 --> B4
    P2 --> B5
    P1 --> B6
    
    B1 --> E1
    B2 --> E1
    B3 --> E1
    B4 --> E1
    B6 --> E1
    B1 --> E2
    B2 --> E2
    B6 --> E2
```

资料来源：[src/web/src/widgets/actor-detail-widget.tsx](src/web/src/widgets/actor-detail-widget.tsx)

---

## 通用 UI 组件

### 组件列表

| 组件名 | 文件路径 | 用途 |
|--------|----------|------|
| Button | `components/ui/Button.tsx` | 可交互按钮，支持多种变体和状态 |
| Card | `components/ui/Card.tsx` | 容器卡片组件 |
| Badge | `components/ui/Badge.tsx` | 状态徽章与标签 |
| Alert | `components/ui/Alert.tsx` | 消息提示与警告 |
| JsonPreview | `components/ui/JsonPreview.tsx` | JSON 数据可视化展示 |
| WidgetLayout | `components/layout/WidgetLayout.tsx` | Widget 布局容器 |

### 设计规范遵循

所有 UI 组件必须严格遵循 Apify Design System：

**颜色使用规则**：

| 语义类别 | 使用方式 | 示例 |
|----------|----------|------|
| 文本颜色 | `theme.color.{category}.text` | `theme.color.neutral.text` |
| 背景色 | `theme.color.{category}.background` | `theme.color.primary.background` |
| 交互色 | `theme.color.{category}.action` | `theme.color.primary.action` |
| 边框色 | `theme.color.{category}.border` | `theme.color.neutral.border` |
| 图标色 | `theme.color.{category}.icon` | `theme.color.neutral.icon` |

**状态变体**：

```typescript
// Default → Hover → Active 状态链
background: ${theme.color.primary.action};
&:hover { background: ${theme.color.primary.actionHover}; }
&:active { background: ${theme.color.primary.actionActive}; }
```

**间距规范**：

| 用途 | 可用值 |
|------|--------|
| 元素间间距 | `space4`, `space8`, `space12` |
| 组件内边距 | `space8`, `space12`, `space16` |
| 区域外边距 | `space16`, `space24`, `space32` |
| 大型布局 | `space40`, `space64`, `space80` |

资料来源：[DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md](DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md)

---

## Widget 系统

### Widget 类型

Apify MCP Server 提供三种核心 Widget：

| Widget 名称 | 文件 | 功能描述 |
|-------------|------|----------|
| search-actors-widget | `widgets/search-actors-widget.tsx` | 搜索并浏览 Apify Store 中的 Actors |
| actor-run-widget | `widgets/actor-run-widget.tsx` | 展示 Actor 运行状态与进度 |
| actor-detail-widget | `widgets/actor-detail-widget.tsx` | 显示单个 Actor 的详细信息 |

### Widget 生命周期

```mermaid
sequenceDiagram
    participant Client as MCP 客户端
    participant Server as MCP 服务器
    participant Resource as 资源读取<br/>ui://widget/*
    participant FS as 文件系统
    participant Widget as React Widget
    
    Client->>Server: tools/call (widget tool)
    Server->>Server: 获取 toolOutput
    Server->>Resource: 注册 widget 资源
    Client->>Resource: resources/read (ui://widget/...)
    Resource->>FS: 读取 widget.js
    FS-->>Resource: widget JavaScript 代码
    Resource->>Resource: 包装为 HTML 页面
    Resource-->>Client: HTML 页面 (包含 JS bundle)
    Client->>Widget: 浏览器渲染
    Widget->>Server: 获取 toolOutput props
    Widget-->>Client: 渲染可视化界面
```

资料来源：[src/resources/resource_service.ts](src/resources/resource_service.ts)

### Widget 初始化模式

每个 Widget 采用统一的初始化模式：

```typescript
// 1. 定义 Wrapper 组件接收工具输出
const ActorDetailWrapper = () => {
    const toolOutput = useWidgetProps<WidgetToolOutput>();
    const details = toolOutput?.details;

    if (!details) {
        return <div>No actor details available</div>;
    }

    return <ActorSearchDetail details={details} />;
};

// 2. 开发/生产环境路由
(async () => {
    if (IS_DEV_BUILD) {
        const { setupActorDetailWidgetDev } = await import("./actor-detail-widget.dev");
        setupActorDetailWidgetDev();
    }
    renderWidget(ActorDetailWrapper);
})();
```

资料来源：[src/web/src/widgets/actor-detail-widget.tsx](src/web/src/widgets/actor-detail-widget.tsx)

---

## Widget 布局组件

`WidgetLayout` 是所有 Widget 的基础容器组件，提供统一的页面结构：

```mermaid
graph LR
    subgraph "WidgetLayout 结构"
        Header["Header (标题 + 操作)"]
        Content["Content (主内容区)"]
        Footer["Footer (可选)"]
    end
    
    Widget["<WidgetLayout>"]
    Widget --> Header
    Widget --> Content
    Widget --> Footer
```

**主要属性**：

| 属性名 | 类型 | 说明 |
|--------|------|------|
| title | string | Widget 标题 |
| actions | ReactNode | 右上角操作区域 |
| children | ReactNode | 主内容区 |
| footer | ReactNode | 底部区域（可选） |

资料来源：[src/web/src/components/layout/WidgetLayout.tsx](src/web/src/components/layout/WidgetLayout.tsx)

---

## 业务组件

### ActorCard 组件

用于展示单个 Actor 的搜索结果卡片：

```typescript
interface ActorCardProps {
    actor: Actor;
}

export const ActorCard: React.FC<ActorCardProps> = (props: ActorCardProps) => {
    const { actor } = props;
    // 渲染 Actor 卡片，包含徽章、统计信息等
};
```

**功能特性**：
- 显示 Actor 名称、描述、图标
- 展示使用量、评分等统计信息
- 集成 Badge 组件显示状态

资料来源：[src/web/src/components/actor/ActorCard.tsx](src/web/src/components/actor/ActorCard.tsx)

### ActorStats 组件

展示 Actor 的关键统计数据：

```typescript
interface ActorStatsProps {
    stats: {
        runsCount?: number;
        rating?: number;
        // 其他统计字段
    };
}
```

**统计维度**：

| 指标 | 说明 |
|------|------|
| runsCount | 运行次数 |
| rating | 平均评分 |
| avgDuration | 平均执行时长 |

资料来源：[src/web/src/components/actor/ActorStats.tsx](src/web/src/components/actor/ActorStats.tsx)

---

## Bundle 优化策略

Widget Bundle 必须保持自包含，但顶层 `@apify/ui-library` 和 `@apify/ui-icons` 的打包成本较高。

### 优化规则

| 策略 | 说明 |
|------|------|
| 优先使用 `dist/src/...` 导入 | 避免导入整个 barrel 文件 |
| 避免重型组件 | 在共享路径使用轻量级本地实现 |
| Markdown 渲染特殊处理 | 变动时需重新测量 bundle 影响 |

### 优化效果

| Widget | 优化前 | 优化后 | 降幅 |
|--------|--------|--------|------|
| actor-run-widget | ~1.86 MB | ~1.16 MB | ~38% |
| actor-detail-widget | ~1.86 MB | ~1.52 MB | ~18% |
| search-actors-widget | ~1.87 MB | ~1.53 MB | ~18% |

资料来源：[res/web-widget-bundle-size.md](res/web-widget-bundle-size.md)

### 导入规范对比

```typescript
// ✅ 优化后的导入方式（推荐）
import { Button } from '@apify/ui-library/dist/src/Button';
import styled from 'styled-components';

// ❌ 不推荐的导入方式
import { Button } from '@apify/ui-library';  // 导入整个库
```

资料来源：[res/web-widget-bundle-size.md](res/web-widget-bundle-size.md)

---

## 开发模式

### 热重载开发

```bash
APIFY_TOKEN='your-apify-token' pnpm run dev
```

开发服务器配置：

| 服务 | 端口 | 说明 |
|------|------|------|
| MCP 服务器 | 3001 | standby 模式 |
| esbuild 开发服务器 | 3226 | widget 热重载 |

### UI 模式

Widget 渲染需要服务器运行在 UI 模式：
- URL 参数：`?ui=true`（如 `/mcp?ui=true`）
- 环境变量：`UI_MODE=true`

### 本地预览

访问 http://localhost:3226/index.html 预览所有可用 Widget：

```html
<a href="/index-actor-search.html" target="_blank">Actor Search Widget</a>
<a href="/index-actor-run.html" target="_blank">Actor Run Widget</a>
```

资料来源：[src/web/index.html](src/web/index.html)

---

## 组件开发规范

### 开发检查清单

在提交 UI 代码前，必须完成以下验证：

1. **Token 审计**：搜索代码中是否存在违规值
   - 颜色：`['"]#[0-9a-fA-F]{3,8}['"]` — 应为 0 处匹配
   - 间距：`['"][0-9]+px['"]` — 应为 0 处匹配

2. **导入检查**：
   - 所有 styled-components 必须导入 `theme` from `@apify/ui-library`
   - 不得有重复组件实现

3. **模式匹配**：
   - 对比相似组件的结构
   - 遵循相同的属性命名约定
   - 使用相同的变体模式

### 组件结构模板

```typescript
// 1. 导入（分组）
import { forwardRef } from 'react';
import styled from 'styled-components';
import { theme } from '@apify/ui-library';

// 2. 常量与类型
export const COMPONENT_VARIANTS = { ... } as const;
type ComponentVariants = ValueOf<typeof COMPONENT_VARIANTS>;

// 3. 样式组件
const StyledWrapper = styled.div`...`;

// 4. 组件实现
export const Component = forwardRef<HTMLElement, Props>((props, ref) => {
    // implementation
});

// 5. Display Name
Component.displayName = 'Component';
```

资料来源：[DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md](DESIGN_SYSTEM_AGENT_INSTRUCTIONS.md)

---

## 总结

Apify MCP Server 的组件库与 Widget 系统是一个分层架构：

- **基础层**：通用 UI 组件严格遵循 Design System，确保一致的用户体验
- **业务层**：ActorCard、ActorStats 等组件封装业务逻辑
- **应用层**：Widget 整合所有组件，提供完整的用户交互功能

通过导入优化和热重载开发支持，系统在保持功能完整性的同时，实现了较好的性能和开发效率。

---

<a id='development-setup'></a>

## 开发环境配置

### 相关页面

相关主题：[项目简介](#project-introduction)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apify/apify-mcp-server/blob/main/README.md)
- [CONTRIBUTING.md](https://github.com/apify/apify-mcp-server/blob/main/CONTRIBUTING.md)
- [package.json](https://github.com/apify/apify-mcp-server/blob/main/package.json)
- [tsconfig.json](https://github.com/apify/apify-mcp-server/blob/main/tsconfig.json)
- [vitest.config.ts](https://github.com/apify/apify-mcp-server/blob/main/vitest.config.ts)
- [src/tsconfig.json](https://github.com/apify/apify-mcp-server/blob/main/src/tsconfig.json)
- [.nvmrc](https://github.com/apify/apify-mcp-server/blob/main/.nvmrc)
- [.env.example](https://github.com/apify/apify-mcp-server/blob/main/.env.example)
</details>

# 开发环境配置

## 概述

本文档介绍 apify-mcp-server 项目的开发环境配置方法。该项目是一个基于 Model Context Protocol (MCP) 的服务器实现，用于与 Apify 平台进行交互。开发环境配置涵盖了 Node.js 版本管理、环境变量设置、项目构建流程、测试框架配置以及代码规范遵循等核心内容。

## 环境要求

### Node.js 版本

项目要求 Node.js 版本为 22 或更高版本。版本号通过 `.nvmrc` 文件进行统一管理：

```text
22
```

资料来源：[.nvmrc]()

推荐使用 nvm (Node Version Manager) 来管理 Node.js 版本，可通过以下命令切换到正确版本：

```bash
nvm use
```

### 包管理器

项目使用 pnpm 作为包管理器。确保本地已安装 pnpm：

```bash
npm install -g pnpm
```

## 环境变量配置

### 必需的环境变量

在项目根目录创建 `.env` 文件，配置以下环境变量：

```text
APIFY_TOKEN="your-apify-token"
```

资料来源：[README.md:10-12]()

`APIFY_TOKEN` 是访问 Apify API 的认证令牌，用于验证用户身份和授权 API 调用。

### 其他配置项

| 环境变量 | 用途 | 示例值 |
|----------|------|--------|
| `APIFY_TOKEN` | Apify API 访问令牌 | `your-apify-token` |
| `APIFY_META_ORIGIN` | 请求来源标识（用于 Standby 模式） | `STANDBY` |

## 项目构建

### 构建流程

项目使用 TypeScript 构建系统。需要先构建项目再运行：

```bash
pnpm run build
```

资料来源：[README.md:14-16]()

构建过程会将 TypeScript 源码编译为 JavaScript，输出到 `dist` 目录。

### TypeScript 配置

项目采用双层 tsconfig 结构：

#### 根目录配置 (`tsconfig.json`)

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true
  }
}
```

资料来源：[tsconfig.json]()

#### 源码目录配置 (`src/tsconfig.json`)

```json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../dist",
    "rootDir": "."
  }
}
```

资料来源：[src/tsconfig.json]()

## 服务器运行模式

项目支持两种 MCP 服务器运行模式：

### HTTP Streamable 模式

通过 Apify CLI 启动 HTTP 流式传输服务器：

```bash
export APIFY_TOKEN="your-apify-token"
export APIFY_META_ORIGIN=STANDBY
apify run -p
```

资料来源：[README.md:19-23]()

服务器启动后暴露在 `http://localhost:3001`，可使用 [MCP Inspector](https://github.com/modelcontextprotocol/inspector) 进行调试。

### 标准输入输出 (stdio) 模式

通过 MCP Inspector 启动标准输入输出模式的服务器：

```bash
export APIFY_TOKEN="your-apify-token"
npx @modelcontextprotocol/inspector node ./dist/stdio.js
```

资料来源：[README.md:29-32]()

Inspector 会显示一个 URL，可在浏览器中打开进行调试。

## 测试配置

### Vitest 测试框架

项目使用 Vitest 作为测试框架，配置文件为 `vitest.config.ts`：

```typescript
// vitest.config.ts 配置示例
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'node',
    globals: true,
  },
});
```

资料来源：[vitest.config.ts]()

### 运行测试

| 命令 | 描述 |
|------|------|
| `pnpm test` | 运行所有测试 |
| `pnpm test:watch` | 监听模式运行测试 |
| `pnpm test:coverage` | 运行测试并生成覆盖率报告 |

## 代码规范

### 分支命名规范

功能分支必须遵循 `type/short-description` 格式，其中 type 必须匹配 Conventional Commit 类型：

```text
feat/add-dataset-tool
fix/connection-timeout
chore/update-dependencies
refactor/tool-registry
docs/update-readme
```

资料来源：[CONTRIBUTING.md:8-17]()

### 提交信息规范

所有提交和 PR 标题必须遵循 [Conventional Commits](https://www.conventionalcommits.org/) 格式，**type** 和 **scope** 均为必填项：

```text
feat: Add new tool for fetching actor details
feat!: Migrate to new MCP SDK version [internal]
fix: Handle connection errors gracefully
refactor: Improve type definitions [ignore]
chore: Update dependencies
```

资料来源：[CONTRIBUTING.md:19-32]()

使用 `!` 表示破坏性变更，例如 `feat!: ...`。

### 变量命名规范

| 命名类型 | 规范 | 示例 |
|----------|------|------|
| 常量 | 全大写下划线分隔 | `WIDGET_REGISTRY`, `LOG_LEVEL_MAP` |
| 金额/成本 | 添加单位后缀 | `externalCostUsd`, `intervalMillis` |
| 日期/时间 | 使用 `At` 后缀 | `updateStartedAt`, `paidAt` |
| Zod 验证器 | 使用 `Validator` 后缀 | `InputValidator` |
| 用户可见文本 | 使用品牌术语 `Actor`（大写） | Actor、Actor Run |

资料来源：[CONTRIBUTING.md:42-47]()

### 字符串格式化

- 短的一行字符串使用单引号
- 多行或超出 `max-len` 的字符串使用 `dedent` 模板字面量
- 避免在 `dedent` 内插值从列 0 开始的值（如 `JSON.stringify` 输出）

资料来源：[CONTRIBUTING.md:50-58]()

## 集成测试覆盖

项目维护了 MCP 协议各端点的测试覆盖情况，关键测试项包括：

| MCP 协议端点 | 状态 |
|--------------|------|
| `tools/list` | ✅ 已覆盖（约 30 个用例） |
| `tools/call` 正常路径 | ✅ 已覆盖 |
| `tools/call` 错误处理 | ✅ 已覆盖 |
| `prompts/list` | ✅ 已覆盖 |
| `prompts/get` 正常路径 | ✅ 已覆盖 |
| `logging/setLevel` | ❌ 缺少集成测试 |
| `ping` | ❌ 缺少集成测试 |
| `resources/list` | ❌ 仅单元测试 |
| `resources/read` | ❌ 仅单元测试 |

资料来源：[res/integration_test_coverage_audit.md]()

## 快速启动流程

```mermaid
graph TD
    A[安装 Node.js 22+] --> B[安装 pnpm]
    B --> C[克隆仓库]
    C --> D[创建 .env 文件配置 APIFY_TOKEN]
    D --> E[运行 pnpm install]
    E --> F[运行 pnpm run build]
    F --> G[选择运行模式]
    G --> H[HTTP Streamable 模式]
    G --> I[stdio 模式]
    H --> J[使用 MCP Inspector 调试]
    I --> J
```

## 未认证访问

当 `tools` 查询参数仅包含明确允许未认证使用的工具时，托管服务器允许无令牌访问。当前允许的工具列表：

| 工具名称 | 描述 |
|----------|------|
| `search-actors` | 搜索 Actors |
| `fetch-actor-details` | 获取 Actor 详情 |
| `search-apify-docs` | 搜索 Apify 文档 |
| `fetch-apify-docs` | 获取 Apify 文档内容 |

资料来源：[README.md:35-38]()

使用示例：
```
https://mcp.apify.com?tools=search-actors
```

## Canary 版本发布

Apify MCP 服务器分为两个代码仓库：

- 本仓库 (`apify-mcp-server`)：核心 MCP 逻辑
- 私有仓库 (`apify-mcp-server-internal`)：托管服务器

创建 canary 版本需要在 PR 分支上添加 `beta` 标签。

资料来源：[README.md:41-47]()

## 总结

开发环境配置的核心要点：

1. **环境版本**：Node.js 22+，pnpm 作为包管理器
2. **认证配置**：在 `.env` 文件中设置 `APIFY_TOKEN`
3. **构建流程**：`pnpm run build` 编译 TypeScript
4. **运行模式**：支持 HTTP Streamable 和 stdio 两种 MCP 协议传输方式
5. **代码规范**：遵循 Conventional Commits 规范，变量命名需符合类型约定

---

---

## Doramagic 踩坑日志

项目：apify/apify-mcp-server

摘要：发现 22 个潜在踩坑项，其中 5 个为 high/blocking；最高优先级：安装坑 - 来源证据：fix: Allow calling MCP server actors in normal (one-shot) mode。

## 1. 安装坑 · 来源证据：fix: Allow calling MCP server actors in normal (one-shot) mode

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：fix: Allow calling MCP server actors in normal (one-shot) mode
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_be82315ed0f441ba9d942931d846d78c | https://github.com/apify/apify-mcp-server/issues/857 | 来源类型 github_issue 暴露的待验证使用条件。

## 2. 配置坑 · 来源证据：Remove the flat-fields back-compat shim from `_meta.x402` once all consumers read `accepts[]`

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Remove the flat-fields back-compat shim from `_meta.x402` once all consumers read `accepts[]`
- 对用户的影响：可能影响升级、迁移或版本选择。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_8ec6ff22f24a4bb18b439177f4a8c270 | https://github.com/apify/apify-mcp-server/issues/892 | 来源类型 github_issue 暴露的待验证使用条件。

## 3. 安全/权限坑 · 来源证据：Do not include the rag web browser when ?payment=x402

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Do not include the rag web browser when ?payment=x402
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_23bafe4901554148896241f0a1e183b0 | https://github.com/apify/apify-mcp-server/issues/875 | 来源类型 github_issue 暴露的待验证使用条件。

## 4. 安全/权限坑 · 来源证据：Perf: `search-actors` tools returns huuuge `inputFields` object

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Perf: `search-actors` tools returns huuuge `inputFields` object
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_af51cb3cbcb3479fbbdf27cedef734aa | https://github.com/apify/apify-mcp-server/issues/888 | 来源类型 github_issue 暴露的待验证使用条件。

## 5. 安全/权限坑 · 来源证据：feat(telemetry): track tool result size in bytes

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：feat(telemetry): track tool result size in bytes
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_9c2ef77c88914458910ae67d9f903931 | https://github.com/apify/apify-mcp-server/issues/838 | 来源类型 github_issue 暴露的待验证使用条件。

## 6. 身份坑 · 仓库名和安装名不一致

- 严重度：medium
- 证据强度：runtime_trace
- 发现：仓库名 `apify-mcp-server` 与安装入口 `@apify/actors-mcp-server` 不完全一致。
- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。
- 复现命令: `npx @apify/actors-mcp-server`
- 防护动作: 页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。
- 证据：identity.distribution | github_repo:911256711 | https://github.com/apify/apify-mcp-server | repo=apify-mcp-server; install=@apify/actors-mcp-server

## 7. 安装坑 · 来源证据：chore(core): collapse array indices in dataset fields to prevent nextStep schema bloat

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：chore(core): collapse array indices in dataset fields to prevent nextStep schema bloat
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_9c05c17621e3443dad6175f21db31a34 | https://github.com/apify/apify-mcp-server/issues/894 | 来源类型 github_issue 暴露的待验证使用条件。

## 8. 安装坑 · 来源证据：feat: Add structured output to remaining storage tools

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：feat: Add structured output to remaining storage tools
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_c9b7c39f3e8f43e88ee52c2c8ae94b01 | https://github.com/apify/apify-mcp-server/issues/884 | 来源类型 github_issue 暴露的待验证使用条件。

## 9. 安装坑 · 来源证据：feat: migrate direct actor tools to canonical RunResponse shape

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：feat: migrate direct actor tools to canonical RunResponse shape
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_6b304ff2763849fe9b4678cc7bf9f5b2 | https://github.com/apify/apify-mcp-server/issues/852 | 来源类型 github_issue 暴露的待验证使用条件。

## 10. 安装坑 · 来源证据：test: Consolidate duplicated MCP server test fixtures

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：test: Consolidate duplicated MCP server test fixtures
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_5a7a24d9e8ce42468a7775a54dfa8ca6 | https://github.com/apify/apify-mcp-server/issues/847 | 来源类型 github_issue 暴露的待验证使用条件。

## 11. 配置坑 · 来源证据：feat: Dataset tools correctness and coverage

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：feat: Dataset tools correctness and coverage
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_3fa86b498f66434a8f247c1b63fb56c9 | https://github.com/apify/apify-mcp-server/issues/784 | 来源类型 github_issue 暴露的待验证使用条件。

## 12. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作: 假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:911256711 | https://github.com/apify/apify-mcp-server | README/documentation is current enough for a first validation pass.

## 13. 运行坑 · 来源证据：chore: Add mixpanel analytics for storage tools + error rates

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：chore: Add mixpanel analytics for storage tools + error rates
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_03dbd8daa0c840d690bddb1d52e189c1 | https://github.com/apify/apify-mcp-server/issues/887 | 来源类型 github_issue 暴露的待验证使用条件。

## 14. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作: 维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:911256711 | https://github.com/apify/apify-mcp-server | last_activity_observed missing

## 15. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作: 下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:911256711 | https://github.com/apify/apify-mcp-server | no_demo; severity=medium

## 16. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作: 评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:911256711 | https://github.com/apify/apify-mcp-server | no_demo; severity=medium

## 17. 安全/权限坑 · 来源证据：[Bug]: Inconsistent `search-actors` schema and results

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: Inconsistent `search-actors` schema and results
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_364bc036f84b42e8b7be6534cb76381e | https://github.com/apify/apify-mcp-server/issues/889 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 18. 安全/权限坑 · 来源证据：design: Calibrate get-dataset-schema output detail

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：design: Calibrate get-dataset-schema output detail
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_8b7a4266d8eb4298919b5cb2a58fa420 | https://github.com/apify/apify-mcp-server/issues/882 | 来源类型 github_issue 暴露的待验证使用条件。

## 19. 安全/权限坑 · 来源证据：refactor: Extract storage tool helpers

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：refactor: Extract storage tool helpers
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_496f0061952341728e4222b961251325 | https://github.com/apify/apify-mcp-server/issues/890 | 来源类型 github_issue 暴露的待验证使用条件。

## 20. 安全/权限坑 · 来源证据：tools/list response contains `type: "unknown"` in an input schema — rejected by ajv-based MCP clients (LibreChat)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：tools/list response contains `type: "unknown"` in an input schema — rejected by ajv-based MCP clients (LibreChat)
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_77fae88d35e2486d8125a2ecea9abdc7 | https://github.com/apify/apify-mcp-server/issues/738 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 21. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作: issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:911256711 | https://github.com/apify/apify-mcp-server | issue_or_pr_quality=unknown

## 22. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作: 发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:911256711 | https://github.com/apify/apify-mcp-server | release_recency=unknown

<!-- canonical_name: apify/apify-mcp-server; human_manual_source: deepwiki_human_wiki -->
