# @frontmcp/plugin-approval 中文文档

规范地址：https://npmcn.com/package/%40frontmcp/plugin-approval/

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

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

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

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

- 包体积（解压后）：318 kB，70 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=24\.0\.0
- 运行依赖：3 个
- peer 依赖：@vercel/kv ^2\.0\.0 \|\| ^3\.0\.0，@frontmcp/sdk 1\.12\.2，@frontmcp/lazy-zod 1\.12\.2
- 首次发布：2026-01-09T03:00:48.115Z
- 最新版本发布：2026-11-14T21:09:45.538Z
- 近 30 天下载量：5228（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：112（近 12 个月 112 个）

## 中文简介

FrontMCP 的批准插件: 拒绝运行标记工具, 直至为调用者记录批准

## 安装

```sh
npm install @frontmcp/plugin-approval
```

也可以使用：`pnpm add @frontmcp/plugin-approval`、`yarn add @frontmcp/plugin-approval`、`bun add @frontmcp/plugin-approval`

## README

# @ frontmcp/plugin - 核准

一个FrontMCP插件,拒绝运行一个工具,直到为呼叫者录制一个批准. 用来做工具 不应该在没有别人说的情况下跑,比如删除机票或者退款。 标记工具为 `approval`, (中文(简体) ), 直到你的代码批准之前 每一个电话都被拒绝 `this.approval` 或插件的商店. 每一次批准批准的记录,可以撤销或者规定失效. 你决定一个人如何答应: 窗体从 `this.elicit()`,或采用外部审批系统,插件会向您询问 [网点](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-webhook-mode) 或通过 [投票](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-recheck-mode)。 。 。 .

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

## 安装

```bash
npm install @frontmcp/plugin-approval @frontmcp/sdk
```

需要节点.js 24或后. 保留 `@frontmcp/sdk` 上。 核准 保存在内存中,除非您配置 `storage`重新获得支持`ioredis`)包括;对于其他商店,安装 他们自己的客户:

-   `@vercel/kv`,可选的同伴依赖,用于 `storage: { type: 'vercel-kv' }`。 。 。 .
-   `@upstash/redis` 页:1 `storage: { type: 'upstash' }`。 。 。 .

此插件不属于 [`@frontmcp/plugins`](https://www.npmjs.com/package/@frontmcp/plugins) 元包装.

## 使用量

注册插件于 `@FrontMcp`打开每个应用程序的工具,或者打开一个 `@App`标出需要批准的工具, 并给用户一个批准的方法:

```ts
import { ApprovalPlugin, userGrantor } from '@frontmcp/plugin-approval';
import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';

@Tool({
  name: 'delete_ticket',
  description: 'Delete a support ticket for good. Needs approval: call approve_delete first.',
  inputSchema: { id: z.string() },
  approval: {
    approvalMessage: 'delete_ticket needs the user to approve it. Call approve_delete first.',
    category: 'delete',
    riskLevel: 'high',
  },
})
class DeleteTicket extends ToolContext {
  async execute({ id }: { id: string }) {
    return { id, deleted: true };
  }
}

@Tool({ name: 'approve_delete', description: 'Ask the user to allow delete_ticket for this session', inputSchema: {} })
class ApproveDelete extends ToolContext {
  async execute() {
    // The user answers this form in the client. The model can't.
    const answer = await this.elicit(
      'Allow the assistant to delete tickets in this session?',
      z.object({ allow: z.boolean() }),
    );
    if (answer.status !== 'accept' || !answer.content?.allow) return { approved: false };

    await this.approval.grantSessionApproval('help-desk:delete_ticket', {
      grantedBy: userGrantor(this.auth.user.sub),
    });
    return { approved: true };
  }
}

@App({ id: 'help-desk', name: 'Help Desk', tools: [DeleteTicket, ApproveDelete] })
class HelpDeskApp {}

@FrontMcp({
  info: { name: 'help-desk', version: '1.0.0' },
  apps: [HelpDeskApp],
  elicitation: { enabled: true },
  plugins: [ApprovalPlugin.init()],
})
export default class Server {}
```

-   **工具标识是 `<app id>:<tool name>`**一样 `help-desk:delete_ticket`给予 `'delete_ticket'` 记录 a 批准什么也没有检查.
-   **批准属于打电话者**,因此使用已签名用户的插件。 匿名电话可以换个新的 然后就永远不适用于他们的下一次通话.
-   **别让模特儿批准自己的电话.** 一个不问人就提供工具 就能保护大门 没什么 如上所述,在表格后给予用户答复,或给予更多权利的呼叫者答复.
-   **字段需要它的插件 .** 一个工具所在的服务器 `approval` 没有 `ApprovalPlugin` 到达它不会开始: 失败 `UnenforcedMetadataError`。 。 。 .
-   `ApprovalPlugin.init()` 没有争论 `plugins: [ApprovalPlugin]`,使用默认值.

## 客户所看到的

拒绝调用是模型可以读取的工具错误: `isError: true`, (中文(简体) ), `_meta.code: 'APPROVAL_REQUIRED'`文本时 该工具的 `approvalMessage`在生产过程中(批准错误扩大) `PublicMcpError`) (中文(简体) ). 默认 留言, `Tool "<id>" requires approval to execute. Allow?`不要告诉模特儿下一步该做什么,所以写你 拥有的。 这个工具 `category`, (中文(简体) ), `riskLevel` 其他字段留在服务器上.

