# @frontmcp/edge 中文文档

规范地址：https://npmcn.com/package/%40frontmcp/edge/

版本：1\.12\.2
npm 元数据更新时间：2026-11-14T21:09:40.556Z
中文译文更新时间：2026-11-15T15:34:31.267Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40frontmcp/edge
原文对照：https://npmcn.com/package/%40frontmcp/edge/?lang=original
项目主页：https://frontmcp.dev/reference/deployment/edge
源码仓库：https://github.com/agentfront/frontmcp

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：85.1 kB，13 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=24\.0\.0
- 运行依赖：2 个
- peer 依赖：@frontmcp/sdk 1\.12\.2
- 首次发布：2026-06-21T15:31:34.159Z
- 最新版本发布：2026-11-14T21:09:40.194Z
- 近 30 天下载量：5080（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：68（近 12 个月 68 个）

## 中文简介

在 Cloudflare Workers / V8 上运行一个 FrontMCP MCP 服务器 从平面配置中分离出来 — 没有装饰器, 没有构建步骤

## 安装

```sh
npm install @frontmcp/edge
```

也可以使用：`pnpm add @frontmcp/edge`、`yarn add @frontmcp/edge`、`bun add @frontmcp/edge`

## README

# @ frontmcp/ edge (帮助)

从平面配置对象运行 Cloudflare Workers 上的 FrontMCP 服务器 。 工人的输入文件呼叫 `createEdgeMcp()` 用你给的配置 `@FrontMcp` 并出口其回报; `wrangler` 捆绑文件的原样,没有 `frontmcp build` 步骤和无 `@FrontMcp` 课。 比较 `frontmcp build --target cloudflare`,它添加了保存在持久对象和管理模式中的会话,可以拉出一个技能化的 OpenAPI 捆绑,从 Cron 触发器中刷新,并可以取出被推入的捆绑.

