内容
Analytics MCP 工作器
[Zoho Analytics](https.zoho.com [API v2](www.zoho.com/analytics/api/v2/introduction.html) 以 **远程 MCP 服务器形式公开,运行于 **Cloudflare Worker**(式传输的 HTTP +构建于 [`agents://github.com/cloudflare) 的 `Mcp 上。
其客户端Zoho Analytics v2所有 161 个(已针对 Zo[官方 OpenAPI https://github.comho/analytics-oas)),通过 **144 个公开 — 发现、数据 API、异步/批量批量 API、建模(表、、报告、列、公式、文件夹、、依赖项)、工作区管理、共享和协作、管理员)、用户管理、发布和嵌入(URL灯片)、电子邮件计划、变量、收藏夹、数据源同步、模板导出和 **AutoML** — 除了原始 API 缺乏的便利功能:一次调用 **工作区模式映射**、一个端到端的 **SQL 查询助手**,为您驱动异步导出作业,有界并发批量读取,有界作业轮询和破坏性操作上的 `dry_run` 预览。工具定义位于 [`src/tools.ts`](src/tools.ts),Zoho Analytics REST 客户端位于 [`src/zohoanalytics.ts`](src/zohoanalytics.ts);两者都是与传输无关的,因此每个构建都共享相同的工具表面。设置 `MCP_READONLY=true` 以仅注册约 51 个读取工具。
此存储库提供了 **从同一代码部署的两个版本**:
| 工作器 | 认证 | 从哪里使用 | 入口 |
|--------|------|-------------|-------|
| **`zoho-analytics-mcp`** | 静态持有者令牌 | Claude Code、Claude Desktop、程序化 | [`src/index.ts`](src/index.ts) · [`wrangler.jsonc`](wrangler.jsonc) |
| **`zoho-analytics-mcp-oauth`** | OAuth 2.1(单用户通行短语) | **Claude.ai 网页** 自定义连接器 | [`src/oauth.ts`](src/oauth.ts) · [`wrangler.oauth.jsonc`](wrangler.oauth.jsonc) |
> **状态:** 两个部署都经过类型检查、打包并通过测试(`npm audit` = 0 个漏洞)。机密信息通过 `wrangler secret put` 设置,**从不** 提交。
---
## 目录
- [架构](#架构)
- [端点](#端点 [认证](#认证)
工具](#工具)
- [Zoho Analytics API ho-analytics-api-覆盖)
- [配置)
- [获取 Zo 凭证](#获取-oauth-凭证)
部署](#部署)
](#验证)
- [测试](#测试)
-客户端](#连接客户端 [Claude Code](#claude-code) · [ Desktop](#claude-desktop [Claude Webaude-web) · [程序化](#程序化)
OAuth 工作器(Claude.ai 网页)-工作器claudeai)
- [注意事项](#注意事项)
- [](#项目布局)
---
架构
```
客户端 者工作器(src/index.ts)
Claude Desktop / curl ── Authorization: Bearer <M_TOKEN> ──┐ │
Claude.ai ── OAuth 2.1(通行短语─ oauth 工作器/oauth.ts) ─ ▼
ZohoAnalyticsMCP(Agent,Durable Object)
• registerTools(server, client) ← tools • ZohoAnalyticsClient ← zohoanalytics.ts
│
从刷新令牌中颁发访问令牌(accounts.zoho.*),
然后 Authorization: Zoho-oauthtoken <access_token>
ZANALYTICS-ORGID: <org id>
▼
Zoho Analytics REST API v2
```
- **`McpAgent` + Durable Object.** MCP 会话状态存储在 Cloudflare Durable Object(SQLite 支持,迁移 `v1`)中。两个工作器都将其绑定为 `MCP_OBJECT` → `ZohoAnalyticsMCP` 类。
- **共享工具层。** `registerTools()` 和 `ZohoAnalyticsClient` 是普通的 TypeScript,没有特定的 Worker 导入,因此持有者工作器和 OAuth 工作器共享它们。
- **OAuth 令牌管理。** Zoho 访问令牌每小时过期,因此客户端存储刷新令牌 + 客户端 ID/密钥并颁发/缓存访问令牌,自动刷新和重试 `401`。
- **精简捆绑。** 仅导入 `agents/mcp` 服务器路径;`ai`/`react` 的 peer 依赖从不被捆绑到达。
---
##者工作器zoho-analytics-mcp`):
| 方法 | 路径 | 认证 | 目的 |
|--------|----------------|--------|------------------------------------------|
| `GET` | `/` | 无 | 健康检查 → `zoho-analytics-mcp 工作器:正常` |
| `POST` | `/mcp` | 持有者 | MCP 可流式传输的 HTTP(现代客户端) |
| `GET` | `/sse` | 持有者 | MCP SSE(旧客户端) |
OAuth 工作器(`zoho-analytics-mcp-oauth`)— 参见 [OAuth 工作器](#oauth-工作器claudeai-网页).
---
## 认证
两个层次,分别保持:
1. **连接器认证 — 谁可以调用此 MCP 服务器。**
- **持有者工作器** 由 **共享持有者令牌** (`MCP_AUTH_TOKEN`) 保护:失败关闭(无机密 → 所有 401),恒定时间比较。适用于程序化使用、`mcp-remote`、Claude Code/Desktop。
- **OAuth 工作器** 通过 [`@cloudflare/workers-oauth-provider`](https://github.com/cloudflare/workers-oauth-provider) 实现 **OAuth 2.1** (PKCE + 动态客户端注册),在同意屏幕上由单个共享 **通行短语** (`APP_PASSPHRASE`) 保护 — 这是 Claude.ai 网页接受的唯一模型。
2. **Zoho 认证 — 服务器如何调用 Zoho Analytics。** 服务器持有您的 Zoho **刷新令牌** + **客户端 ID/密钥** (`ZOHO_*` 机密) 并颁发短时访问令牌,在匹配的账号域 (`accounts.zoho.<dc>/oauth/v2/token`),将它们作为 `Authorization: Zoho-oauthtoken <token>` 与 `ZANALYTICS-ORGID` 头一起发送。令牌缓存在内存中并自动刷新;`401` 触发一次透明的刷新和重试。参见 [获取 Zoho OAuth 凭证](#获取zoho-oauth-凭证).
**数据中心。** 将 `ZOHO_DC` 设置为您的 Zoho 账户所在的数据中心。从中解析 API 主机和 OAuth 主机:
| `ZOHO_DC` | API 主机 | 账号(OAuth)主机 |
|-----------|----------|------------------------|
| `com`(默认) | `analyticsapi.zoho.com` | `accounts.zoho.com` |
| `eu` | `analyticsapi.zoho.eu` | `accounts.zoho.eu` |
| `in` | `analyticsapi.zoho.in` | `accounts.zoho.in` |
| `au` | `analyticsapi.zoho.com.au` | `accounts.zoho.com.au` |
jp` | `analyticszoho.jp `accounts.zoho.jp` |
| `sa` | `analyticsapi.zoho.sa` | `accounts.zoho.sa` |
| `ca` | `analyticsapi.zohocloud.ca` | `accounts.zohocloud.ca` |
| `uk` | `analyticsapi.zoho.uk` | `accounts.zoho.uk` |
| `cn` | `analyticsapi.zoho.com.cn` | `accounts.zoho.com.cn` |
---
## 工具
所有工具都调用外部服务(WorldHint: true`)。ID(`workspace_id`、`view_id`)来自发现工具。筛选器使用 Zoho 的 `criteria` 语法 — 完全限定的、双引号的标识符,带有单引号值,例如 `"Sales"."Region"='East### 发现和元数据(只读)
| 工具 | 目的 | 输入 |
|------|---------|-------|
| `zoho_whoami` | 健康检查 — 确认 OAuth 凭证有效;列出可访问的组织;回显配置的组织 ID + 数据中心 |
| `zohos` |令牌可访问的组织(查找) || `zohospaces` | 列出工作区(所有者和紧凑名称 | `verbose?| `zoho_get_workspace_details` |区的详细信息 |_id` |
| `zoho_list_views`出工作区中的表、查询表、图表、数据透视仪表盘);按类型/关键词过滤 | `workspace_id`、`view_types?`、`keyword?`?` |
| `zoho_get_view_details某个视图的详细信息;默认包含列 | `view_id`、`with_columns?` `zoho_get_metadata` | 按名称区/视图 + ID | `workspace_nameview_name?` `zoho_describe_workspace` | **** — 列出获取每个表的列(有界并发),以便在查询前了解 | `workspace_idinclude_columns?`_views?`、`?` |
### 读取和查询
| 目的 | 类别 |
|-------|-------|
| `zoho_query_data`主要工具** — 运行临时 SQL `SELECT从 SQL 创建异步批量导出作业,轮询其完成,下载和解析行 | `workspace_id`、`sql_query`、`max_rows?`、`timeout` | 只读 `zoho_export | 同步导出表的行/视图(可选过滤/投影)为解析的行 | `workspace_idview_id`、``、`selected_columns、`response_format?_rows?`读 |
| `zoho_create_export_job` | 为大结果启动** 导出( 或按视图);job_id` | `workspace_id`、`sql_query?`/`view`、`response_format、`criteria?` | 只读 · 不幂等 |
| `zoho_get_export_job` | 检查导出作业(`1001`/`1002` 运行中 · `1003` **失败** · `1004` 完成 · `1005` 无效)并可选下载其 `workspace_id`、`job_id``、`max` | 只读 |
| `zoho_job` | 检查 + 摘要workspace_id`、`job_id` | 只 **同步 vs异步导出。**ho_export_data`且方便的,但 Zoho 不允许用于超过,000,的视图、实时和 Dashboard-Table 视图。对于 以及临时 SQL `zoho_query(内联等待)或 `zoho_job` + `zoho_get_export_job结果太大而)。
### 由 `MCP_READONLY` 控制)
当 `MCP_READ 时,不注册 — 它们出现在 `tools/list。
| 工具 | 目的 | 输入 | 类别 |
|------||
| `_add_row` | 向表中添加一行 |_id`、`view_id`、`columns`、`?`、`?` | | `zoho_update_rows` | 更新匹配` 的行(或带有显式 `` 的所有`add_if` 会进行插入workspace_id`、``、`columnscriteria?`、`update_all_rows?`、`_exist?dry_run?`破坏性** |
zoho_delete_rows` | 删除匹配 `criteria` 的行(或带有显式 `delete_all_rows` 的所有行) | `workspace_id`、`view_id`、`criteria?`、`delete_all_rows?`、`dry_run?` | **破坏性** |
| `zoho_import_data` | 将 CSV/JSON 文本批量导入表中:`append` / `truncateadd`(替换)/ `updateadd`(插入) 。默认情况下等待作业完成 | `workspace_id`、`view_id`、`data`、`file_type?`、`import_type?`、`matching_columns?`、`auto_identify?`、`on_error?`、`wait?`、`dry_run?` | **破坏性** |
| `zoho_create_workspace` | 创建新的工作区(数据库) | `workspace_name`、`workspace_desc?` | 写入 |
| `zoho_create_table` | 创建带有列设计(类型化列)的表 | `workspace_id`、`table_name`、`columns[]`、`description?`、`folder_name?`、`dry_run?` | 写入 |
| `zoho_delete_view` | 将视图/表移到 **回收站**(使用 `zoho_restore_view` 恢复;使用 `zoho_delete` ) | `workspace、`view_id`、`dry_run?`破坏性** |
**安全性:** 破坏性工具(删除行/列/文件夹/工作区、删除共享/用户等)接受 `dry_run` 以在任何内容的情况下预览。 “更新/删除所有行”需要显update_all_rowsdelete_all_rows` — 不允许空`truncateadd导入会警告它们所有数据。 **从不** 自动重试。
### 建模和模式(写入)
重塑数据查询表:`zoho_get_query_tableho_create_query_table`、`zoho_edit_query_table`。报告:`zoho_create_report`、`zoho_update_report`。列:`zoho_add_column`、`zoho_rename_column`、`zoho_delete_column`、`zoho_hide_columns`、`zoho_show_columns`、`zoho_reorder_columns`、`zoho_add_lookup`、`zoho_remove_lookup`。公式:`zoho_add_formula_column`、`zoho_delete_formula、`zoho_add_aggregate_formula`ho_delete_aggregate_formula`。文件夹:`zoho_create_folder`、`zoho_`、`zo_folder`。视图`zoho_、`zo_view`、`zoho_move_views_to_folder`、`zoho_sort_data`、`zoho_create_table_from_data`,以及回收站操作 `zoho_get_trash` · `zoho_restore_view` · `zoho_delete_trash_view`。工作区管理员zoho_workspace`、`zoho_delete_workspace`ho_copy_workspace`、`zoho_copy_views`、`zoho_regenerate_workspace_secret_key`(轮换/使密钥失效)。另外读取 `zoho_get_workspace_secret_key`、`zoho_list_folders`、`zoho_get_view_metadata`、`zoho_list_dashboards`、`zoho_list_recent_views`、`zoho_list_datasources` 共享和`zoho_share、`zoho_update_shared_views`、`zoho_remove_share`、`_get_shared_details`ho_get_my_permissions`。组:`zoho_list_groups`、`zoho_create_group`、`zoho_rename_group`、`zoho_delete_group`、`zoho_add_group_members`、`zoho_remove_group_members`。管理员:`zoho_get_workspace_admins`、`zoho_add_workspace`、`zoho_admins`ho_get_org_admins`。权限是映射(需要 `read`;还有 `export`、`vud`、`addRow`、`drillDown`、`share`,...)。
### 用户管理
组织:`zoho_list_users`、`zoho_add_users`、`zoho_remove_users`、`zoho_set_users_status`、`zoho_change_user_role`(USER/VIEWER/ORGADMIN),以及 `zoho_get_subscription` 和 `zoho_get_resources`。工作区:`zoho_list_workspace_users`、`zoho_add_workspace_users`、`zoho_remove_workspace_users`、`zoho_change_workspace_user_status`、`zoho_change_workspace_user_role`(USER/WORKSPACEADMIN/自定义)。
### 发布和嵌入
`zoho_get_view_url`、`zoho_get_embed_url`、`zoho_get_private_url`、`zoho_create_private_url`、`zoho_remove_private_url`、`zoho_make_view_public`、`zoho_remove_public`、`zoho_get_publish_config`、`zoho_update_publish_config`。幻灯片:`zoho_list_slideshows`、`zoho_get_slideshow`、`zoho_create_slideshow`、`zoho_update_slideshow`、`zoho_delete_slideshow`、`zoho_get_slideshow_url`。
### 变量
`zoho_list_variables`、`zoho_get_variable`、`zoho_create_variable`、`zoho_update_variable`、`zoho_delete_variable`。
### 依赖项、公式和分析
读取:`zoho_get_dependents`(视图/列)、`zoho_list_formula_columns`、`zoho_list_aggregate_formulas`、`zoho_get_aggregate_formula_value`、`zoho_get_aggregate_formula_dependents`、`zoho_get_last_import_details`、`zoho_export_workspace_template`(base64 ZIP)。写入:`zoho_edit_formula_column`、`zoho_edit_aggregate_formula`、`zoho_copy_formulas`(跨工作区/组织)、`zoho_create_similar_views`、`zoho_auto_analyse`(视图或列)、文件夹放置(`zoho_make_default_folder`、`zoho_move_folder`、`zoho_reorder_folder`).
### 收藏夹、默认值和数据源
`zoho_set_favorite_workspace`、`zoho_set_favorite_view`、`zoho_set_default_workspace`、`zoho_set_workspace_domain_access`(白名单)、`zoho_sync_datasource`、`zoho_update_datasource_connection`、`zoho_refetch_view_data`。
### 电子邮件计划
`zoho_list_email_schedules`、`zoho_create_email_schedule`、`zoho_update_email_schedule`、`zoho_delete_email_schedule`、`zoho_trigger_email_schedule`(发送真实电子邮件;`dry_run`)、`zoho_set_email_schedule_status`。
### AutoML
读取:`zoho_list_automl_analysis`(组织/工作区)、`zoho_get_automl_analysis`、`zoho_list_automl_deployments`、`zoho_automl_whatif`(单个输入的预测)。写入:`zoho_create_automl_analysis`(训练模型 — REGRESSION/CLASSIFICATION/CLUSTERING)、`zoho_create_automl_deployment`、`zoho_run_automl_deployment`,以及分析/模型/部署的删除(所有操作均带有 `dry_run`)。
### 操作模式
- **只读部署。** 设置 `MCP_READONLY=true` 以进行报告/仪表板连接器 — 仅注册发现、查询和读取工具。
- **审计跟踪。** 每个状态更改的调用都在 HTTP 层记录 (`[zoho-analytics-mcp /workspaces/.../rows` + 路径),并且写入工具在资源名称/计数(工作区/表/列名称、电子邮件计数 — 绝不包括行数据或电子邮件地址)处添加一个操作级审计行,通过 `wrangler tail见。
- **弹性。** 幂等 GET 请求在 `429`/`5xx` 时重试,Retry-After` 感知退避;写入请求绝不自动重试;批量读取使用有界并发来尊重 Zoho 的每分钟频率限制。
---
## Zoho Analytics API 支持
这些工具映射到 Zoho Analytics v2 端点(相对于 `https://<api-host>/restapi/v2`)。操作选项在 `CONFIG` 查询参数中(一个 URL 编码的 JSON 对象);响应使用 `{status, summary, data}` 信封,除了导出/下载端点,它们会流式传输原始文件字节。
| 工具 | 方法 & 路径 |
|------|---------------|
| `zoho_get_orgs` / `zoho_whoami` | `GET /orgs` |
| `zoho_list_workspaces` | `GET /workspaces` |
| `zoho_get_workspace_details` | `GET /workspaces/{workspace-id}` |
| `zoho_list_views` | `GET /workspaces/{workspace-id}/views` |
| `zoho_get_view_details` / `zoho_describe_workspace` | `GET /views/{view-id}` (`withInvolvedMetaInfo`) |
| `zoho_get_metadata` | `GET /metadetails` |
| `zoho_export_data` | `GET /workspaces/{workspace-id}/views/{view-id}/data` |
| `zoho_add_row` | `POST /workspaces/{workspace-id}/views/{view-id}/rows` |
| `zoho_update_rows` | `PUT /workspaces/{workspace-id}/views/{view-id}/rows` |
| `zoho_delete_rows` | `DELETE /workspaces/{workspace-id}/views/{view-id}/rows` |
| `zoho_query_data` / `zoho_create_export_job` (SQL) | `GET /bulk/workspaces/{workspace-id}/data` (`sqlQuery`) |
| `zoho_create_export_job` (view) | `GET /bulk/workspaces/{workspace-id}/views/{view-id}/data` |
| `zoho_get_export_job` | `GET /bulk/workspaces/{workspace-id}/exportjobs/{job-id}` (+ `/data` to download) |
| `zoho_import_data` | `POST /bulk/workspaces/{workspace-id}/views/{view-id}/data` (multipart `FILE`) |
| `zoho_get_import_job` | `GET /bulk/workspaces/{workspace-id}/importjobs/{job-id}` |
| `zoho_create_workspace` | `POST /workspaces` |
| `zoho_create_table` | `POST /workspaces/{workspace-id}/tables` |
| `zoho_delete_view` | `DELETE /workspaces/{workspace-id}/views/{view-id}` |
上述表格列出了核心数据/元数据端点;其他 v2 接口也被覆盖 - 建模 (`/querytables`, `/reports`, `/views/{id}/columns`, `/customformulas`, `/aggregateformulas`, `/folders`, `/views/{id}/saveas`, `/trash/{id}`, `/similarviews`, `/autoanalyse`, …),工作区管理员 (`/secretkey`, 复制/重命名/删除,`/views/copy`, `/template/data`,收藏/默认/`/wlaccess`),共享 (`/share`, 每个视图 `/views/{id}/share` 更新,`/groups`, `/admins`, `/orgadmins`),用户管理 (`/users`, `/users/role`, `/subscription`, `/resources`, `/workspaces/{id}/users`),发布/嵌入 (`/publish`, `/publish/embed`, `/publish/privatelink`, `/publish/public`, `/slides`),电子邮件计划 (`/emailschedules` CRUD + 触发器),数据源 (`/datasources`, `/datasource/{id}/sync`),`/variables`,和 AutoML (`/automl/...` 分析,模型,部署,假设) — 参见上面的匹配工具类别和 [`src/zohoanalytics.ts`](src/zohoanalytics.ts) 中的 `ZohoAnalyticsClient` 方法。
**覆盖范围: 161/161 端点**,跨越 Zoho 的七个已发布的 OpenAPI 规范文件(数据,批量,元数据,建模,共享,用户管理,嵌入),通过将每个规范的 `(method, path)` 对与客户端进行差异验证。完整 API: <https://www.zoho.com/analytics/api/v2/introduction.html> · 规范: <https://github.com/zoho/analytics-oas>.
---
## 配置
通过 `npx wrangler secret put <NAME>`(秘密)或 `[vars]` 块(非秘密)设置。添加 `-c wrangler.oauth.jsonc` 以定位 OAuth 工作器。
| 名称 | 工作器 | 必需 | 目的 |
|------|--------|----------|---------|
| `ZOHO_CLIENT_ID` | 两个 | ✅ | Zoho OAuth 客户端 ID |
| `ZOHO_CLIENT_SECRET` | 两个 | ✅ | Zoho OAuth 客户端秘密(可能是每个数据中心) |
| `ZOHO_REFRESH_TOKEN` | 两个 | ✅ | 长寿命刷新令牌 (`access_type=offline`) |
| `ZOHO_ORG_ID` | 两个 | ✅ | `ZANALYTICS-ORGID` — 从 `zoho_get_orgs` 获取 |
| `MCP_AUTH_TOKEN` | bearer | ✅ | 共享 bearer 客户端发送为 `Authorization: Bearer <…>` |
| `APP_PASSPHRASE` | oauth | ✅ | OAuth 同意屏幕上输入的通行短语 |
| `OAUTH_KV` (绑定) | oauth | ✅ | 存储 OAuth 授权/注册的 KV 命名空间 |
| `ZOHO_DC` | 两个 | 可选 | 数据中心: `com` (默认) `eu in au jp sa ca uk cn` |
| `TOKEN_KV` (绑定) | bearer | 推荐 | 在所有会话中共享一个 Zoho 访问令牌的 KV 命名空间(OAuth 工作器自动重用 `OAUTH_KV`)。如果没有它,每个新的 MCP 会话都会创建一个令牌 - Zoho 在每 10 分钟限制令牌创建约 10 个,因此 >10 个新会话在 10 分钟内将开始出现身份验证失败。 `npx wrangler kv namespace create TOKEN_KV`,然后取消注释 [wrangler.jsonc](wrangler.jsonc) 中的块。 |
| `ZOHO_ACCESS_TOKEN` | 两个 | 可选 | 静态访问令牌(每小时过期;仅用于测试 - 跳过刷新) |
| `ZOHO_ANALYTICS_BASE_URL` | 两个 | 可选 | 覆盖 API 主机 |
| `ZOHO_ACCOUNTS_BASE_URL` | 两个 | 可选 | 覆盖帐户/OAuth 主机 |
| `ZOHO_MAX_RETRIES` | 两个 | 可选 | 幂等调用的最大重试次数(默认 `3`) |
| `MCP_READONLY` | 两个 | 可选 | `true` ⇒ 仅注册读取工具 |
| `MCP_CORE` | 两个 | 可选 | `true` ⇒ 仅注册精选的 ~26 个日常工具(日常 LLM 使用的最佳工具选择准确性) |
| `EXPORTS` (绑定)+ `PUBLIC_BASE_URL` | bearer | 可选 | R2 溢出:截断的导出数据永久保留并返回 24 小时有签名的 `/download/` URL(在仪表板中启用 R2 一次,然后在 wrangler.jsonc 中取消注释)。 |
| `USAGE` (绑定)| bearer | 可选 | 每个工具的 Worker Analytics 引擎使用情况遥测 |
| `RATE_LIMITER` (绑定)| bearer | 可选 | 每 IP 洪水上限(300 req/min) |
| `ZOHO_MULTI_USER` | oauth | 可选 | `true` ⇒ 同意屏幕上的每个用户 Zoho 登录而不是共享通行短语;每个用户的刷新令牌存储在加密的授权属性中(需要基于服务器的 Zoho 客户端,带有重定向 `<origin>/zoho/callback`) |
---
## 获取 Zoho OAuth 凭证
一次性设置以生成 `ZOHO_CLIENT_ID`, `ZOHO_CLIENT_SECRET` 和 `ZOHO_REFRESH_TOKEN`。在**您的数据中心 API 控制台**(例如 `api-console.zoho.eu` for EU)上执行此操作。
1. **注册客户端** 在 <https://api-console.zoho.com/> → **自有客户端** (适用于单个用户服务器的最简单方式)或基于服务器的应用程序。记下**客户端 ID** 和**客户端秘密**。
2. **选择范围。** 对于完整的工具表面,请使用 `ZohoAnalytics.fullaccess.all`,或范围缩小到:
`ZohoAnalytics.data.all,ZohoAnalytics.metadata.read,ZohoAnalytics.modeling.all` (删除 `data.create/update/delete` 和 `modeling.all` 以获取只读连接器)。
3. **生成授权令牌(代码)**,使用 `access_type=offline` (自有客户端:“生成代码”;或使用 `response_type=code&access_type=offline` 运行 `/oauth/v2/auth` 同意流程)。
4. **将代码交换为刷新令牌** (一次)在您的帐户域名:
```bash
curl -X POST "https://accounts.zoho.com/oauth/v2/token" \
-d "grant_type=authorization_code" \
-d "client_id=$ZOHO_CLIENT_ID" \
-d "client_secret=$ZOHO_CLIENT_SECRET" \
-d "code=<grant_token>"
# → { "access_token": "...", "refresh_token": "...", "expires_in": 3600 }
```
保存 `refresh_token` — 即 `ZOHO_REFRESH_TOKEN`。(服务器会自动从中刷新访问令牌;刷新令牌本身不会过期,除非被撤销。)
5. **查找您的组织 ID**,在部署后调用 `zoho_get_orgs` / `zoho_whoami` 工具,并将其设置为 `ZOHO_ORG_ID`。
---
## 部署
```bash
npm install
# Zoho 凭证 - 在提示符下粘贴每个值(不要将机密放在命令行上):
npx wrangler secret put ZOHO_CLIENT_ID
npx wrangler secret put ZOHO_CLIENT_SECRET
npx wrangler secret put ZOHO_REFRESH_TOKEN
npx wrangler secret put ZOHO_ORG_ID
npx wrangler secret put MCP_AUTH_TOKEN
# 非机密数据中心(如果不是 'com'):添加到 wrangler.jsonc 中,如 "vars": { "ZOHO_DC": "eu" }
npx wrangler deploy
```
生成一个没有尾部换行符的强大 `MCP_AUTH_TOKEN`(尾部换行符会破坏恒定时间比较):
```bash
MCP_TOKEN=$(openssl rand -hex 32); printf '%s' "$MCP_TOKEN" | npx wrangler secret put MCP_AUTH_TOKEN; echo "MCP_AUTH_TOKEN=$MCP_TOKEN"
```
第一次部署会创建 Durable Object(迁移 `v1`)并打印您的 `https://zoho-analytics-mcp.<subdomain>.workers.dev` URL。对于 OAuth 工作器,请参见 [OAuth 工作器](#oauth-worker-claudeai-web)。
---
## 验证
```bash
URL="https://zoho-analytics-mcp.<subdomain>.workers.dev"
# 1) 健康检查(无身份验证)→ "zoho-analytics-mcp worker: ok"
curl "$URL/"
# 2) 失败关闭 - 无令牌 → 401
curl -i -X POST "$URL/mcp"
# 3) MCP 初始化(带有令牌)→ JSON-RPC 结果,不是 401
curl -X POST "$URL/mcp" \
-H "Authorization: Bearer <MCP_AUTH_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
```
或运行端到端烟雾测试(初始化 → 工具/列表 → `zoho_whoami`,验证 Zoho 凭证实时):
```bash
MCP_URL="$URL/mcp" MCP_TOKEN="<MCP_AUTH_TOKEN>" npm run smoke
```
---
## 测试
```bash
npm run typecheck # tsc --noEmit (strict)
npm test # vitest — OAuth 刷新 + 401 重试,DC 路由,CONFIG/头编码,信封错误,原始导出,帮助函数
npm run smoke # 针对已部署的工作器进行实时烟雾测试(设置 MCP_URL + MCP_TOKEN)
```
CI ([.github/workflows/ci.yml](.github/workflows/ci.yml)) 在每次推送和 PR 上运行类型检查 + 测试。客户端可以使用模拟的 `fetch` 进行完全单元测试(可注入的 `backoffBaseMs` 保持重试测试快速);纯帮助函数(行解析,列提取,视图类型映射)针对固定数据进行测试。
---
## 连接客户端
### Claude 代码
```bash
claude mcp add --transport http --scope user zoho-analytics \
https://zoho-analytics-mcp.<subdomain>.workers.dev/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"
claude mcp list # → zoho-analytics: … (HTTP) - ✓ 已连接
```
### Claude 桌面版
Claude 桌面版使用 stdio,因此通过 [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) 桥接远程服务器。添加到 `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/`) 并完全重启应用程序:
```jsonc
{
"mcpServers": {
"zoho-analytics": {
"command": "npx",
"args": [
"mcp-remote",
"https://zoho-analytics-mcp.<subdomain>.workers.dev/mcp",
"--header", "Authorization: Bearer <MCP_AUTH_TOKEN>"
]
}
}
}
```
> 如果裸 `npx` 在桌面应用程序内无法解析(通常当 Node 通过版本管理器安装时),请使用 `which npx` 的绝对路径。
### Claude 网页
**Bearer** 工作器无法添加到 Claude.ai 网页(其连接器 UI 需要 OAuth,没有静态令牌字段)。使用 **`zoho-analytics-mcp-oauth`** 部署代替:
1. 部署它并设置其机密 - 参见 [OAuth 工作器](#oauth-worker-claudeai-web)。
2. 在 Claude.ai → **设置 → 连接器 → 添加自定义连接器**,输入 MCP URL:
`https://zoho-analytics-mcp-oauth.<subdomain>.workers.dev/mcp`
3. Claude.ai 自动发现 OAuth(动态客户端注册)并将您发送到同意屏幕。输入您的 **通行短语** 以授权。
### 编程
任何 HTTP MCP 客户端都有效 - 发送 `Authorization: Bearer <MCP_AUTH_TOKEN>` 和 `Accept: application/json, text/event-stream` 到 `POST /mcp`。
---
## OAuth 工作器(Claude.ai 网页)
`zoho-analytics-mcp-oauth` 是相同的 MCP 服务器,由 OAuth 2.1 提供程序支持,通过单个共享通行短语控制。路由:
| 路由 | 目的 |
|-------|---------|
| `GET /` | 健康检查(无身份验证) |
| `GET`/`POST` `/authorize` | 通行短语同意屏幕 |
| `/token`, `/register`, `/.well-known/oauth-*` | OAuth 端点(由提供程序处理) |
| `POST /mcp`, `GET /sse` | MCP 传输,OAuth 保护 |
与 bearer 工作器一起部署:
```bash
# 一次性:创建提供程序需要的 KV 命名空间,然后将其 ID 粘贴到 wrangler.oauth.jsonc
npx wrangler kv namespace create OAUTH_KV # → { "binding": "OAUTH_KV", "id": "<paste into kv_namespaces>" }
# 机密(在提示符下粘贴;-c 选择 OAuth 工作器):
npx wrangler secret put ZOHO_CLIENT_ID -c wrangler.oauth.jsonc
npx wrangler secret put ZOHO_CLIENT_SECRET -c wrangler.oauth.jsonc
npx wrangler secret put ZOHO_REFRESH_TOKEN -c wrangler.oauth.jsonc
npx wrangler secret put ZOHO_ORG_ID -c wrangler.oauth.jsonc
npx wrangler secret put APP_PASSPHRASE -c wrangler.oauth.jsonc
npx wrangler deploy -c wrangler.oauth.jsonc
```
`APP_PASSPHRASE` 关闭失败 - 如果未设置,同意屏幕将拒绝每个尝试。然后在 [Claude Web](#claude-web) 中添加连接器。
---
## 注意事项
- **请自带 OAuth 应用。** 您需要一个已注册的 Zoho 客户端和刷新令牌(参见 [获取 Zoho OAuth 凭证](#getting-zoho-oauth-credentials))。`ZOHO_DC` 必须与您的帐户所在的数据中心匹配,否则令牌刷新将失败。
- **临时 SQL 是异步的。** Zoho 通过批量导出 *作业* 运行临时 SQL。`zoho_query_data` 隐藏此(创建 → 轮询 → 下载)但限制其等待(默认 50 秒,最高 120 秒;Zoho 作业通常需要 30-90 秒);对于非常大的结果集,它返回一个 `job_id` 以使用 `zoho_get_export_job` 轮询。
- **API 单位和频率限制。** 调用消耗每日 API 单位,并受每分钟频率限制(≈100 req/min 总体)。批量工具使用有限的并发,但大量使用仍可能达到配额错误(`6043`/`6045`)。
- **大型工具表面。** 完整的覆盖意味着 ~144 个工具。对于一个连接器来说,这是一个很大的数字 - 如果您的客户端难以应对计数,或者您只需要报告,请使用 `MCP_READONLY=true` 部署 ~51 个读取工具。建模、共享、发布和变量工具上的高级/长尾 CONFIG 键通过 `options` 对象传递(按工具记录),而不是作为参数枚举。
- **OAuth 工作器:默认单个用户,多用户可选。** 默认情况下,OAuth 工作器在一个共享的通行短语上运行,并使用一个工作器范围的 Zoho 令牌 - 适合个人连接器。设置 `ZOHO_MULTI_USER=true` (使用 *基于服务器的* Zoho 客户端,其重定向 URI 为 `<origin>/zoho/callback>`),使同意屏幕成为真正的每个用户 Zoho 登录:每个用户的自己的刷新令牌存储在加密的授权属性中,访问令牌和模式缓存按用户命名空间,每个用户按用户费率限制服务器。 多用户模式发送关闭,并具有自己的端到端同意 + 隔离测试,但未在实时多租户组织中测试 - 在依赖它之前进行验证。
- **规范模糊性。** 许多 Zoho 端点在 OpenAPI 规范和实时 API 文档/ SDK 之间不一致。在它们冲突时,此客户端遵循 **实时文档 + SDK**:电子邮件计划写入是工作区范围的,没有 `/trigger` 后缀;数据源路径是工作区范围的和复数的;共享/删除共享是 `/workspaces/{id}/share`,带有每个视图的 PUT 进行更新;`makeDefaultFolder` 是 PUT;`sortData` 使用 CONFIG 传输和列 ID。剩余的未经验证的特定路径:`get_my_permissions`(OAS 中的 `mypermissions` 与 SDK 中的 `userpermissions`)。使用实时调用验证特定路径。
- **内存限制。** 同步导出/下载在 ~10MB 以上被拒绝(使用异步 CSV 导出并分页),导入在 ~25MB 以上被拒绝(拆分文件),模板 ZIP 在 ~256KB 以上被拒绝(导出较少的视图)- Durable Objects 有 128MB 内存上限,工具结果进入 LLM 上下文。
- **依赖版本。** `agents@^0.14.5` + `@modelcontextprotocol/sdk@^1.29.0` + `zod@^4`;`npm audit` 是干净的。`ai`/`react` 是 `agents` 的所需对等方(npm 自动安装它们),但在 `agents/mcp` 服务器路径上没有导入它们,因此它们从未进入 Worker 包。
---
## 项目布局
```
src/
index.ts 无承载工作器入口 - 路由,无承载门控,McpAgent/Durable 对象,clientFromEnv
oauth.ts OAuth 工作器入口 - OAuth 提供程序 + 通行短语同意 + McpAgent
tools.ts 注册工具() - 100+ 工具定义 + Zod 模式 + 帮助函数(共享)
zohoanalytics.ts ZohoAnalyticsClient - 无依赖 REST 客户端(仅限 fetch):OAuth 刷新,
CONFIG 参数 + 信封处理,DC 路由,重试/退避,mapLimit(共享)
tests/ vitest 单元测试(客户端 OAuth/重试/DC/CONFIG,帮助函数)
vitest.config.ts 测试配置(解析 NodeNext .js 规范为 .ts)
scripts/smoke.mjs 针对已部署的工作器进行烟雾测试(npm run smoke);自动检测 CORE/READONLY 模式
scripts/live-test.mjs 有防护的实时集成测试(MCP_URL + MCP_TOKEN + LIVE_WRITE=1)—
创建一个一次性表,执行行/SQL/干燥运行,并通过垃圾邮件 + 清理进行清理
.github/workflows/ci.yml CI - 类型检查 + 测试 + 脚本的语法检查
.github/workflows/deploy.yml 有防护的手动部署(类型检查 + 测试 -> wrangler 部署 -> 实时烟雾测试);需要 CLOUDFLARE_API_TOKEN 机密
wrangler.jsonc 无承载工作器配置(zoho-analytics-mcp)
wrangler.oauth.jsonc OAuth 工作器配置(zoho-analytics-mcp-oauth)- 添加 OAUTH_KV
package.json 依赖项(SDK ^1.29.0,代理 ^0.14.5,zod ^4,workers-oauth-provider,wrangler,vitest)
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器