hono-apcore 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +426 -0
  3. package/dist/a2a/apcore-a2a.service.d.ts +44 -0
  4. package/dist/a2a/apcore-a2a.service.d.ts.map +1 -0
  5. package/dist/a2a/apcore-a2a.service.js +82 -0
  6. package/dist/a2a/apcore-a2a.service.js.map +1 -0
  7. package/dist/a2a/index.d.ts +2 -0
  8. package/dist/a2a/index.d.ts.map +1 -0
  9. package/dist/a2a/index.js +2 -0
  10. package/dist/a2a/index.js.map +1 -0
  11. package/dist/bridge/binding-loader.d.ts +45 -0
  12. package/dist/bridge/binding-loader.d.ts.map +1 -0
  13. package/dist/bridge/binding-loader.js +84 -0
  14. package/dist/bridge/binding-loader.js.map +1 -0
  15. package/dist/bridge/index.d.ts +3 -0
  16. package/dist/bridge/index.d.ts.map +1 -0
  17. package/dist/bridge/index.js +2 -0
  18. package/dist/bridge/index.js.map +1 -0
  19. package/dist/cli/apcore-cli.service.d.ts +50 -0
  20. package/dist/cli/apcore-cli.service.d.ts.map +1 -0
  21. package/dist/cli/apcore-cli.service.js +76 -0
  22. package/dist/cli/apcore-cli.service.js.map +1 -0
  23. package/dist/cli/index.d.ts +2 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +2 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/cli.d.ts +4 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +247 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/config.d.ts +55 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +86 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/constants.d.ts +27 -0
  36. package/dist/constants.d.ts.map +1 -0
  37. package/dist/constants.js +27 -0
  38. package/dist/constants.js.map +1 -0
  39. package/dist/context/hono-context.factory.d.ts +61 -0
  40. package/dist/context/hono-context.factory.d.ts.map +1 -0
  41. package/dist/context/hono-context.factory.js +117 -0
  42. package/dist/context/hono-context.factory.js.map +1 -0
  43. package/dist/context/index.d.ts +3 -0
  44. package/dist/context/index.d.ts.map +1 -0
  45. package/dist/context/index.js +2 -0
  46. package/dist/context/index.js.map +1 -0
  47. package/dist/core/apcore.d.ts +135 -0
  48. package/dist/core/apcore.d.ts.map +1 -0
  49. package/dist/core/apcore.js +257 -0
  50. package/dist/core/apcore.js.map +1 -0
  51. package/dist/core/executor.d.ts +32 -0
  52. package/dist/core/executor.d.ts.map +1 -0
  53. package/dist/core/executor.js +41 -0
  54. package/dist/core/executor.js.map +1 -0
  55. package/dist/core/middleware.d.ts +61 -0
  56. package/dist/core/middleware.d.ts.map +1 -0
  57. package/dist/core/middleware.js +51 -0
  58. package/dist/core/middleware.js.map +1 -0
  59. package/dist/core/registry.d.ts +79 -0
  60. package/dist/core/registry.d.ts.map +1 -0
  61. package/dist/core/registry.js +218 -0
  62. package/dist/core/registry.js.map +1 -0
  63. package/dist/index.d.ts +33 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +71 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/mcp/apcore-mcp.service.d.ts +83 -0
  68. package/dist/mcp/apcore-mcp.service.d.ts.map +1 -0
  69. package/dist/mcp/apcore-mcp.service.js +189 -0
  70. package/dist/mcp/apcore-mcp.service.js.map +1 -0
  71. package/dist/mcp/index.d.ts +5 -0
  72. package/dist/mcp/index.d.ts.map +1 -0
  73. package/dist/mcp/index.js +3 -0
  74. package/dist/mcp/index.js.map +1 -0
  75. package/dist/mcp/mount.d.ts +51 -0
  76. package/dist/mcp/mount.d.ts.map +1 -0
  77. package/dist/mcp/mount.js +95 -0
  78. package/dist/mcp/mount.js.map +1 -0
  79. package/dist/output/index.d.ts +3 -0
  80. package/dist/output/index.d.ts.map +1 -0
  81. package/dist/output/index.js +2 -0
  82. package/dist/output/index.js.map +1 -0
  83. package/dist/output/yaml-writer.d.ts +31 -0
  84. package/dist/output/yaml-writer.d.ts.map +1 -0
  85. package/dist/output/yaml-writer.js +49 -0
  86. package/dist/output/yaml-writer.js.map +1 -0
  87. package/dist/scanners/hono-route-scanner.d.ts +60 -0
  88. package/dist/scanners/hono-route-scanner.d.ts.map +1 -0
  89. package/dist/scanners/hono-route-scanner.js +217 -0
  90. package/dist/scanners/hono-route-scanner.js.map +1 -0
  91. package/dist/scanners/index.d.ts +3 -0
  92. package/dist/scanners/index.d.ts.map +1 -0
  93. package/dist/scanners/index.js +2 -0
  94. package/dist/scanners/index.js.map +1 -0
  95. package/dist/schema/adapters/json-schema.adapter.d.ts +23 -0
  96. package/dist/schema/adapters/json-schema.adapter.d.ts.map +1 -0
  97. package/dist/schema/adapters/json-schema.adapter.js +40 -0
  98. package/dist/schema/adapters/json-schema.adapter.js.map +1 -0
  99. package/dist/schema/adapters/schema-adapter.interface.d.ts +24 -0
  100. package/dist/schema/adapters/schema-adapter.interface.d.ts.map +1 -0
  101. package/dist/schema/adapters/schema-adapter.interface.js +2 -0
  102. package/dist/schema/adapters/schema-adapter.interface.js.map +1 -0
  103. package/dist/schema/adapters/typebox.adapter.d.ts +26 -0
  104. package/dist/schema/adapters/typebox.adapter.d.ts.map +1 -0
  105. package/dist/schema/adapters/typebox.adapter.js +39 -0
  106. package/dist/schema/adapters/typebox.adapter.js.map +1 -0
  107. package/dist/schema/adapters/zod.adapter.d.ts +17 -0
  108. package/dist/schema/adapters/zod.adapter.d.ts.map +1 -0
  109. package/dist/schema/adapters/zod.adapter.js +372 -0
  110. package/dist/schema/adapters/zod.adapter.js.map +1 -0
  111. package/dist/schema/index.d.ts +6 -0
  112. package/dist/schema/index.d.ts.map +1 -0
  113. package/dist/schema/index.js +5 -0
  114. package/dist/schema/index.js.map +1 -0
  115. package/dist/schema/schema-extractor.d.ts +51 -0
  116. package/dist/schema/schema-extractor.d.ts.map +1 -0
  117. package/dist/schema/schema-extractor.js +89 -0
  118. package/dist/schema/schema-extractor.js.map +1 -0
  119. package/dist/tools/define-tool.d.ts +68 -0
  120. package/dist/tools/define-tool.d.ts.map +1 -0
  121. package/dist/tools/define-tool.js +122 -0
  122. package/dist/tools/define-tool.js.map +1 -0
  123. package/dist/tools/index.d.ts +3 -0
  124. package/dist/tools/index.d.ts.map +1 -0
  125. package/dist/tools/index.js +2 -0
  126. package/dist/tools/index.js.map +1 -0
  127. package/dist/types.d.ts +246 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +2 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/utils/id-generator.d.ts +52 -0
  132. package/dist/utils/id-generator.d.ts.map +1 -0
  133. package/dist/utils/id-generator.js +87 -0
  134. package/dist/utils/id-generator.js.map +1 -0
  135. package/dist/utils/module-factory.d.ts +34 -0
  136. package/dist/utils/module-factory.d.ts.map +1 -0
  137. package/dist/utils/module-factory.js +59 -0
  138. package/dist/utils/module-factory.js.map +1 -0
  139. package/package.json +109 -0