## 这个 `approval` 打开 `@Tool`

`approval: true` 表示 `{ required: true, defaultScope: ApprovalScope.SESSION }`。任何物体都需要批准,除非 它说 `required: false`。 。 。 .

| 外地 | 它会做什么 |
| --- | --- |
| `required` | `false` 把门关了 默认 `true`。 。 。 . |
| `skipApproval` | `true` 把门也关了. |
| `alwaysPrompt` | 每次批准都允许一个呼叫运行,并被使用. |
| `approvalMessage` | 拒书之文. |
| `allowedScopes` | 批准这一工具的范围。 补助金通过 `this.approval` 其他范围抛出 `ApprovalScopeNotAllowedError`。 。 。 . |
| `maxTtlMs` | 这个工具的核准时间最长. |
| `preApprovedContexts` | 让一个电话在未经批准的情况下运行 `authInfo.extra.approvalContext` 火柴。 比赛。 FrontMCP的认证模式没有设置,所以你自己的代码必须设置. |
| `category`, (中文(简体) ), `riskLevel`, (中文(简体) ), `defaultScope` | 锁定错误 `details`客户看不到的. |

## `this.approval`

该插件添加 `this.approval` 给它注册的应用程序的工具、资源和提示。 它的作用为 当前调用器,并在 `<app id>:<tool name>` 形式.

| 方法 | 它会做什么 |
| --- | --- |
| `isApproved(toolId, context?)` | 门是否让呼叫者运行工具 . |
| `grantSessionApproval(toolId, options?)` | 批准召会. |
| `grantUserApproval(toolId, options?)` | 批准在每届会议上召集人. |
| `grantTimeLimitedApproval(toolId, ttlMs, options?)` | 核准: `ttlMs` 毫秒长. |
| `grantContextApproval(toolId, context, options?)` | 在一个方面核准, `{ type, identifier }` (见 `preApprovedContexts`) (中文(简体) ). |
| `revokeApproval(toolId, options?)` | 删去呼叫人对工具的认可,保留副本24小时. |
| `getRevocations(toolId)` | 调用者对该工具的认可在后24小时内被撤销. |
| `getApproval`, (中文(简体) ), `getSessionApprovals`, (中文(简体) ), `getUserApprovals`, (中文(简体) ), `queryApprovals`, (中文(简体) ), `clearSessionApprovals` | 读取或清取来电所录. |

赠款 `options` 为: `{ grantedBy?, reason?, metadata? }`选项 `{ revokedBy?, reason? }`没有 `grantedBy`,一个赠款记录了与 `method: 'implicit'`上面写着没人问: `{ source: 'user', identifier: <user id>, method: 'implicit' }`,或 `{ source: 'user', method: 'implicit' }` 没有 注册用户。 在用户同意后,通过一个设保人说:

```ts
import { policyGrantor, userGrantor } from '@frontmcp/plugin-approval';

// { source: 'user', identifier: 'user-123', displayName: 'Jane Doe', method: 'interactive' }
await this.approval.grantUserApproval('ops:deploy', { grantedBy: userGrantor('user-123', 'Jane Doe') });

// { source: 'policy', identifier: 'safe-list', method: 'implicit' }
await this.approval.grantSessionApproval('ops:deploy', { grantedBy: policyGrantor('safe-list') });
```