[![npm](https://img.shields.io/npm/v/@frontmcp/edge.svg)](https://www.npmjs.com/package/@frontmcp/edge) [![License](https://img.shields.io/npm/l/@frontmcp/edge.svg)](https://github.com/agentfront/frontmcp/blob/main/LICENSE)

## 安装

```bash
npm install @frontmcp/edge @frontmcp/sdk
npm install -D wrangler
```

`@frontmcp/sdk` 是同级依赖. `@frontmcp/plugin-skilled-openapi`,管理模式使用,是一个依赖性,所以它与这个软件包一起被安装. 安装与节点.js 24 或稍后.

## 使用量

```ts
// src/worker.ts
import { createEdgeMcp } from '@frontmcp/edge';
import { app, tool, z } from '@frontmcp/sdk';

const searchTickets = tool({
  name: 'search_tickets',
  description: 'Search tickets by title',
  inputSchema: { query: z.string() },
})(async ({ query }) => ({ query, tickets: [{ id: 'T-1', title: 'Cannot log in' }] }));

export default createEdgeMcp({
  info: { name: 'help-desk', version: '1.0.0' },
  apps: [app({ id: 'help-desk', name: 'Help Desk', tools: [searchTickets] })],
  http: { entryPath: '/mcp' },
});
```

```toml
# wrangler.toml
name = "help-desk"
main = "src/worker.ts"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]
```

```bash
npx wrangler dev      # local
npx wrangler deploy   # ship
```

`nodejs_compat` 需要, 也一样 `apps` (您列出时可能是空的) `tools` (在最高一级). `tool()` 财务报告和审定财务报表 `app()` 定义没有装饰器的工具和应用程序; `@Tool` 财务报告和审定财务报表 `@App` 上课也行.

处理者做什么:

-   **它根据第一个请求构建服务器**,而不是当模块装入, 因为一个工人不能做 I/O,然后再用它。 构建失败的答案 `500` (配置错误)或 `503` 与 `Retry-After`,在延迟1秒至60秒后再次受审.
-   **它复制字符串绑定到 `process.env`** 第一次请求时 `[vars]` ,而不是替换已经存在的值。 KV 命名空间等其他约束工具 `this.workerEnv`。 。 。 .
-   **服务于** MCP 时间 `http.entryPath` (单位:千美元)`/` (默认)和 `/healthz`,以及 `/readyz` 与 `health: { readyz: { enabled: true } }`。 。 。 .
-   **背景任务取消** 边缘; 服务器日志并启动.
-   **在德诺和邦**,通过 `fetch` 他们自己的第二个论点,处理者从中读取客户端IP.

## 持久对象中的会话

无 `sessions`,"工人"不保留会话:2026-07-28之前,客户端对协议版本的每一个请求都会自行送达(2026-07-28不需要会话). 与 `sessions: {}`中,每个会话的请求都转到一个以会话 ID 命名的持久对象上,它保持了会话的服务器和请求之间的传输。 导出类并绑定:

```ts
// src/worker.ts
import { createEdgeMcp } from '@frontmcp/edge';
import { app, tool, z } from '@frontmcp/sdk';

const searchTickets = tool({
  name: 'search_tickets',
  description: 'Search tickets by title',
  inputSchema: { query: z.string() },
})(async ({ query }) => ({ query, tickets: [] }));

const mcp = createEdgeMcp({
  info: { name: 'help-desk', version: '1.0.0' },
  apps: [app({ id: 'help-desk', name: 'Help Desk', tools: [searchTickets] })],
  http: { entryPath: '/mcp' },
  sessions: {}, // the Durable Object binding defaults to FRONTMCP_SESSIONS; set { binding } to change it
});

export default mcp;
export const FrontMcpSession = mcp.SessionDurableObject;
```

```toml
# wrangler.toml
[[durable_objects.bindings]]
name = "FRONTMCP_SESSIONS"
class_name = "FrontMcpSession"

[[migrations]]
tag = "v1"
new_classes = ["FrontMcpSession"]
```

如果捆绑不在的话 `wrangler.toml`,工人不开庭就满足请求.

## 管理模式

`managed` 拉一个签名 [熟练的 OpenAPI](https://frontmcp.dev/reference/plugins/skilled-openapi) 捆绑( OpenAPI specs 编译为 MCP 技能和工具) 从捆绑的服务器, 并服务于您的应用程序旁边, 因此服务器的能力不进行调用而改变 。 一个工人在请求之间没有定时器,所以捆绑由 Cron 触发器刷新,该触发器称返回 `scheduled()` 处理器 :

```ts
// src/worker.ts
import { env } from 'cloudflare:workers';

import { createEdgeMcp, kvBundleCacheFromEnv } from '@frontmcp/edge';

export default createEdgeMcp({
  info: { name: 'billing', version: '1.0.0' },
  apps: [],
  managed: {
    endpoint: 'https://bundles.example.com/v1/bundles/billing',
    authToken: env.BUNDLE_PULL_TOKEN,
    expectedAudience: 'billing-prod',
    jwksUrl: 'https://bundles.example.com/.well-known/jwks.json',
    expectedIssuer: 'https://bundles.example.com',
    trustedKeys: [{ keyId: 'billing-2026-11', alg: 'EdDSA', publicKeyPem: env.BUNDLE_SIGNING_KEY }],
    cache: kvBundleCacheFromEnv('BUNDLE_CACHE'),
  },
});
```

```toml
# wrangler.toml
[[kv_namespaces]]
binding = "BUNDLE_CACHE"
id = "<your KV namespace id>"

[triggers]
crons = ["*/5 * * * *"]
```

`BUNDLE_PULL_TOKEN` 是个秘密( a)`npx wrangler secret put BUNDLE_PULL_TOKEN`) (中文(简体) ). 模块装入时会评价配置, 所以从中读取密钥 `env` 那个 `cloudflare:workers` 出口,不是来自请求.

`BUNDLE_SIGNING_KEY` 是公共密钥的 PEM 服务器符号捆绑,以及 `keyId` 是其捆绑名称的密钥 ID。 这不是秘密: 一个 `[vars]` 输入 `wrangler.toml` 我会做的。 钥匙在 `jwksUrl` 只验证拉动符,而不是捆绑,所以没有 `trustedKeys` 每个捆绑都被拒绝 `unknown signing keyId` 工人们,是没有技能的。 至 1.11.2 这一例子尚存 `trustedKeys` 出来.

| 外地 | 说明 |
| --- | --- |
| `endpoint` | 为签名捆绑服务的 HTTPS URL |
| `authToken` | 为此服务器发布的捆绑服务器的令牌 |
| `expectedAudience`, (中文(简体) ), `jwksUrl`, (中文(简体) ), `expectedIssuer` | 捆绑服务器的代号是如何验证的 |
| `trustedKeys` | 公共密钥捆绑的签名有: `{ keyId, alg: 'RS256' | 'EdDSA', publicKeyPem }` |
| `cache` | 保留上次应用的捆绑 : `kvBundleCacheFromEnv('BINDING')`,或者你自己的商店 |
| `enableWebhook` | 还要带捆子去 `POST /__skilled_openapi/push`页:1 |
| `requirePushBodyDigest` | 拒绝一个无助推号 `body_sha256` 索赔,见下文。 默认 `false` |
| `pushReplay` | 哪里推出标志 `jti`s 保留: `{ binding }` (默认) `FRONTMCP_PUSH_REPLAY`页:1 |
| `allowRollback` | 如下文所示,用比所服务年龄大的拉出或推出捆绑。 默认 `false` |
| `requireSignature`, (中文(简体) ), `dev`, (中文(简体) ), `credentials`, (中文(简体) ), `outbound` | 被传入了技能型OpenAPI插件. `dev` 跳过签名检查: 生产中永远不要使用它 |
| `confirm` | 作为插件在用户请求前询问用户的动作 `confirm`; 见下文 |
| `pollIntervalMs`, (中文(简体) ), `bundleCacheDir` | 忽略了没有计时器或文件系统的工人 |

一旦套接字应用并保存在其中, Cron 运行结束 `cache`,同样当它是第一个事件时,一个孤立者会得到:然后它开始捆绑同步,它的第一拉就是跑的拉. 失败签名或其他检查的捆绑没有被应用和保存,所以无法到达捆绑服务器的冷启动服务于Worker应用的最后一个捆绑.

Bundles只向前走:一个被拉出或被推入的捆绑比隔离服务要长的捆绑没有被应用和保存,所以一个有效签名的旧捆绑无法将工人卷回. 按 semver 比较出两个 semver 版本;同一种版本(重新签名),或两种版本都不同时 semver 比较出 `generatedAt`。要回滚,请在较新的版本下发布先前的内容,或设定 `allowRollback: true`。一个启动的隔离还没有完成捆绑,所以缓存捆绑就代表了它:当缓存捆绑的拉力失败、被拒绝时,或者当它比缓存捆绑老(没有)时,隔离为缓存捆绑服务 `allowRollback`),所以一个被打乱了的CDN或回滚出源无法取回新的隔离. 服务缓存的捆绑 永远不会写回 `cache`高达1.11.0个新隔离器服务于它所拔出的东西,当捆绑被拒绝时,它没有任何服务,并且将缓存输入器重置在离线起始处.

Cron 运行失败( E)`scheduled()` cloudflare将运行记录为例外, 并算作失败引用)