@@ -0,0 +1,189 @@
1
+ /** Options forwarded to both `serve()` and `asyncServe()`. */
2
+ const SHARED_OPTION_KEYS = [
3
+ 'name',
4
+ 'version',
5
+ 'tags',
6
+ 'prefix',
7
+ 'validateInputs',
8
+ 'logLevel',
9
+ 'metricsCollector',
10
+ 'observability',
11
+ 'authenticator',
12
+ 'requireAuth',
13
+ 'exemptPaths',
14
+ 'approvalHandler',
15
+ 'approvalStore',
16
+ 'approvalNotify',
17
+ 'outputFormatter',
18
+ 'outputFormat',
19
+ 'redactOutput',
20
+ 'trace',
21
+ 'strategy',
22
+ ];
23
+ /** Options only `serve()` understands (they configure a standalone server). */
24
+ const SERVE_ONLY_KEYS = [
25
+ 'transport',
26
+ 'host',
27
+ 'port',
28
+ 'explorer',
29
+ 'explorerPrefix',
30
+ 'allowExecute',
31
+ 'dynamic',
32
+ 'onStartup',
33
+ 'onShutdown',
34
+ 'explorerTitle',
35
+ 'explorerProjectName',
36
+ 'explorerProjectUrl',
37
+ ];
38
+ /** Options renamed on their way to `apcore-mcp`. */
39
+ const RENAMED_OPTIONS = {
40
+ mcpMiddleware: 'middleware',
41
+ mcpAcl: 'acl',
42
+ };
43
+ /**
44
+ * Manages the MCP (Model Context Protocol) server for a Hono app.
45
+ *
46
+ * `apcore-mcp` is an **optional** peer dependency and is loaded lazily, so
47
+ * importing `hono-apcore` stays safe on runtimes without `node:http`
48
+ * (Workers, Deno, Bun) as long as the MCP surface goes unused there.
49
+ *
50
+ * Two deployment shapes are supported:
51
+ *
52
+ * - **Standalone** — {@link start} runs an MCP server on its own port, next
53
+ * to the Hono HTTP server. Configure `transport` to enable it.
54
+ * - **Embedded** — {@link asyncServe} returns a request handler that
55
+ * {@link mountMcp} wires into the Hono app itself, so one port serves both.
56
+ */
57
+ export class ApcoreMcpService {
58
+ registry;
59
+ executor;
60
+ options;
61
+ _isRunning = false;
62
+ _app = null;
63
+ constructor(registry, executor, options) {
64
+ this.registry = registry;
65
+ this.executor = executor;
66
+ this.options = options;
67
+ }
68
+ // -------------------------------------------------------------------------
69
+ // Properties
70
+ // -------------------------------------------------------------------------
71
+ /** Whether a standalone MCP server has been started. */
72
+ get isRunning() {
73
+ return this._isRunning;
74
+ }
75
+ /** The embedded MCP app, once {@link asyncServe} has built one. */
76
+ get app() {
77
+ return this._app;
78
+ }
79
+ /** Number of tools exposed, honouring the module-level `tags` / `prefix`. */
80
+ get toolCount() {
81
+ return this.registry.list({
82
+ tags: this.options.tags ?? undefined,
83
+ prefix: this.options.prefix ?? undefined,
84
+ }).length;
85
+ }
86
+ // -------------------------------------------------------------------------
87
+ // Lifecycle
88
+ // -------------------------------------------------------------------------
89
+ /**
90
+ * Start a standalone MCP server using the configured transport.
91
+ *
92
+ * With `transport: 'stdio'` this occupies the process's stdio, so it is the
93
+ * right choice for a CLI-launched MCP server and the wrong one for a web
94
+ * process — use {@link asyncServe} there.
95
+ *
96
+ * @param overrides - Per-call option overrides, e.g. the flags the
97
+ * `hono-apcore serve` command accepts.
98
+ */
99
+ async start(overrides = {}) {
100
+ const { serve } = await import('apcore-mcp');
101
+ this._isRunning = true;
102
+ const serveOptions = {
103
+ ...this.collectOptions(SHARED_OPTION_KEYS),
104
+ ...this.collectOptions(SERVE_ONLY_KEYS),
105
+ };
106
+ for (const [key, value] of Object.entries(overrides)) {
107
+ if (value !== undefined)
108
+ serveOptions[key] = value;
109
+ }
110
+ await serve(this.executor.raw, serveOptions);
111
+ }
112
+ /**
113
+ * Build an embeddable MCP request handler without starting a server.
114
+ *
115
+ * Repeated calls return the same app; call {@link stop} to tear it down.
116
+ *
117
+ * @param options - Per-call overrides for endpoint and Explorer settings.
118
+ */
119
+ async asyncServe(options) {
120
+ if (this._app)
121
+ return this._app;
122
+ const { asyncServe } = await import('apcore-mcp');
123
+ const asyncOptions = {
124
+ ...this.collectOptions(SHARED_OPTION_KEYS),
125
+ explorer: options?.explorer ?? this.options.explorer,
126
+ explorerPrefix: options?.explorerPrefix ?? this.options.explorerPrefix,
127
+ allowExecute: options?.allowExecute ?? this.options.allowExecute,
128
+ explorerTitle: this.options.explorerTitle,
129
+ explorerProjectName: this.options.explorerProjectName,
130
+ explorerProjectUrl: this.options.explorerProjectUrl,
131
+ };
132
+ if (options?.endpoint !== undefined)
133
+ asyncOptions['endpoint'] = options.endpoint;
134
+ if (options?.dynamic !== undefined)
135
+ asyncOptions['dynamic'] = options.dynamic;
136
+ for (const key of Object.keys(asyncOptions)) {
137
+ if (asyncOptions[key] === undefined)
138
+ delete asyncOptions[key];
139
+ }
140
+ this._app = (await asyncServe(this.executor.raw, asyncOptions));
141
+ return this._app;
142
+ }
143
+ /** Tear down the embedded MCP app and mark the service stopped. */
144
+ async stop() {
145
+ this._isRunning = false;
146
+ if (this._app) {
147
+ await this._app.close();
148
+ this._app = null;
149
+ }
150
+ }
151
+ /** Stop, then start the standalone MCP server. */
152
+ async restart() {
153
+ await this.stop();
154
+ await this.start();
155
+ }
156
+ // -------------------------------------------------------------------------
157
+ // Tool conversion
158
+ // -------------------------------------------------------------------------
159
+ /**
160
+ * Convert the registered modules to OpenAI-compatible tool definitions,
161
+ * ready to hand to a chat-completions `tools` parameter.
162
+ */
163
+ async toOpenaiTools(options) {
164
+ const { toOpenaiTools } = await import('apcore-mcp');
165
+ return toOpenaiTools(this.executor.raw, options ?? {
166
+ tags: this.options.tags ?? undefined,
167
+ prefix: this.options.prefix ?? undefined,
168
+ });
169
+ }
170
+ // -------------------------------------------------------------------------
171
+ // Private helpers
172
+ // -------------------------------------------------------------------------
173
+ /** Collect the defined values for `keys`, applying any option renames. */
174
+ collectOptions(keys) {
175
+ const result = {};
176
+ for (const key of keys) {
177
+ const value = this.options[key];
178
+ if (value !== undefined)
179
+ result[key] = value;
180
+ }
181
+ for (const [from, to] of Object.entries(RENAMED_OPTIONS)) {
182
+ const value = this.options[from];
183
+ if (value !== undefined)
184
+ result[to] = value;
185
+ }
186
+ return result;
187
+ }
188
+ }
189
+ //# sourceMappingURL=apcore-mcp.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apcore-mcp.service.js","sourceRoot":"","sources":["../../src/mcp/apcore-mcp.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { ApcoreMcpService } from './apcore-mcp.service.js';
2
+ export type { McpApp } from './apcore-mcp.service.js';
3
+ export { mountMcp, toHonoHandler, RESPONSE_ALREADY_SENT } from './mount.js';
4
+ export type { MountableApp } from './mount.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ApcoreMcpService } from './apcore-mcp.service.js';
2
+ export { mountMcp, toHonoHandler, RESPONSE_ALREADY_SENT } from './mount.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { ApcoreMcpService, McpApp } from './apcore-mcp.service.js';
2
+ import type { MountMcpOptions } from '../types.js';
3
+ /** The subset of a Hono app used for mounting. */
4
+ export interface MountableApp {
5
+ all: (path: string, handler: (c: unknown) => Promise<Response> | Response) => unknown;
6
+ }
7
+ /**
8
+ * The sentinel `@hono/node-server` recognises as "the handler already wrote
9
+ * this response itself".
10
+ *
11
+ * Constructed here rather than imported from
12
+ * `@hono/node-server/utils/response` so mounting never makes the Node adapter
13
+ * a hard dependency; the header name is the contract.
14
+ */
15
+ export declare const RESPONSE_ALREADY_SENT: Response;
16
+ /**
17
+ * Wrap `apcore-mcp`'s Node request handler as a Hono handler.
18
+ *
19
+ * The MCP transport speaks Streamable HTTP with SSE, which needs direct
20
+ * control of the response stream — so the handler writes to the Node
21
+ * `ServerResponse` and returns the already-sent sentinel instead of a
22
+ * `Response` Hono would try to serialise itself.
23
+ */
24
+ export declare function toHonoHandler(mcpApp: McpApp): (c: unknown) => Promise<Response>;
25
+ /**
26
+ * Mount the MCP endpoint — and, when enabled, the Tool Explorer UI and the
27
+ * `/health`, `/metrics`, `/usage` routes — into an existing Hono app.
28
+ *
29
+ * One process, one port: the app keeps serving its own routes while AI
30
+ * clients talk MCP at `endpoint`.
31
+ *
32
+ * **Node runtime only.** The MCP transport needs the raw Node request and
33
+ * response objects that `@hono/node-server` exposes on `c.env`. On other
34
+ * runtimes, run the server standalone with {@link ApcoreMcpService.start}.
35
+ *
36
+ * `endpoint` must be the path as the HTTP server sees it — if the Hono app
37
+ * itself sits under a `basePath`, include that prefix here.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { serve } from '@hono/node-server';
42
+ *
43
+ * await apcore.init();
44
+ * await mountMcp(app, apcore.mcp!, { endpoint: '/mcp', explorer: true });
45
+ * serve({ fetch: app.fetch, port: 3000 });
46
+ * ```
47
+ *
48
+ * @returns The embedded MCP app; call `close()` on shutdown.
49
+ */
50
+ export declare function mountMcp(app: MountableApp, service: ApcoreMcpService, options?: MountMcpOptions): Promise<McpApp>;
51
+ //# sourceMappingURL=mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/mcp/mount.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,KAAK,OAAO,CAAC;CACvF;AAWD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAElC,CAAC;AAcH;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAa/E;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
@@ -0,0 +1,95 @@
1
+ import { DEFAULT_EXPLORER_PREFIX, DEFAULT_MCP_ENDPOINT, HONO_ALREADY_SENT_HEADER } from '../constants.js';
2
+ /**
3
+ * The sentinel `@hono/node-server` recognises as "the handler already wrote
4
+ * this response itself".
5
+ *
6
+ * Constructed here rather than imported from
7
+ * `@hono/node-server/utils/response` so mounting never makes the Node adapter
8
+ * a hard dependency; the header name is the contract.
9
+ */
10
+ export const RESPONSE_ALREADY_SENT = new Response(null, {
11
+ headers: { [HONO_ALREADY_SENT_HEADER]: 'true' },
12
+ });
13
+ const NODE_ONLY_MESSAGE = 'mountMcp() needs the Node bindings from @hono/node-server (c.env.incoming / c.env.outgoing). ' +
14
+ 'On Workers, Deno, or Bun, run the MCP server standalone with ApcoreMcpService.start() instead.';
15
+ function nodeBindings(c) {
16
+ const env = c?.env;
17
+ if (env === null || typeof env !== 'object')
18
+ return null;
19
+ const { incoming, outgoing } = env;
20
+ if (!incoming || !outgoing)
21
+ return null;
22
+ return { incoming, outgoing };
23
+ }
24
+ /**
25
+ * Wrap `apcore-mcp`'s Node request handler as a Hono handler.
26
+ *
27
+ * The MCP transport speaks Streamable HTTP with SSE, which needs direct
28
+ * control of the response stream — so the handler writes to the Node
29
+ * `ServerResponse` and returns the already-sent sentinel instead of a
30
+ * `Response` Hono would try to serialise itself.
31
+ */
32
+ export function toHonoHandler(mcpApp) {
33
+ return async (c) => {
34
+ const bindings = nodeBindings(c);
35
+ if (!bindings) {
36
+ return new Response(NODE_ONLY_MESSAGE, {
37
+ status: 501,
38
+ headers: { 'content-type': 'text/plain; charset=utf-8' },
39
+ });
40
+ }
41
+ await mcpApp.handler(bindings.incoming, bindings.outgoing);
42
+ return RESPONSE_ALREADY_SENT;
43
+ };
44
+ }
45
+ /**
46
+ * Mount the MCP endpoint — and, when enabled, the Tool Explorer UI and the
47
+ * `/health`, `/metrics`, `/usage` routes — into an existing Hono app.
48
+ *
49
+ * One process, one port: the app keeps serving its own routes while AI
50
+ * clients talk MCP at `endpoint`.
51
+ *
52
+ * **Node runtime only.** The MCP transport needs the raw Node request and
53
+ * response objects that `@hono/node-server` exposes on `c.env`. On other
54
+ * runtimes, run the server standalone with {@link ApcoreMcpService.start}.
55
+ *
56
+ * `endpoint` must be the path as the HTTP server sees it — if the Hono app
57
+ * itself sits under a `basePath`, include that prefix here.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * import { serve } from '@hono/node-server';
62
+ *
63
+ * await apcore.init();
64
+ * await mountMcp(app, apcore.mcp!, { endpoint: '/mcp', explorer: true });
65
+ * serve({ fetch: app.fetch, port: 3000 });
66
+ * ```
67
+ *
68
+ * @returns The embedded MCP app; call `close()` on shutdown.
69
+ */
70
+ export async function mountMcp(app, service, options = {}) {
71
+ const endpoint = options.endpoint ?? DEFAULT_MCP_ENDPOINT;
72
+ const explorerPrefix = options.explorerPrefix ?? DEFAULT_EXPLORER_PREFIX;
73
+ const builtinRoutes = options.builtinRoutes ?? true;
74
+ const mcpApp = await service.asyncServe({
75
+ endpoint,
76
+ explorer: options.explorer,
77
+ explorerPrefix,
78
+ allowExecute: options.allowExecute,
79
+ });
80
+ const handler = toHonoHandler(mcpApp);
81
+ app.all(endpoint, handler);
82
+ if (options.explorer) {
83
+ app.all(explorerPrefix, handler);
84
+ app.all(`${explorerPrefix}/*`, handler);
85
+ }
86
+ if (builtinRoutes) {
87
+ // Served by the MCP transport itself: /health and /metrics before auth,
88
+ // /usage after it.
89
+ for (const path of ['/health', '/metrics', '/usage']) {
90
+ app.all(path, handler);
91
+ }
92
+ }
93
+ return mcpApp;
94
+ }
95
+ //# sourceMappingURL=mount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/mcp/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAkB1G;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAa,IAAI,QAAQ,CAAC,IAAI,EAAE;IAChE,OAAO,EAAE,EAAE,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE;CAChD,CAAC,CAAC;AAEH,MAAM,iBAAiB,GACrB,+FAA+F;IAC/F,gGAAgG,CAAC;AAEnG,SAAS,YAAY,CAAC,CAAU;IAC9B,MAAM,GAAG,GAAI,CAA8B,EAAE,GAAG,CAAC;IACjD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAA4B,CAAC;IAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,KAAK,EAAE,CAAU,EAAqB,EAAE;QAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,QAAQ,CAAC,iBAAiB,EAAE;gBACrC,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE;aACzD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,qBAAqB,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAiB,EACjB,OAAyB,EACzB,UAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,oBAAoB,CAAC;IAC1D,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAC;IACzE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACtC,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc;QACd,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE3B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACjC,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,wEAAwE;QACxE,mBAAmB;QACnB,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { modulesToBindings, renderBindingsYaml, writeBindingsFile } from './yaml-writer.js';
2
+ export type { BindingRecord } from './yaml-writer.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/output/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC5F,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { modulesToBindings, renderBindingsYaml, writeBindingsFile } from './yaml-writer.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/output/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { ScannedModule } from 'apcore-toolkit';
2
+ /** One entry of the `bindings:` list in a bindings YAML file. */
3
+ export interface BindingRecord {
4
+ module_id: string;
5
+ target: string;
6
+ description: string;
7
+ input_schema?: Record<string, unknown>;
8
+ output_schema?: Record<string, unknown>;
9
+ tags?: string[];
10
+ annotations?: Record<string, unknown>;
11
+ documentation?: string;
12
+ }
13
+ /**
14
+ * Serialise scanned modules into the `bindings:` shape that
15
+ * {@link ApBindingLoader} reads back.
16
+ *
17
+ * Keys are snake_case, matching the wire format shared by every apcore SDK.
18
+ */
19
+ export declare function modulesToBindings(modules: ScannedModule[]): BindingRecord[];
20
+ /** Render scanned modules as the text of a bindings YAML file. */
21
+ export declare function renderBindingsYaml(modules: ScannedModule[]): string;
22
+ /**
23
+ * Write scanned modules to a single bindings YAML file, creating parent
24
+ * directories as needed.
25
+ *
26
+ * @param modules - Modules to serialise.
27
+ * @param filePath - Destination path, e.g. `./bindings.yaml`.
28
+ * @returns The path that was written.
29
+ */
30
+ export declare function writeBindingsFile(modules: ScannedModule[], filePath: string): Promise<string>;
31
+ //# sourceMappingURL=yaml-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-writer.d.ts","sourceRoot":"","sources":["../../src/output/yaml-writer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAkB3E;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,CAKnE;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,EAAE,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAIjB"}
@@ -0,0 +1,49 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import * as yaml from 'js-yaml';
4
+ import { annotationsToDict } from 'apcore-toolkit';
5
+ /**
6
+ * Serialise scanned modules into the `bindings:` shape that
7
+ * {@link ApBindingLoader} reads back.
8
+ *
9
+ * Keys are snake_case, matching the wire format shared by every apcore SDK.
10
+ */
11
+ export function modulesToBindings(modules) {
12
+ return modules.map((module) => {
13
+ const record = {
14
+ module_id: module.moduleId,
15
+ target: module.target,
16
+ description: module.description,
17
+ input_schema: { ...module.inputSchema },
18
+ output_schema: { ...module.outputSchema },
19
+ };
20
+ if (module.tags.length > 0)
21
+ record.tags = [...module.tags];
22
+ if (module.annotations) {
23
+ record.annotations = annotationsToDict(module.annotations);
24
+ }
25
+ if (module.documentation)
26
+ record.documentation = module.documentation;
27
+ return record;
28
+ });
29
+ }
30
+ /** Render scanned modules as the text of a bindings YAML file. */
31
+ export function renderBindingsYaml(modules) {
32
+ const header = '# Generated by hono-apcore. Load with HonoApcore.loadBindings() or\n' +
33
+ '# `hono-apcore serve --bindings <file>`.\n';
34
+ return header + yaml.dump({ bindings: modulesToBindings(modules) }, { noRefs: true, lineWidth: 100 });
35
+ }
36
+ /**
37
+ * Write scanned modules to a single bindings YAML file, creating parent
38
+ * directories as needed.
39
+ *
40
+ * @param modules - Modules to serialise.
41
+ * @param filePath - Destination path, e.g. `./bindings.yaml`.
42
+ * @returns The path that was written.
43
+ */
44
+ export async function writeBindingsFile(modules, filePath) {
45
+ await mkdir(dirname(filePath), { recursive: true });
46
+ await writeFile(filePath, renderBindingsYaml(modules), 'utf-8');
47
+ return filePath;
48
+ }
49
+ //# sourceMappingURL=yaml-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-writer.js","sourceRoot":"","sources":["../../src/output/yaml-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAenD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAkB;YAC5B,SAAS,EAAE,MAAM,CAAC,QAAQ;YAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,YAAY,EAAE,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE;YACvC,aAAa,EAAE,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE;SAC1C,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,CAAC,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAA4B,CAAC;QACxF,CAAC;QACD,IAAI,MAAM,CAAC,aAAa;YAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;QAEtE,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,OAAwB;IACzD,MAAM,MAAM,GACV,sEAAsE;QACtE,4CAA4C,CAAC;IAC/C,OAAO,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;AACxG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAwB,EACxB,QAAgB;IAEhB,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { BaseScanner } from 'apcore-toolkit';
2
+ import type { ScannedModule } from 'apcore-toolkit';
3
+ import type { BoundExecuteFn } from '../utils/module-factory.js';
4
+ import type { RouteScanOptions } from '../types.js';
5
+ /**
6
+ * The slice of Hono's app surface the scanner needs.
7
+ *
8
+ * Typed structurally so the scanner works with any `Hono<Env>` instantiation
9
+ * without dragging Hono's generics through this package's public API.
10
+ */
11
+ export interface HonoAppLike {
12
+ routes: Array<{
13
+ path: string;
14
+ method: string;
15
+ handler: unknown;
16
+ }>;
17
+ /**
18
+ * Hono's own `request()` takes two further optional arguments (`Env` and
19
+ * `ExecutionContext`); they are omitted here so any `Hono<Env>` remains
20
+ * structurally assignable regardless of its bindings.
21
+ */
22
+ request: (input: Request | string | URL, init?: RequestInit) => Response | Promise<Response>;
23
+ }
24
+ /**
25
+ * Scans a Hono app's route table and turns each route into an apcore module.
26
+ *
27
+ * Registered modules replay the route in-process through `app.request()`, so
28
+ * middleware, validators, and error handlers all run exactly as they do for a
29
+ * real HTTP request — no duplicated business logic, no second code path.
30
+ *
31
+ * Behavioural annotations are inferred from the HTTP method per RFC 9110
32
+ * safe-method semantics (`GET` → readonly + cacheable, `DELETE` →
33
+ * destructive, `PUT` → idempotent).
34
+ */
35
+ export declare class HonoRouteScanner extends BaseScanner {
36
+ getSourceName(): string;
37
+ /**
38
+ * Scan the app's routes into toolkit `ScannedModule` intermediates.
39
+ *
40
+ * Use {@link scanWithExecutors} when you also need the bound execute
41
+ * functions — `scan()` returns serialisable metadata only, which is what
42
+ * the `scan` CLI command and YAML binding export want.
43
+ */
44
+ scan(app: HonoAppLike, options?: RouteScanOptions): ScannedModule[];
45
+ /**
46
+ * Scan the app's routes, returning each module together with the execute
47
+ * function that replays it through `app.request()`.
48
+ */
49
+ scanWithExecutors(app: HonoAppLike, options?: RouteScanOptions): Array<{
50
+ module: ScannedModule;
51
+ execute: BoundExecuteFn;
52
+ }>;
53
+ private buildEntry;
54
+ }
55
+ /**
56
+ * Substitute path parameters and append the query string, producing the URL
57
+ * handed to `app.request()`.
58
+ */
59
+ export declare function buildRequestUrl(path: string, method: string, inputs: Record<string, unknown>, baseUrl: string): string;
60
+ //# sourceMappingURL=hono-route-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono-route-scanner.d.ts","sourceRoot":"","sources":["../../src/scanners/hono-route-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EAKZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClE;;;;OAIG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC9F;AAgGD;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,aAAa,IAAI,MAAM;IAIvB;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,gBAAqB,GAAG,aAAa,EAAE;IAIvE;;;OAGG;IACH,iBAAiB,CACf,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,gBAAqB,GAC7B,KAAK,CAAC;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE,CAAC;IA+D5D,OAAO,CAAC,UAAU;CAkDnB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,MAAM,GACd,MAAM,CAgBR"}