hono-apcore
hono-apcore
Адаптер Hono для экосистемы модулей apcore AI-Perceivable. Превращает приложение Hono в инструменты MCP и совместимые с OpenAI определения функций — либо объявляя инструменты явно, либо сканируя уже имеющиеся маршруты.
Возможности
Два способа — объявляйте инструменты с помощью
defineTool()/defineToolset(), или сканируйте существующие маршруты без изменений кодаПовторный вызов маршрута — сканированный маршрут становится модулем, который вызывает обратно через
app.request(), так что middleware, валидаторы и обработчики ошибок по-прежнему работаютОдин порт —
mountMcp()обслуживает конечную точку MCP, Tool Explorer и/healthиз одного и того же приложения HonoВывод аннотаций —
GET→ readonly + cacheable,PUT→ idempotent,DELETE→ destructive (семантика безопасных методов RFC 9110)Мультисхема — TypeBox, Zod 3, Zod 4 и обычный JSON Schema, автоматически определяемые через цепочку приоритетов
Контекст, ACL и идентичность — middleware
apcore()создаёт контекст apcore для каждого запроса с распространением трассировки W3C, так что правила ACL также управляют вашими маршрутамиЯдро, не зависящее от среды выполнения —
apcore-mcp,apcore-cliиapcore-a2a— это опциональные пиры, загружаемые лениво, поэтому импортhono-apcoreникогда не тянетnode:httpв edge-сборкуCLI —
hono-apcore scan | serve | exportработает с обычным приложением HonoYAML-привязки — регистрируйте модули декларативно, не касаясь исходного кода
Related MCP server: hono-mcp-server
Установка
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/mcpTool Explorer на
http://localhost:3000/explorer/
Два способа предоставить возможность
defineTool() — явные инструменты
Аналог декоратора @ApTool из NestJS для 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, …Идентификаторы модулей формируются из пути и HTTP-глагола:
Маршрут | Идентификатор модуля | Выведенные аннотации |
|
|
|
|
|
|
|
| — |
|
|
|
|
|
|
Сгенерированная схема ввода содержит одно обязательное строковое свойство для каждого параметра пути, плюс свободный объект 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(), вызов ИИ проходит по тому же пути кода, что и HTTP-вызов — middleware аутентификации, валидаторы, обработчики ошибок и всё остальное. Идентичность и заголовки трассировки W3C из контекста apcore Context передаются в повторяемый запрос.
Справочник 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?)
Middleware 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
Создаёт контекст apcore Context из контекста Hono, объекта Request или простых Headers.
Разрешение идентичности по порядку: x-user-id → Authorization: Bearer … (идентификатор "bearer") → простой заголовок x-roles (демонстрационный ярлык) → аноним. Заголовок traceparent предоставляет идентификатор трассировки; 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 });Для этого нужны сырые объекты запроса и ответа Node, которые @hono/node-server предоставляет в c.env, поэтому это работает только в Node; смонтированный обработчик на другой среде выполнения отвечает 501 с этим объяснением. endpoint должен быть путём, как его видит HTTP-сервер — включите префикс, если приложение находится под basePath.
Автономный — отдельный порт или stdio для сервера, запущенного из CLI:
createApcore({ mcp: { transport: 'streamable-http', host: '0.0.0.0', port: 8000 } });
// init() starts it, because `transport` was set explicitlyКлючевые параметры MCP:
Поле | Тип | Описание |
|
| Автономный транспорт. Его установка заставляет |
|
| Адрес привязки для HTTP-транспортов. |
|
| Идентичность сервера. |
| Веб-интерфейс Tool Explorer. | |
| JWT или пользовательская аутентификация. | |
| Предоставлять только соответствующие модули. | |
|
| Принудительно проверять схемы ввода при каждом вызове. |
| Метрики + middleware использования и их конечные точки. | |
| Сериализация результатов. | |
| Шлюз одобрения для разрушительных инструментов. | |
| Дополнительный middleware apcore / ACL для исполнителя MCP. |
Адаптеры схем
Схемы автоматически обнаруживаются и преобразуются через цепочку приоритетов:
Адаптер | Приоритет | Вход |
| 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:
Переменная | Тип | По умолчанию | Назначение |
| bool |
| Главный переключатель — |
| bool |
| Подробное логирование / интроспекция |
| list |
| Идентификаторы включённых сканеров |
| list |
| Шаблоны маршрутов для включения (пусто = все) |
| list |
| Шаблоны маршрутов для исключения |
| str |
| Префикс, добавляемый к сгенерированным идентификаторам модулей |
| bool |
| Требовать аутентификацию для конечных точек MCP/A2A |
| str |
|
|
| str |
| Транспорт MCP: |
| str |
| Адрес привязки, когда транспорт не stdio |
| int |
| Порт привязки, когда транспорт не stdio |
Дополнительные пакеты не реэкспортируются
В отличие от адаптера NestJS, hono-apcore не реэкспортирует поверхности apcore-mcp / apcore-cli / apcore-a2a. В противном случае они загружались бы немедленно, а apcore-mcp подтягивает node:http — что ломает сборку приложения для Workers, Deno или Bun, которое никогда не использует поверхность MCP. Импортируйте эти символы из их собственных пакетов:
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 | |
Маршруты, управляемые ACL apcore — |
pnpm install && pnpm build
cd examples/demo && pnpm install && pnpm devПодробная документация
Обзор возможностей — архитектура и граф зависимостей
Определение инструментов —
defineTool,defineToolset, идентификаторы модулейСканер маршрутов — как маршруты становятся модулями и какова стоимость повторного воспроизведения
Интеграция MCP — встроенный и автономный режимы, мост Node
Извлечение схемы — цепочка адаптеров и пользовательские адаптеры
Контекст и ACL — идентификация, трассировка и управление маршрутами
Скрипты
Команда | Описание |
| Компиляция TypeScript |
| Компиляция в режиме наблюдения |
| Запуск набора тестов (vitest) |
| Тесты с покрытием (порог 90%) |
| Проверка типов без генерации кода |
| Линтинг исходников и тестов |
Лицензия
Apache-2.0
This server cannot be deployed
Maintenance
Related MCP Connectors
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client.
Give any MCP-compatible AI assistant a builder for live, hosted web tools and workflows.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
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.34 npm86MIT
- AlicenseNot gradedqualityCmaintenanceEasily expose your Hono API endpoints as MCP tools with minimal configuration, supporting type-safe input handling and tool registration.34 npm2MIT
- AlicenseNot gradedqualityDmaintenanceExposes OpenAPI endpoints as MCP tools, enabling LLMs to discover and interact with REST APIs through the MCP protocol.9 npmMIT
- AlicenseNot gradedqualityCmaintenanceExposes FastAPI routes as MCP tools with auto-discovery, Pydantic schema extraction, and built-in observability.Apache 2.0