-   **未应用它提取的捆绑**: 其签名或其他检查失败, 或比所服务的时间长 。 错误名称 : `[frontmcp/edge] Cron refresh: bundle billing@4.2.0 was not applied: digest mismatch (...)`。当运行开始隔离时,它说 `was not applied, so the cached bundle serves: older than the cached bundle billing@4.3.0 (...)`。 。 。 .
-   **牵引失败**数字 : `[frontmcp/edge] Cron refresh: the bundle pull failed: pull responded 503`。当运行开始隔离时,它说 `the bundle pull failed, so the cached bundle serves`。在它的代号上失败的拉出支票: `the bundle pull failed (token check: expired): ...`,作为 `lastSync.tokenFailure` 显示在 `/readyz`。 。 。 .

多达1.11.0次,据报告取得了成功。 运行,它的拉 应用捆,或拉 服务,成功.

`/readyz` 说一样,一次 `health: { readyz: { enabled: true } }` 你们应当打开它。 虽然上一次同步被拒绝或失败,但其 `skilled-openapi` 检查是 `degraded`,与 `details: { state: 'stale', bundleId, bundleVersion, lastSync }`:捆绑已送达,拒绝或失败与其理由和时间. 工人保持准备,因为它服务 最后一个好捆。 每一个隔离的答案 自己的捆绑和同步。 细节出现在生产之外,或与 `health.includeDetails: true`。 。 。 .