设保人的其他帮助者是: `adminGrantor`, (中文(简体) ), `systemGrantor`, (中文(简体) ), `agentGrantor`, (中文(简体) ), `apiGrantor`, (中文(简体) ), `oauthGrantor`, (中文(简体) ), `testGrantor` 财务报告和审定财务报表 `customGrantor`,与匹配的撤销器助手(`userRevoker`, (中文(简体) ), `adminRevoker`, (中文(简体) ), `policyRevoker`,以及 页:1.

要批准或撤销除打电话者以外的人,如批准队友的领先者,使用商店: `this.get(ApprovalStoreToken)` 返回,使用 `grantApproval({ toolId, scope, userId?, sessionId?, ttlMs?, grantedBy?, ... })` 财务报告和审定财务报表 `revokeApproval(...)`。 。 。 .

## 范围

`ApprovalScope` 是字符串音符 :

| 范围 | 数值 | 它会做什么 |
| --- | --- | --- |
| `SESSION` | `'session'` | 核准本届会议. |
| `USER` | `'user'` | 在每届会议上为用户核准. |
| `TIME_LIMITED` | `'time_limited'` | 需要a `ttlMs`,并批准至到期. |
| `CONTEXT_SPECIFIC` | `'context_specific'` | 仅核准发出这方面的呼吁,因为 `authInfo.extra.approvalContext` 携带. |
| `TOOL_SPECIFIC` | `'tool_specific'` | 标签 插件中没有任何内容授予它. |

根据MCP协议2026-07-28,客户端没有会话,因此每个用户都会保持会话批准,并持续到完成 撤销或过期。 在有需要时,给予有时限的批准.

## 选项

```ts
ApprovalPlugin.init({
  storage: { type: 'redis', redis: { url: process.env.REDIS_URL } },
});
```

| 选项 | 默认 | 说明 |
| --- | --- | --- |
| `storage` | `{ type: 'auto' }` | 在保留批准的情况下: `'memory'`, (中文(简体) ), `'redis'`, (中文(简体) ), `'vercel-kv'`, (中文(简体) ), `'upstash'`, (中文(简体) ), `'cloudflare-kv'` 或者说 `'auto'`。 。 。 . `'auto'` 从其环境变量中选择 Upstash, Vercel KV 或 Redis, 否则则选择内存 . |
| `storageInstance` |  | 一个你做的存储器 `createStorage()` 从 `@frontmcp/utils`胜利结束 `storage`。 。 。 . |
| `namespace` | `'approval'` | 插件密钥的前缀 . |
| `cleanupIntervalSeconds` | `60` | 过期核准被删除的频率如何. `0` 关掉. |
| `mode` | `'recheck'` | `'recheck'` 民意调查 `recheck.url` 当它被设置的时候; `'webhook'` 登记a `ChallengeService` 并向 `webhook.url` 当它被设置。 没有 URL , 既不接触外部系统 . |
| `recheck` |  | 见 [重新检查模式](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-recheck-mode)。 。 。 . |
| `webhook` |  | 见 [Webhook 模式](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-webhook-mode)。 。 。 . `webhook.challengeTtl` (默认) `300`)是挑战持续多久,以秒计. |
| `enableAudit` | `false` | 日志 a [审计线索](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-audit-trail)。 。 。 . |
| `maxDelegationDepth` | `3` | 最深处 [授权链](https://npmcn.com/package/%40frontmcp/plugin-approval/#readme-delegation-chains) 授权批准可以指名,0至64个. |

在浏览器构建中( I)`create()` 在网页上,WebMCP, `storage: { type: 'redis' }` 或者说 `{ type: 'sqlite' }` 掷出 `BrowserStoreUnavailableError` 从 `init()`名称 `storage: { type: 'memory' }`: 一页没有 TCP 套接字, 没有 文档. `{ type: 'auto' }` 在那里选择记忆.

## 审计线索

与 `enableAudit: true`,插件日志 1 `info` 线条( 浏览器) `ApprovalAudit`每个事件。 讯息是 `<event> <toolId>`,第一个论点是:

| 活动 | 何时 |
| --- | --- |
| `approval.requested` | 一通电话没有得到任何认可 它可以使用. `state`数字 : `pending`, (中文(简体) ), `expired`, (中文(简体) ), `denied`,或 `approved` 由复检系统进行; `via`数字 : `webhook` 或者说 `recheck`。 。 。 . |
| `approval.granted` | 核准记录如下: `this.approval`,商店,一个webhook召回或重新检查答案. |
| `approval.denied` | 一份否认书被记录在案. |
| `approval.revoked` | 一项批准被撤销(`revokedBy`, (中文(简体) ), `reason`),或会议批准被批准(`count`) (中文(简体) ). |
| `approval.expired` | 清理删除了过期的审批或拒绝. |

字段是工具、范围、用户编号、上下文、设保人或撤销人、理由和 `expiresAt`。一条线从不携带 会话 id、 符号或记录 `metadata`。一个过期的后端,例如Redis,可以删除已过期的 记录在清理之前; `approval.granted` 携带其 `expiresAt`。 。 。 .

默认关闭:最多1.11.2项选项无所作为(其记录的默认为 `true`,并打开它添加 线条,在日志中带有用户编号。 以木质运输方式追踪他们.

## 代表团链

授权批准姓名,授权: `grantedBy.delegationContext`, (中文(简体) ), `{ delegatorId, delegateId, purpose?, constraints?, chain? }`代表可进一步授权: `chain` 代表团名单 授权人的第一个,和 `extendDelegation()` 建立下个.

```ts
import { agentGrantor, extendDelegation } from '@frontmcp/plugin-approval';

const toPlanner = { delegatorId: 'user-123', delegateId: 'planner-agent', purpose: 'release' };
const toDeployer = extendDelegation(toPlanner, 'deploy-agent', { purpose: 'deploy step' });
// { delegatorId: 'planner-agent', delegateId: 'deploy-agent', purpose: 'deploy step',
//   chain: [{ delegatorId: 'user-123', delegateId: 'planner-agent', purpose: 'release' }] }

await this.approval.grantSessionApproval('ops:deploy', { grantedBy: agentGrantor('deploy-agent', toDeployer) });
```

`maxDelegationDepth` (默认) `3`限制链条,计算代表团本身: `toPlanner` 一个深, `toDeployer` 2. 其链条更深、断裂(不是前一名代表的委托人)或当事人名称的赠款 两次抛出 `ApprovalOperationError`,而存储的批准 这样不允许一个电话通过。 拒绝保留 无论他们的链子是什么. `maxDelegationDepth: 1` 仅允许直接授权,以及 `0` 没有授权核准. `delegationDepth(context)` 财务报告和审定财务报表 `delegationProblem(context, maxDepth)` 自己检查一个上下文。 最多1.11.2选项 什么都没做.

## Webhook 模式

与 `mode: 'webhook'` 财务报告和审定财务报表 `webhook.url`电话需要批准 它不会发出签名的批准请求 并被拒绝作为 `pending`. 系统 由 POSTING 返回到 `webhook.callbackPath`,而打电话者的下一个呼叫运行,或被拒绝作为 `denied`。 。 。 .

```ts
ApprovalPlugin.init({
  storage: { type: 'redis', redis: { url: process.env.REDIS_URL } },
  mode: 'webhook',
  webhook: {
    url: 'https://approvals.example.com/webhook',
    secret: process.env.APPROVAL_WEBHOOK_SECRET, // required with url, at least 24 bytes
    challengeTtl: 300,
    callbackPath: '/approval/callback',
  },
});
```

| 选项 | 默认 | 说明 |
| --- | --- | --- |
| `webhook.url` |  | 请求被搁置的地方. `https://`· ; `http://localhost`, (中文(简体) ), `127.0.0.1` 或者说 `[::1]` 仅在 `NODE_ENV` 没有 `production`没有证书. |
| `webhook.secret` |  | 签名每个请求并验证每个召回。 要求为 `url`A级 `whsec_` secret (Standard Webhooks) 是前缀后的基础64. |
| `webhook.includeJwt` | `false` | 在请求中添加调用符 `jwt`. 只有当审批制度必须充当调用人时才设置. |
| `webhook.challengeTtl` | `300` | 驳回请求等待裁决 驳回请求没有 `ttlMs` 持续时间. |
| `webhook.callbackPath` | `'/approval/callback'` | 服务器作出决定的路径( T)`POST`) (中文(简体) ). |

请求,每个呼叫者和工具发送一次,直至决定或 `challengeTtl` 通行证 :

```json
{
  "type": "approval.requested",
  "codeChallenge": "…",
  "codeVerifier": "…",
  "toolId": "ops:delete_ticket",
  "toolName": "delete_ticket",
  "category": "delete",
  "riskLevel": "high",
  "approvalMessage": "…",
  "requestedScope": "session",
  "userId": "user-123",
  "callbackPath": "/approval/callback",
  "callbackUrl": "https://mcp.example.com/approval/callback",
  "expiresAt": 1700000300000,
  "timestamp": 1700000000000
}
```

它从来不给会话命名. `callbackUrl` 有没有当 `FRONTMCP_PUBLIC_URL` 设置; `allowedScopes` 财务报告和审定财务报表 `maxTtlMs` 当工具限制它们时; `jwt` 仅使用 `includeJwt: true`保留 `codeVerifier` 秘密:决定 请求。 失败的请求( 错误状态, 重定向, 10 秒内没有答案) 由下一个调用再次发送 .

这一决定,被选为: `callbackPath` 并以同一秘密签署:

```json
{
  "codeVerifier": "…",
  "approved": true,
  "scope": "session",
  "ttlMs": 3600000,
  "grantedBy": { "source": "user", "identifier": "lead-7" },
  "reason": "ok"
}
```

-   被记录下来的,是给打电话的人的 要求,从来没有一个尸体的名字 `allowedScopes` 财务报告和审定财务报表 `maxTtlMs` (单位:千美元)`scope` 默认为 `requestedScope`),与 `grantedBy` 财务报告和审定财务报表 `origin: 'webhook'`A级 拒绝(`approved: false`)记录在呼叫者的会话中,并持续 `ttlMs`,或 `challengeTtl` 没有它.
-   每个 `codeVerifier` 工作过一次,直到 `challengeTtl` 通过。 重播或迟到的决定毫无作用.
-   每一个签名的,造型良好的召回 `202 { "status": "received" }`,无论它是否符合请求,所以 路由从未说明是否等待批准。 未签名或错误签名的回调,或一个以上签名的回调 几分钟前,得到 `401`一个不是决定的身体 `400`; 1 超过 16 KB `413`。 。 。 .

