hono-apcore
hono-apcore
Hono 适配器,用于 apcore AI-Perceivable 模块生态系统。将 Hono 应用转换为 MCP 工具和 OpenAI 兼容的函数定义——既可以通过显式声明工具,也可以通过扫描已有的路由。
特性
两种方式 — 使用
defineTool()/defineToolset()声明工具,或零代码更改扫描现有路由路由重放 — 扫描的路由成为通过
app.request()回调的模块,因此中间件、验证器和错误处理程序仍然全部运行单端口 —
mountMcp()从同一个 Hono 应用提供 MCP 端点、工具浏览器和/health注解推断 —
GET→ readonly + cacheable,PUT→ idempotent,DELETE→ destructive(RFC 9110 安全方法语义)多模式 — TypeBox、Zod 3、Zod 4 和纯 JSON Schema,通过优先级链自动检测
上下文、ACL 和身份 —
apcore()中间件构建每个请求的 apcoreContext,并带有 W3C 跟踪传播,因此 ACL 规则也管理你的路由运行时无关核心 —
apcore-mcp、apcore-cli和apcore-a2a是可选的对等依赖,按需加载,因此导入hono-apcore永远不会将node:http拖入边缘构建CLI —
hono-apcore scan | serve | export可针对普通 Hono 应用工作YAML 绑定 — 以声明方式注册模块,无需修改源代码
Related MCP server: Graft
安装
npm install hono-apcore hono可选的对等依赖,仅为你使用的功能安装:
npm install apcore-mcp @modelcontextprotocol/sdk # MCP server + Tool Explorer
npm install @hono/node-server # mountMcp() on the Node runtime
npm install apcore-cli # CLI surface
npm install apcore-a2a # A2A agent surface
npm install @sinclair/typebox # TypeBox schemas (recommended)
npm install zod # Zod schemas要求: Node.js >= 18,Hono >= 4(已在 Hono 4.13 上测试)。
快速开始
1. 声明一些工具
// todo.tools.ts
import { Type } from '@sinclair/typebox';
import { defineToolset } from 'hono-apcore';
export const todoTools = defineToolset({
namespace: 'todo',
description: 'Todo list management',
tags: ['todo'],
tools: {
list: {
description: 'List all todos, optionally filtered by status',
inputSchema: Type.Object({ done: Type.Optional(Type.Boolean()) }),
annotations: { readonly: true, idempotent: true },
handler: (inputs) => ({ todos: store.list(inputs.done as boolean | undefined) }),
},
add: {
description: 'Add a new todo item',
inputSchema: Type.Object({ title: Type.String() }),
annotations: { readonly: false },
handler: (inputs) => ({ todo: store.add(String(inputs.title)) }),
},
},
});2. 将其接入应用
// app.ts
import { Hono } from 'hono';
import { apcore, createApcore } from 'hono-apcore';
import { todoTools } from './todo.tools.js';
export const ap = createApcore({
tools: todoTools,
mcp: { name: 'my-app', explorer: true, allowExecute: true },
});
export const app = new Hono();
app.use('*', apcore(ap));
app.get('/todos', (c) => c.json(store.list()));3. 启动
// main.ts
import { serve } from '@hono/node-server';
import { app, ap } from './app.js';
await ap.init(app); // register tools + scan routes
await ap.mountMcp(app); // mount /mcp, /explorer, /health
serve({ fetch: app.fetch, port: 3000 });你的应用现在响应:
REST 位于
http://localhost:3000/todosMCP 位于
http://localhost:3000/mcp工具浏览器 位于
http://localhost:3000/explorer/
暴露能力的两种方式
defineTool() — 显式工具
这是 NestJS 的 @ApTool 装饰器的 Hono 对应物。Hono 没有可装饰的类或 DI 容器,因此工具是一个携带自身元数据和处理程序的普通对象。
import { defineTool } from 'hono-apcore';
const sendEmail = defineTool({
namespace: 'email',
name: 'send', // -> module id "email.send"
description: 'Send an email',
inputSchema: Type.Object({ to: Type.String(), body: Type.String() }),
outputSchema: Type.Object({ messageId: Type.String() }),
annotations: { readonly: false, destructive: false, requiresApproval: true },
tags: ['email'],
params: { to: 'Recipient address' }, // merged into the schema descriptions
handler: async (inputs, context) => mailer.send(inputs, context),
});字段 | 说明 |
| 原样使用。否则为 |
| TypeBox、Zod 或纯 JSON Schema |
|
|
| 每个参数的说明文本合并到输入模式中。JavaScript 无法像 Python 读取 docstring 那样在运行时读取函数的前导注释,因此这是显式的 |
|
|
路由扫描 — 零侵入工具
将扫描器指向应用,每个路由都会成为一个通过 app.request() 在进程内重放它的模块:
const ap = createApcore({
routes: {
excludePaths: ['/health', '/mcp*', '/explorer*'],
modulePrefix: 'api',
},
});
await ap.init(app); // -> api.todos.list, api.todos.get, api.todos.create, …模块 ID 来自路径和 HTTP 动词:
路由 | 模块 ID | 推断的注解 |
|
|
|
|
|
|
|
| — |
|
|
|
|
|
|
生成的输入模式为每个路径参数携带一个必需的字符串属性,外加一个自由形式的 query 对象(GET/DELETE)或 body 对象(POST/PUT/PATCH)。可以按路由覆盖其中任何部分:
routes: {
overrides: {
'GET /todos': {
id: 'todo.all',
description: 'Every todo, newest first',
inputSchema: Type.Object({ done: Type.Optional(Type.Boolean()) }),
annotations: { readonly: true, idempotent: true },
},
'DELETE /admin/wipe': { skip: true },
},
}由于执行通过 app.request() 返回,AI 调用与 HTTP 调用运行相同的代码路径——包括认证中间件、验证器、错误处理程序等。来自 apcore Context 的身份和 W3C 跟踪头会被转发到重放的请求上。
API 参考
createApcore(options)
返回一个 HonoApcore — 注册表、执行器和所有表面都挂载在它上面。
createApcore({
extensionsDir?: string | null, // scanned by Registry.discover()
acl?: ACL, // enforced by the Executor on every call
middleware?: Middleware[], // apcore middleware installed on the Executor
bindings?: string, // YAML bindings file loaded during init()
tools?: ApToolDefinition[], // registered during init()
routes?: RouteScanOptions, // route-scanner configuration
settings?: Partial<ApcoreSettings>, // overrides for the APCORE_* settings
mcp?: ApcoreMcpOptions, // presence enables the MCP surface
cli?: ApcoreCliOptions, // presence enables the CLI surface
a2a?: ApcoreA2aOptions, // presence enables the A2A surface
})方法 | 说明 |
| 发现、注册工具和绑定,扫描路由,启动独立表面。幂等 |
| 等待进行中的 |
| 在运行时注册工具定义 |
| 注册普通服务对象的方法 |
| 扫描并注册应用的路由 |
| 此实例将使用的合并路由扫描选项 |
| 加载 YAML 绑定文件 |
| 将 |
| OpenAI 兼容的函数定义 |
| 关闭 MCP 和 A2A 表面 |
apcore(instance | options, middlewareOptions?)
Hono 中间件,将实例和每个请求的 apcore Context 放到 Hono 上下文上。
app.use('*', apcore(ap));
app.get('/orders', async (c) =>
c.json(await getApcore(c).executor.call('orders.list', {}, getApcoreContext(c))),
);变量映射被增强,因此 c.get('apcore') 和 c.get('apcoreContext') 也有类型。在从不调用模块的路由上传递 { skipContext: true },或传递 { contextFactory } 以接入真实认证。
HonoContextFactory
从 Hono 上下文、Request 或裸 Headers 构建 apcore Context。
身份解析顺序:x-user-id → Authorization: Bearer …(身份 id "bearer")→ 裸 x-roles 头(演示快捷方式)→ 匿名。traceparent 头提供跟踪 id;x-correlation-id(或 x-request-id)进入 context.data。
new HonoContextFactory({
resolveIdentity: (headers) => identityFromSession(headers), // wins over the above
data: (headers) => ({ tenant: headers.get('x-tenant') }),
});MCP
ApcoreMcpService 以两种方式运行 MCP 服务器。
嵌入式 — 一个进程,一个端口:
await ap.mountMcp(app, { endpoint: '/mcp', explorer: true, allowExecute: true });这需要 @hono/node-server 在 c.env 上暴露的原始 Node 请求和响应对象,因此仅限 Node;其他运行时上的挂载处理程序会以该说明回答 501。endpoint 必须是 HTTP 服务器看到的路径——如果应用位于 basePath 下,请包含前缀。
独立 — 单独的端口,或用于 CLI 启动的服务器的 stdio:
createApcore({ mcp: { transport: 'streamable-http', host: '0.0.0.0', port: 8000 } });
// init() starts it, because `transport` was set explicitly关键 MCP 选项:
字段 | 类型 | 说明 |
|
| 独立传输。设置它会使 |
|
| HTTP 传输的绑定地址 |
|
| 服务器身份 |
| 工具浏览器 Web UI | |
| JWT 或自定义认证 | |
| 仅暴露匹配的模块 | |
|
| 在每次调用时强制执行输入模式 |
| 指标 + 使用中间件及其端点 | |
| 结果序列化 | |
| 破坏性工具的审批门 | |
| 为 MCP 执行器提供的额外 apcore 中间件 / ACL |
模式适配器
模式通过优先级链自动检测和转换:
适配器 | 优先级 | 输入 |
| 100 |
|
| 50 | Zod 3( |
| 30 | 纯 JSON Schema 对象 |
检测是结构性的——运行时不会导入 TypeBox 或 Zod——因此宿主应用安装哪个(或都不安装)都可以。使用 SchemaExtractor.registerAdapter() 注册你自己的适配器。
YAML 绑定
无需修改源代码即可注册模块:
bindings:
- module_id: email.send
target: EmailService.send
description: Send an email
input_schema:
type: object
properties:
to: { type: string }
tags: [email, mutate]
annotations:
readonly: falseimport { resolverFromObjects } from 'hono-apcore';
await ap.loadBindings('./bindings.yaml', resolverFromObjects({ EmailService: mailer }));反过来,writeBindingsFile() 将扫描的模块序列化输出——这正是 hono-apcore scan --format yaml 所做的。
CLI
hono-apcore scan ./src/app.ts # print the modules a scan would produce
hono-apcore scan ./src/app.ts --format yaml --out bindings.yaml
hono-apcore serve ./src/app.ts --transport http --port 8000 --explorer
hono-apcore export ./src/app.ts --out tools.json入口是 path[:export];导出默认为 default,然后是 app。如果模块以任何名称导出 HonoApcore,其配置——路由过滤器、模块前缀、MCP 选项——会被尊重,因此 scan 报告应用自身注册的模块;CLI 标志会覆盖它。没有实例的入口仍然有效,因此 serve 可以针对从未听说过 apcore 的应用运行。TypeScript 入口需要加载器:
npx tsx node_modules/.bin/hono-apcore scan ./src/app.ts配置(APCORE_*)
每个 apcore 集成实现的标准设置,从环境读取并可通过 settings 覆盖:
Variable | Type | Default | Purpose |
| bool |
| 主开关—— |
| bool |
| 详细日志/内省 |
| list |
| 启用的扫描器标识符 |
| list |
| 要包含的路由模式(空 = 全部) |
| list |
| 要排除的路由模式 |
| str |
| 附加到生成的模块 ID 的前缀 |
| bool |
| MCP/A2A 端点需要身份验证 |
| str |
|
|
| str |
| MCP 传输: |
| str |
| 当传输不是 stdio 时的绑定地址 |
| int |
| 当传输不是 stdio 时的绑定端口 |
可选对等依赖不会被重新导出
与 NestJS 适配器不同,hono-apcore 不重新导出 apcore-mcp / apcore-cli / apcore-a2a 接口。这样做会使它们被急切加载,而 apcore-mcp 会引入 node:http——这会破坏从不使用 MCP 接口的 Workers、Deno 或 Bun 应用构建。请从它们各自的包中导入这些符号:
import { JWTAuthenticator, getCurrentIdentity } from 'apcore-mcp';
import { createCli } from 'apcore-cli';
import { A2AClient } from 'apcore-a2a';apcore-js 和 apcore-toolkit 是硬依赖,因此它们的公共符号(ACL、Config、registerSysModules、TraceContext、BaseScanner、formatModules 等)直接从 hono-apcore 重新导出。
示例
示例 | 展示 |
完整应用:手写工具和路由扫描、JWT、ACL、系统模块、Docker | |
由 apcore ACL 管理的路由—— |
pnpm install && pnpm build
cd examples/demo && pnpm install && pnpm dev详细文档
功能概览 — 架构和依赖关系图
工具定义 —
defineTool、defineToolset、模块 ID路由扫描器 — 路由如何成为模块,以及重放的成本
MCP 集成 — 嵌入式与独立式,Node 桥接
模式提取 — 适配器链和自定义适配器
上下文和 ACL — 身份、追踪和路由治理
脚本
命令 | 描述 |
| 编译 TypeScript |
| 监视模式编译 |
| 运行测试套件(vitest) |
| 带覆盖率的测试(90% 阈值) |
| 类型检查(不输出) |
| 检查源代码和测试 |
许可证
Apache-2.0
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes Hono API endpoints as Model Context Protocol tools, allowing LLMs to interact with your API routes through a dedicated MCP endpoint. It provides helpers to describe routes and includes a codemode for dynamic API interaction via search and execute tools.3286MIT
- AlicenseNot gradedqualityCmaintenanceEnables building agent-ready APIs that expose tools as both HTTP and MCP endpoints from a single server definition, with automatic OpenAPI, discovery docs, and interactive API reference.5Apache 2.0
- AlicenseBqualityCmaintenanceTransforms OpenAPI definitions into MCP tools for seamless LLM-API integration.8391MIT
- AlicenseNot gradedqualityCmaintenanceEasily expose your Hono API endpoints as MCP tools with minimal configuration, supporting type-safe input handling and tool registration.322MIT
Related MCP Connectors
Point Gecko at an OpenAPI spec; get first-call-correct, auth-hidden agent tools.
Free public MCP for AI agents — 193 tools, 44 workflows. No API key.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aiperceivable/hono-apcore'
If you have feedback or need assistance with the MCP directory API, please join our Discord server