每个操作呼叫先检查API的宿主: 在工人, `node:dns` 通过DNS解决HTTPS,所以主机必须公开解决.

`confirm` 通过 HTTP 方法、 标记或操作ID , 将用户在请求前询问的动作命名为 Skilled OpenAPI 插件 [`confirm` 选项](https://frontmcp.dev/reference/plugins/skilled-openapi) 是否为: `confirm: { methods: ['DELETE'] }`。插件检查它,所以一个无效的值拒绝启动(`500 CONFIG_INVALID`,则日志将字段命名)。 问题是MCP诱导,服务器只用 `elicitation: { enabled: true }`在一个拒绝启动的云旗工人身上(`Elicitation requires distributed storage when running on Edge runtime`因此,有一个动作 `confirm` 名字被拒绝, `the user's confirmation is needed for voidInvoice, and this server can't ask for it: elicitation is disabled; nothing was sent`,或与 `whenUnsupported: 'allow'` 运行不问. `load_skill` 标记为 `asksForConfirmation: true`,审计日志记录了确认结果。 截至1.11.0管理模式无 `confirm`,所以每个动作 跑不问.

### 套装

与 `enableWebhook: true`,捆绑服务器可以推出一个新的捆绑,而不是等待下一次 Cron 运行:

```http
POST /__skilled_openapi/push
Authorization: Bearer <JWT>
Content-Type: application/json

{ "schemaVersion": 1, "bundleId": "billing", "version": "4.2.0", ..., "integrity": { ... } }
```

-   **标志** 检查为 `authToken` (由密钥签名) `jwksUrl`, (中文(简体) ), `iss` 等于 `expectedIssuer`, (中文(简体) ), `aud` 包括 `expectedAudience`页:1 它必须携带 `jti` 包含8个或8个以上没有被推入的字符,以及 `iat` 5分钟内,所以很久前就发行了的拉活符,不能推.
-   **标志 `body_sha256` 索赔** 将它绑在身体上: 基数64url SHA-256,没有被粘贴,是请求体的确切字节(不是捆绑) `integrity.digest`) (中文(简体) ). 工人将它收到的字节搁置起来;任何其他机构都回答 `401`,日志上写着 `push refused (body_mismatch)`拒绝的代币 `jti` 保持未使用,所以它发出的推力仍然适用。 没有这个权利要求,在5分钟内捕获到的标志物可以携带为这名工人签名的捆绑服务器的任何其他捆绑. 一个没有它的信使被接受,每个隔离处有一个警告, 所以捆绑的服务器还没有设置它仍然工作; `requirePushBodyDigest: true` 拒绝. `pushBodyDigest(body)` 财务报告和审定财务报表 `PUSH_BODY_DIGEST_CLAIM` 从 `@frontmcp/adapters/skills` 计算发件人的索赔.
-   **躯体** 作为JSON的捆绑, 被检查为被拉的捆绑是: 它的图谋, 然后它的签名反对 `trustedKeys` (除非 `requireSignature: false`) (中文(简体) ).
-   **适用**,除非它比被送达的捆绑年长,在第一次拉出之后,在任何捆绑已经排队之后,所以一个推和克龙跑永远不能一次应用,然后保持在 `cache`。 。 。 .