请求和回调与HMAC-SHA256在 [标准网络呼号](https://www.standardwebhooks.com/) 格式,所以任何标准 Webhooks 库检查它们:页眉 `webhook-id`, (中文(简体) ), `webhook-timestamp` (Unix 秒)和 (韩语) `webhook-signature: v1,<base64>`结束 `<webhook-id>.<webhook-timestamp>.<body>`检查时间戳在你这边, 并拒绝一个 `webhook-id` 你已经看到了.

`this.get(ChallengeServiceToken)` 返回插件 `ChallengeService`,这些一次性 PKCE (Proof Key) 的存储器 代码交换,RFC 7636挑战: `createChallenge(...)`, (中文(简体) ), `consume(codeVerifier)` (请求一次,或 `undefined`和 `verifyAndConsume(codeVerifier)` (请求一次,或 `ChallengeValidationError`) (中文(简体) ).

## 重新检查模式

与 `mode: 'recheck'` (默认)和 `recheck.url`需要你同意的电话 没有民调 批准API直到它决定.

```ts
ApprovalPlugin.init({
  recheck: {
    url: 'https://approvals.example.com/status',
    auth: 'bearer',
    token: process.env.APPROVALS_API_TOKEN,
    interval: 2000,
    maxAttempts: 5,
  },
});
```

| 选项 | 默认 | 说明 |
| --- | --- | --- |
| `recheck.url` |  | 状态 URL, 规则与 `webhook.url`。 。 。 . |
| `recheck.auth` | `'none'` | `'bearer'` 发送 `recheck.token`· ; `'jwt'` 转发呼叫者自己的访问信使(没有传票的呼叫); `'custom'` 发送信头 `recheck.headers(request)` 返回. |
| `recheck.token` |  | 标志 `auth: 'bearer'` 发送. |
| `recheck.headers` |  | `(request) => headers`,用于 `auth: 'custom'`。 。 。 . |
| `recheck.secret` |  | 在每张民意测验上签名时, 请签名 . |
| `recheck.interval` | `2000` | 民调之间的相差100到60000秒. |
| `recheck.maxAttempts` | `5` | 每通电话1到60. `interval × (maxAttempts − 1)` 最多两分钟. |

每份民意调查 `{ type: 'approval.status', requestId, attempt, toolId, toolName, userId?, requestedScope, ... }` (单位:千美元)`requestId` 对一个打电话者和工具的每一次民意测验都是一样的,姓名也不相同),并读作: `{ approved, pending?, scope?, ttlMs?, grantedBy?, denialReason? }`数字 :

-   `{ "approved": true }` 记录了批准情况,因为网上核准记录了批准情况,但与 `origin: 'recheck'`,则 呼叫运行。 一个 `alwaysPrompt` 工具的批准让它单独通过 并且没有存储.
-   `{ "approved": false, "pending": true }` 投票之后 `interval`; 之后 `maxAttempts` 民意调查 电话被拒绝 `pending`。 。 。 .
-   `{ "approved": false }` 拒绝调用为 `denied`. 无所存: 下一次民调.
-   一个错误状态,一个方向调整,一个不是这样的答案的身体,超过64 KB,或者10秒内没有答案拒绝 调用为 `pending`,并登录一个只列出 URL 来源的警告.

有记录的拒绝在任何信息被传票或发出之前,以两种方式拒绝打电话.

## 启动检查

`ApprovalPlugin.init()` 掷出 `ApprovalConfigurationError` (代码) `APPROVAL_CONFIGURATION`),服务器不 启动, 对于无法工作的选项 : `webhook.url` 无 `webhook.secret`,或24字节以下的秘密; `webhook.*` (不含 `challengeTtl`页:1 `mode: 'webhook'` 或无 `webhook.url`· ; `recheck` 内 `mode: 'webhook'` 或者说 无 `recheck.url`; 不是一个 URL `https://` (或外部生产回放),或在其中有资质; `auth: 'bearer'` 无 `token`, (中文(简体) ), `auth: 'custom'` 无 `headers`,或为另一个设定 `auth`; 一个 `interval` 或者说 `maxAttempts` a 区域外;和 `callbackPath` 这不是一条平坦的道路,服务器保留了 MCP 端点, `/oauth/*`, (中文(简体) ), `/.well-known/*`),或另一个 `ApprovalPlugin` 服务。 最多为1.11.2项选择 被接受和忽视.

