Skip to main content
Glama

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-сборку

  • CLIhono-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/todos

  • MCP на http://localhost:3000/mcp

  • Tool 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),
});

Поле

Примечания

id

Используется как есть. В противном случае "<namespace>.<name>", где name преобразуется в snake_case

inputSchema / outputSchema

TypeBox, Zod или обычный JSON Schema

annotations

readonly, destructive, idempotent, requiresApproval, openWorld, streaming, cacheable, …

params

Пояснения для каждого параметра, объединяемые в схему ввода. JavaScript не может прочитать ведущие комментарии функции во время выполнения так, как Python читает docstring, поэтому это явно

handler

(inputs, context) => result. Необъектный результат оборачивается как { result }

Сканирование маршрутов — инструменты без вторжения

Направьте сканер на приложение, и каждый маршрут станет модулем, который воспроизводит его в процессе через 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-глагола:

Маршрут

Идентификатор модуля

Выведенные аннотации

GET /todos

todos.list

readonly, cacheable

GET /todos/:id

todos.get

readonly, cacheable

POST /todos

todos.create

PUT /todos/:id

todos.update

idempotent

DELETE /todos/:id

todos.delete

destructive

Сгенерированная схема ввода содержит одно обязательное строковое свойство для каждого параметра пути, плюс свободный объект 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
})

Метод

Описание

init(app?, routeOptions?)

Обнаруживает, регистрирует инструменты и привязки, сканирует маршруты, запускает автономные поверхности. Идемпотентно.

ready()

Ожидает завершения выполняющегося init().

registerTool(tool) / registerTools(tools)

Регистрирует определения инструментов во время выполнения.

registerMethod(opts) / registerObject(opts)

Регистрирует методы обычного сервисного объекта.

scanRoutes(app, opts?)

Сканирует и регистрирует маршруты приложения.

routeOptions

Объединённые параметры сканирования маршрутов, которые использует этот экземпляр.

loadBindings(path?, resolver?)

Загружает файл YAML-привязок.

mountMcp(app, opts?)

Монтирует /mcp, Explorer и /health в приложение.

toOpenaiTools(opts?)

Совместимые с OpenAI определения функций.

close()

Завершает работу поверхностей 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-idAuthorization: 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:

Поле

Тип

Описание

transport

'stdio' | 'streamable-http' | 'sse'

Автономный транспорт. Его установка заставляет init() запустить сервер.

host / port

string / number

Адрес привязки для HTTP-транспортов.

name / version

string

Идентичность сервера.

explorer / explorerPrefix / allowExecute

Веб-интерфейс Tool Explorer.

authenticator / requireAuth / exemptPaths

JWT или пользовательская аутентификация.

tags / prefix

Предоставлять только соответствующие модули.

validateInputs

boolean

Принудительно проверять схемы ввода при каждом вызове.

observability

Метрики + middleware использования и их конечные точки.

outputFormat / outputFormatter / redactOutput / trace

Сериализация результатов.

approvalHandler / approvalStore / approvalNotify

Шлюз одобрения для разрушительных инструментов.

mcpMiddleware / mcpAcl

Дополнительный middleware apcore / ACL для исполнителя MCP.

Адаптеры схем

Схемы автоматически обнаруживаются и преобразуются через цепочку приоритетов:

Адаптер

Приоритет

Вход

TypeBoxAdapter

100

схемы @sinclair/typebox

ZodAdapter

50

Zod 3 (_def.typeName) и Zod 4 (_zod.def.type)

JsonSchemaAdapter

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: false
import { 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:

Переменная

Тип

По умолчанию

Назначение

APCORE_ENABLED

bool

true

Главный переключатель — false делает init() no-op

APCORE_DEBUG

bool

false

Подробное логирование / интроспекция

APCORE_SCANNERS

list

["auto"]

Идентификаторы включённых сканеров

APCORE_INCLUDE_PATHS

list

[]

Шаблоны маршрутов для включения (пусто = все)

APCORE_EXCLUDE_PATHS

list

[]

Шаблоны маршрутов для исключения

APCORE_MODULE_PREFIX

str

""

Префикс, добавляемый к сгенерированным идентификаторам модулей

APCORE_AUTH_ENABLED

bool

false

Требовать аутентификацию для конечных точек MCP/A2A

APCORE_AUTH_STRATEGY

str

"bearer"

bearer / session / custom

APCORE_TRANSPORT

str

"stdio"

Транспорт MCP: stdio / http / sse

APCORE_HOST

str

"0.0.0.0"

Адрес привязки, когда транспорт не stdio

APCORE_PORT

int

8808

Порт привязки, когда транспорт не 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.

Примеры

Пример

Показывает

examples/demo

Полное приложение: инструменты, написанные вручную, и сканирование маршрутов, JWT, ACL, системные модули, Docker

examples/acl_demo

Маршруты, управляемые ACL apcore — orders.delete только для администраторов

pnpm install && pnpm build
cd examples/demo && pnpm install && pnpm dev

Подробная документация

Скрипты

Команда

Описание

pnpm build

Компиляция TypeScript

pnpm dev

Компиляция в режиме наблюдения

pnpm test

Запуск набора тестов (vitest)

pnpm test:coverage

Тесты с покрытием (порог 90%)

pnpm typecheck

Проверка типов без генерации кода

pnpm lint

Линтинг исходников и тестов

Лицензия

Apache-2.0

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes 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.
    32
    86
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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.
    5
    Apache 2.0
  • A
    license
    B
    quality
    C
    maintenance
    Transforms OpenAPI definitions into MCP tools for seamless LLM-API integration.
    8
    39
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Easily expose your Hono API endpoints as MCP tools with minimal configuration, supporting type-safe input handling and tool registration.
    32
    2
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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