| 状态 | 体质 |
| --- | --- |
| `200` | `{ "applied": true, "bundleId", "bundleVersion" }` |
| `400` | `{ "error": "invalid_bundle" }`: 身体不是捆绑的 |
| `401` | `{ "error": "invalid_token" }`,与 `WWW-Authenticate: Bearer error="invalid_token"` |
| `409` | `{ "error": "push_replayed" }`: 已使用此符号的推力 |
| `409` | `{ "error": "bundle_outdated" }`: 捆绑比被送达的年长, 留下来 |
| `422` | `{ "error": "bundle_not_applied" }`: 签名或捆绑支票失败; 已送达捆绑保留 |
| `503` | `{ "error": "temporarily_unavailable" }`: JWKS 无法读取,或者 `jti` 无法记录 |

一个被拒绝的代号也一样 `401` 任何支票都拒绝了 只有日志命名它: `[saas-source] push refused (wrong_issuer): ...`,或 `bundle push not checked (jwks_unavailable): ...` (单位:千美元) `503`。 。 。 .

终点是可接通的流出, `skilled-openapi:bundle-push`,在与服务器其他HTTP流相同的IP过滤器和速率限制后.

这个 `jti`s被保存在一个持久对象中,每个工人的隔离和复制都到达,因此回放到另一个隔离的推力也被拒绝. (KV不能做到这一点:它最终是一致的,所以两个隔离点都可以读取a `jti` 未使用。 ) 导出类并绑定:

```ts
// src/worker.ts
const mcp = createEdgeMcp({
  // ...
  managed: { /* ... */ enableWebhook: true }, // the binding defaults to FRONTMCP_PUSH_REPLAY; set pushReplay: { binding } to change it
});

export default mcp;
export const FrontMcpPushReplay = mcp.PushReplayDurableObject;
```

```toml
# wrangler.toml
[[durable_objects.bindings]]
name = "FRONTMCP_PUSH_REPLAY"
class_name = "FrontMcpPushReplay"

[[migrations]]
tag = "v1" # or the next tag, when wrangler.toml already has migrations
new_sqlite_classes = ["FrontMcpPushReplay"]
```

-   **每个观众一个对象** 留着 `jti`s, 以 `expectedAudience`每一个 `jti` 被保存到它的标志 `iat` 5分钟后就投了.
-   **没有束缚**,每个推答 `503 temporarily_unavailable`,日志则指定了缺少的绑定值。 拉和克龙运行不受影响. 最高为1.11.0 `jti`s被保存在每个隔离的记忆中, 隔离不共享.
-   **在德诺或邦**设置 `pushReplay` 到函数 `env` 返回一个商店, `{ claim(key, ttlMs) }`: 它解决 `true` 当它记录 `key`, (中文(简体) ), `false` 何时 `key` 已经记录了,当它无法辨别时,就扔出。 掷出时拒绝推入.

## API 密码

### `createEdgeMcp(config)`

`config` 这是什么 `@FrontMcp` 取( 取)`info`, (中文(简体) ), `apps`, (中文(简体) ), `tools`, (中文(简体) ), `http`, (中文(简体) ), `auth`附加:

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `sessions` | `{ binding? }` | 将每个会话保留在一个持久对象中,以 `binding` (默认) `FRONTMCP_SESSIONS`(中文(简体) ) |
| `managed` | `ManagedEdgeOptions` | 如上, 拖取一个熟练的 OpenAPI 捆绑 |
| `skillIndex` | `{ binding?, ttlSeconds? }`,或函数 `env` | 保留 KV 命名空间中的技能搜索索引( 默认绑定) `FRONTMCP_SKILL_INDEX`),所以一个寒冷的开始读取它而不是重建它 |