## 文档

-   [批准插件参考](https://frontmcp.dev/reference/plugins/approval): 每个选项、方法、出错和 备注,有可重复的例子
-   [请求批准](https://frontmcp.dev/learn/asking-for-approval): 逐步建造大门和询问
-   [插件和适配器](https://frontmcp.dev/reference/plugins): 在哪里注册插件

## 相关软件包

-   [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk): 此插件扩展的框架
-   [`@frontmcp/plugin-feature-flags`](https://www.npmjs.com/package/@frontmcp/plugin-feature-flags): 隐藏和块 特性标记后的工具
-   [`@frontmcp/plugin-remember`](https://www.npmjs.com/package/@frontmcp/plugin-remember)数字 : `this.remember`,一个记忆 用于工具

## 捐款

资料来源: [`plugins/plugin-approval`](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-approval)问题 欢迎抽取请求;见 [捐款额](https://github.com/agentfront/frontmcp/blob/main/CONTRIBUTING.md)。 。 。 .

## 许可证

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

## 常见问题

### @frontmcp/plugin-approval 是什么？

FrontMCP 的批准插件: 拒绝运行标记工具, 直至为调用者记录批准

### 如何安装 @frontmcp/plugin-approval？

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

### @frontmcp/plugin-approval 支持 TypeScript 吗？

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

### @frontmcp/plugin-approval 支持 ESM 还是 CommonJS？

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

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

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

### @frontmcp/plugin-approval 可以商用吗？

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

### @frontmcp/plugin-approval 的下载量有多少？

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

### @frontmcp/plugin-approval 还在维护吗？

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