服务器从不听 : `createEdgeMcp()` 套装 `serve: false`。不构建服务器就可以找到配置错误,例如 `approval` 或者说 `featureFlag` 元数据不执行插件,在评估模块时抛出,所以 Worker 无法部署 .

它返回:

| 成员 | 说明 |
| --- | --- |
| `fetch(request, env?, ctx?)` | 工人的要求处理器 |
| `SessionDurableObject` | 永久对象类 `sessions`。仅在使用时导出它 |
| `PushReplayDurableObject` | 永久对象类 `managed.enableWebhook`,如上所示 |
| `scheduled(event?, env?, ctx?)` | 与 `managed` 仅: Cron 触发器处理器, 它拉出捆绑, 不应用时则扔出 |

其他出口: `kvBundleCacheFromEnv`, (中文(简体) ), `createKvBundleCache`, (中文(简体) ), `kvSkillIndexCacheFromEnv`, (中文(简体) ), `createKvSkillIndexCache`, (中文(简体) ), `buildManagedOpenApiPluginOptions`,则 `EdgeMcp`, (中文(简体) ), `EdgeMcpConfig`, (中文(简体) ), `ManagedEdgeOptions`, (中文(简体) ), `EdgePushReplayStore` 财务报告和审定财务报表 `EdgePushReplayStoreFactory` 类型.

## 文档

-   [`@frontmcp/edge` 参考文献](https://frontmcp.dev/reference/deployment/edge)数字 : `createEdgeMcp()` 完整、会话、管理模式,以及它如何与云层构建目标相比较
-   [云花岗工人](https://frontmcp.dev/reference/deployment/cloudflare-workers)页:1 `frontmcp build --target cloudflare` 替代和工具中的约束
-   [熟练的 OpenAPI 插件](https://frontmcp.dev/reference/plugins/skilled-openapi): 捆绑管理模式服务

## 相关软件包

-   [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk):框架; `createEdgeMcp()` 取其配置
-   [`@frontmcp/plugin-skilled-openapi`](https://www.npmjs.com/package/@frontmcp/plugin-skilled-openapi): 以管理模式拉出并验证捆绑
-   [`frontmcp`](https://www.npmjs.com/package/frontmcp): 国家综合倡议,其 `build --target cloudflare` 以另一种方式运行工人

## 捐款

资料来源: [`libs/edge`](https://github.com/agentfront/frontmcp/tree/main/libs/edge)欢迎提出问题和拉动请求;见 [捐款额](https://github.com/agentfront/frontmcp/blob/main/CONTRIBUTING.md)。 。 。 .

## 许可证

阿帕奇2.0 (英语). 见 [自由主义](https://github.com/agentfront/frontmcp/blob/main/LICENSE)。 。 。 .

## 常见问题

### @frontmcp/edge 是什么？

在 Cloudflare Workers / V8 上运行一个 FrontMCP MCP 服务器 从平面配置中分离出来 — 没有装饰器, 没有构建步骤

### 如何安装 @frontmcp/edge？

在项目目录运行 npm install @frontmcp/edge，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@frontmcp/sdk（1\.12\.2）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @frontmcp/edge 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @frontmcp/edge 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @frontmcp/edge 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=24\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @frontmcp/edge 可以商用吗？

@frontmcp/edge 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @frontmcp/edge 的下载量有多少？

根据 npm 官方下载统计，@frontmcp/edge 在 2026/10/16 – 2026/11/14 这 30 天内被下载 5,080 次，日均约 169 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @frontmcp/edge 还在维护吗？

最新版本 1\.12\.2 发布于 2026/11/15（1 天前）；至今共发布 68 个版本，其中过去 12 个月发布了 68 个；首次发布于 2026/06/21。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

