@lunora/mcp 1.0.0-alpha.7 → 1.0.0-alpha.71
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.
- package/LICENSE.md +126 -0
- package/README.md +139 -9
- package/dist/bin.mjs +3 -35
- package/dist/docs/index.d.mts +250 -0
- package/dist/docs/index.d.ts +250 -0
- package/dist/docs/index.mjs +1 -0
- package/dist/index.d.mts +355 -14
- package/dist/index.d.ts +355 -14
- package/dist/index.mjs +1 -2
- package/dist/packem_shared/AGENT_RUN_INPUT_SCHEMA-DRSY74ed.mjs +1 -0
- package/dist/packem_shared/DEFAULT_DOCS_BASE_URL-CZ3fVsSc.mjs +4 -0
- package/dist/packem_shared/DEFAULT_SEARCH_LIMIT-DWPt0hvR.mjs +3 -0
- package/dist/packem_shared/DOCS_SERVER_NAME-BWzPxJyZ.mjs +1 -0
- package/dist/packem_shared/DOCS_URI_SCHEME-CFANc3vr.mjs +3 -0
- package/dist/packem_shared/LOCAL_SERVER_NAME-0Jb4neqA.mjs +1 -0
- package/dist/packem_shared/OBSERVABILITY_TOOL_DEFINITIONS-KrCukPbu.mjs +1 -0
- package/dist/packem_shared/READ_ONLY_TOOL_DEFINITIONS-DGexf3Tn.mjs +1 -0
- package/dist/packem_shared/connectStdio-BCeI0Wqu.mjs +1 -0
- package/dist/packem_shared/createMcpFetchHandler-TKDnZTGs.mjs +1 -0
- package/dist/packem_shared/createPaidMcpServer-CQO-59WV.mjs +1 -0
- package/dist/packem_shared/createToolServer-BtGuPyMU.mjs +1 -0
- package/dist/packem_shared/observability-tools-Ce0YK58T.mjs +1 -0
- package/dist/packem_shared/serve-stateless.d-B_q8q39X.d.mts +133 -0
- package/dist/packem_shared/serve-stateless.d-B_q8q39X.d.ts +133 -0
- package/dist/packem_shared/serveStateless-Db7J3pAO.mjs +1 -0
- package/dist/packem_shared/toDocsSearchHits-CBLmtWXt.mjs +1 -0
- package/package.json +17 -3
- package/dist/packem_shared/TOOL_DEFINITIONS-Dpiu38ji.mjs +0 -112
- package/dist/packem_shared/connectStdio-C_mvQBs2.mjs +0 -64
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { M as McpResourceProvider, a as McpFetchHandler, T as ToolDefinition, b as McpTool } from "../packem_shared/serve-stateless.d-B_q8q39X.js";
|
|
2
|
+
export type {
|
|
3
|
+
/**
|
|
4
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
5
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
6
|
+
*
|
|
7
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
8
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
9
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
10
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
11
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
12
|
+
* unauthenticated.
|
|
13
|
+
*
|
|
14
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
15
|
+
* its own in-process search index, while anything else (the CLI's
|
|
16
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
17
|
+
* published site over HTTP.
|
|
18
|
+
*
|
|
19
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
20
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
21
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
22
|
+
*
|
|
23
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
24
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
25
|
+
* both entries gets one implementation rather than two copies.
|
|
26
|
+
*/
|
|
27
|
+
c as McpResourceSummary,
|
|
28
|
+
/**
|
|
29
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
30
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
31
|
+
*
|
|
32
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
33
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
34
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
35
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
36
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
37
|
+
* unauthenticated.
|
|
38
|
+
*
|
|
39
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
40
|
+
* its own in-process search index, while anything else (the CLI's
|
|
41
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
42
|
+
* published site over HTTP.
|
|
43
|
+
*
|
|
44
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
45
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
46
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
47
|
+
*
|
|
48
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
49
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
50
|
+
* both entries gets one implementation rather than two copies.
|
|
51
|
+
*/
|
|
52
|
+
d as McpServerInfo, e as ToolInputSchema, f as ToolResult } from "../packem_shared/serve-stateless.d-B_q8q39X.js";
|
|
53
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
54
|
+
import '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
55
|
+
/**
|
|
56
|
+
* The documentation source the docs tools read.
|
|
57
|
+
*
|
|
58
|
+
* The tools are written against this interface rather than against a concrete
|
|
59
|
+
* search engine so the same tool surface can be backed two ways: in-process by
|
|
60
|
+
* the docs site itself (fumadocs `source` + its Orama index), or over HTTP by a
|
|
61
|
+
* remote reader that only has the published site (see `./remote-index`). Both
|
|
62
|
+
* expose the identical tool names and result shapes to the model.
|
|
63
|
+
*/
|
|
64
|
+
/** One hit from {@link DocsIndex.search}. */
|
|
65
|
+
interface DocsSearchHit {
|
|
66
|
+
/** The matched text, when the backend returns one (headings/paragraph hits). */
|
|
67
|
+
excerpt?: string;
|
|
68
|
+
/** Breadcrumb trail to the matched section, e.g. `"Guides › Sharding"`. */
|
|
69
|
+
section?: string;
|
|
70
|
+
/** Page title. */
|
|
71
|
+
title: string;
|
|
72
|
+
/** Site-relative page URL, e.g. `"/docs/sharding"` — feed this to `lunora_get_doc`. */
|
|
73
|
+
url: string;
|
|
74
|
+
}
|
|
75
|
+
/** A page listed by {@link DocsIndex.listPages}. */
|
|
76
|
+
interface DocsPageSummary {
|
|
77
|
+
description?: string;
|
|
78
|
+
title: string;
|
|
79
|
+
/** Site-relative page URL, e.g. `"/docs/sharding"`. */
|
|
80
|
+
url: string;
|
|
81
|
+
}
|
|
82
|
+
/** A page's full text, as returned by {@link DocsIndex.getPage}. */
|
|
83
|
+
interface DocsPage extends DocsPageSummary {
|
|
84
|
+
/** The page body as Markdown. */
|
|
85
|
+
content: string;
|
|
86
|
+
}
|
|
87
|
+
interface DocsIndex {
|
|
88
|
+
/**
|
|
89
|
+
* The page at a site-relative URL, or `undefined` when there is no such
|
|
90
|
+
* page. Implementations should accept the URL exactly as it appears in a
|
|
91
|
+
* search hit.
|
|
92
|
+
*/
|
|
93
|
+
getPage: (url: string) => Promise<DocsPage | undefined>;
|
|
94
|
+
/** Every indexed page, for a model that wants to browse rather than search. */
|
|
95
|
+
listPages: () => Promise<ReadonlyArray<DocsPageSummary>>;
|
|
96
|
+
/**
|
|
97
|
+
* Full-text search, returning whatever the backend found.
|
|
98
|
+
*
|
|
99
|
+
* Deliberately unbounded: the tool layer decides how many hits reach the
|
|
100
|
+
* model's context, so there is one truncation site rather than one per
|
|
101
|
+
* backend plus one in the tool.
|
|
102
|
+
*/
|
|
103
|
+
search: (query: string) => Promise<ReadonlyArray<DocsSearchHit>>;
|
|
104
|
+
}
|
|
105
|
+
/** The subset of a fumadocs `SortedResult` these tools consume. */
|
|
106
|
+
interface FumadocsSearchResult {
|
|
107
|
+
breadcrumbs?: string[];
|
|
108
|
+
content?: string;
|
|
109
|
+
type?: string;
|
|
110
|
+
url?: string;
|
|
111
|
+
}
|
|
112
|
+
/** Map every result, skipping any entry {@link toDocsSearchHit} rejects. */
|
|
113
|
+
declare const toDocsSearchHits: (results: ReadonlyArray<unknown>) => DocsSearchHit[];
|
|
114
|
+
/** The public docs site the remote index reads when no base URL is configured. */
|
|
115
|
+
declare const DEFAULT_DOCS_BASE_URL = "https://lunora.sh";
|
|
116
|
+
interface RemoteDocsIndexOptions {
|
|
117
|
+
/** Origin of the docs site, e.g. `"https://lunora.sh"`. Defaults to {@link DEFAULT_DOCS_BASE_URL}. */
|
|
118
|
+
baseUrl?: string;
|
|
119
|
+
/** `fetch` implementation; defaults to the ambient global. */
|
|
120
|
+
fetch?: typeof fetch;
|
|
121
|
+
/** Per-request deadline in ms. Defaults to {@link DEFAULT_REQUEST_TIMEOUT_MS}. */
|
|
122
|
+
timeoutMs?: number;
|
|
123
|
+
}
|
|
124
|
+
declare const createRemoteDocsIndex: (options?: RemoteDocsIndexOptions) => DocsIndex;
|
|
125
|
+
/** URI scheme identifying a Lunora documentation page. */
|
|
126
|
+
declare const DOCS_URI_SCHEME = "lunora-docs:";
|
|
127
|
+
/** `"/docs/sharding"` → `"lunora-docs:/docs/sharding"`. */
|
|
128
|
+
declare const toDocsUri: (url: string) => string;
|
|
129
|
+
/** The inverse, or `undefined` for a uri this provider does not own. */
|
|
130
|
+
declare const fromDocsUri: (uri: string) => string | undefined;
|
|
131
|
+
/** Expose `index`'s pages as listable, readable resources. */
|
|
132
|
+
declare const docsResources: (index: DocsIndex) => McpResourceProvider;
|
|
133
|
+
/** Server identity advertised in the MCP `initialize` handshake. */
|
|
134
|
+
declare const DOCS_SERVER_NAME = "lunora-docs";
|
|
135
|
+
interface DocsMcpServerOptions {
|
|
136
|
+
/** The documentation source the tools read. */
|
|
137
|
+
index: DocsIndex;
|
|
138
|
+
/** Largest accepted request body. Defaults to {@link DEFAULT_MAX_REQUEST_BYTES}. */
|
|
139
|
+
maxRequestBytes?: number;
|
|
140
|
+
/**
|
|
141
|
+
* Version reported in the handshake. Defaults to `"0.0.0"` — a docs site
|
|
142
|
+
* bundles this code rather than installing it, so it, not the package, is
|
|
143
|
+
* the thing whose version a client would want to see.
|
|
144
|
+
*/
|
|
145
|
+
version?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a transport-agnostic MCP server exposing the documentation tools.
|
|
149
|
+
* Connect it yourself, or use {@link createDocsMcpFetchHandler} for the remote
|
|
150
|
+
* HTTP case.
|
|
151
|
+
*/
|
|
152
|
+
declare const createDocsMcpServer: (options: DocsMcpServerOptions) => Server;
|
|
153
|
+
/**
|
|
154
|
+
* Build a stateless Streamable-HTTP fetch handler serving the documentation
|
|
155
|
+
* tools — the `Request` → `Response` function a docs site mounts at `/mcp`.
|
|
156
|
+
*
|
|
157
|
+
* A fresh server per request keeps the handler safe on platforms that fan
|
|
158
|
+
* requests across isolates, where nothing may be assumed to persist between
|
|
159
|
+
* them.
|
|
160
|
+
*/
|
|
161
|
+
declare const createDocsMcpFetchHandler: (options: DocsMcpServerOptions) => McpFetchHandler;
|
|
162
|
+
/** Hits returned when the caller doesn't ask for a specific number. */
|
|
163
|
+
declare const DEFAULT_SEARCH_LIMIT = 10;
|
|
164
|
+
/**
|
|
165
|
+
* Ceiling on hits per call. Search results are pasted into the model's context
|
|
166
|
+
* verbatim, so an unbounded `limit` is a context-exhaustion foot-gun rather
|
|
167
|
+
* than a useful option.
|
|
168
|
+
*/
|
|
169
|
+
declare const MAX_SEARCH_LIMIT = 50;
|
|
170
|
+
/** The advertised surface, in the order a caller should reach for it. */
|
|
171
|
+
declare const DOCS_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
|
|
172
|
+
/**
|
|
173
|
+
* Normalize whatever a model passes as a page URL into the site-relative form
|
|
174
|
+
* an index stores.
|
|
175
|
+
*
|
|
176
|
+
* Models copy URLs from anywhere — a search hit (`/docs/sharding`), the browser
|
|
177
|
+
* (`https://lunora.sh/docs/sharding`), or their own memory of the slug
|
|
178
|
+
* (`sharding`, `docs/sharding`). All four are the same page, and failing three
|
|
179
|
+
* of them would push the model into a guess-and-retry loop, so resolve them to
|
|
180
|
+
* one form. A trailing slash is dropped for the same reason.
|
|
181
|
+
*
|
|
182
|
+
* A `..` segment is REJECTED rather than resolved. The remote backend appends
|
|
183
|
+
* this path to `/llms.mdx`, so `../../api/search` would walk back out of the
|
|
184
|
+
* documentation tree and pull an unrelated path on the docs origin into the
|
|
185
|
+
* model's context — harmless against a public site, less so against the
|
|
186
|
+
* internal host a self-hosted `--docs-url` may point at.
|
|
187
|
+
*/
|
|
188
|
+
declare const normalizeDocUrl: (raw: string) => string;
|
|
189
|
+
/**
|
|
190
|
+
* The documentation surface, bound to `index`.
|
|
191
|
+
*
|
|
192
|
+
* Each tool carries its own handler rather than routing through a shared
|
|
193
|
+
* `switch`: `createToolServer` already dispatches by name, so a second switch
|
|
194
|
+
* here would be a duplicate table with an unreachable `default`. It also owns
|
|
195
|
+
* the throw-to-`isError` conversion, so these handlers signal argument problems
|
|
196
|
+
* by throwing and return `isError` only for the expected misses a model should
|
|
197
|
+
* read and act on.
|
|
198
|
+
*/
|
|
199
|
+
declare const docsTools: (index: DocsIndex) => ReadonlyArray<McpTool>;
|
|
200
|
+
export { DEFAULT_DOCS_BASE_URL, DEFAULT_SEARCH_LIMIT, DOCS_SERVER_NAME, DOCS_TOOL_DEFINITIONS, DOCS_URI_SCHEME, type DocsIndex, type DocsMcpServerOptions, type DocsPage, type DocsPageSummary, type DocsSearchHit, type FumadocsSearchResult, MAX_SEARCH_LIMIT, type McpFetchHandler,
|
|
201
|
+
/**
|
|
202
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
203
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
204
|
+
*
|
|
205
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
206
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
207
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
208
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
209
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
210
|
+
* unauthenticated.
|
|
211
|
+
*
|
|
212
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
213
|
+
* its own in-process search index, while anything else (the CLI's
|
|
214
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
215
|
+
* published site over HTTP.
|
|
216
|
+
*
|
|
217
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
218
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
219
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
220
|
+
*
|
|
221
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
222
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
223
|
+
* both entries gets one implementation rather than two copies.
|
|
224
|
+
*/
|
|
225
|
+
type McpResourceProvider,
|
|
226
|
+
/**
|
|
227
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
228
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
229
|
+
*
|
|
230
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
231
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
232
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
233
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
234
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
235
|
+
* unauthenticated.
|
|
236
|
+
*
|
|
237
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
238
|
+
* its own in-process search index, while anything else (the CLI's
|
|
239
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
240
|
+
* published site over HTTP.
|
|
241
|
+
*
|
|
242
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
243
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
244
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
245
|
+
*
|
|
246
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
247
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
248
|
+
* both entries gets one implementation rather than two copies.
|
|
249
|
+
*/
|
|
250
|
+
type McpTool, type RemoteDocsIndexOptions, type ToolDefinition, createDocsMcpFetchHandler, createDocsMcpServer, createRemoteDocsIndex, docsResources, docsTools, fromDocsUri, normalizeDocUrl, toDocsSearchHits, toDocsUri };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{toDocsSearchHits as e}from"../packem_shared/toDocsSearchHits-CBLmtWXt.mjs";import{DEFAULT_DOCS_BASE_URL as D,createRemoteDocsIndex as t}from"../packem_shared/DEFAULT_DOCS_BASE_URL-CZ3fVsSc.mjs";import{DOCS_URI_SCHEME as s,docsResources as S,fromDocsUri as E,toDocsUri as I}from"../packem_shared/DOCS_URI_SCHEME-CFANc3vr.mjs";import{DOCS_SERVER_NAME as R,createDocsMcpFetchHandler as p,createDocsMcpServer as A}from"../packem_shared/DOCS_SERVER_NAME-BWzPxJyZ.mjs";import{DEFAULT_SEARCH_LIMIT as M,DOCS_TOOL_DEFINITIONS as O,MAX_SEARCH_LIMIT as T,docsTools as U,normalizeDocUrl as a}from"../packem_shared/DEFAULT_SEARCH_LIMIT-DWPt0hvR.mjs";export{D as DEFAULT_DOCS_BASE_URL,M as DEFAULT_SEARCH_LIMIT,R as DOCS_SERVER_NAME,O as DOCS_TOOL_DEFINITIONS,s as DOCS_URI_SCHEME,T as MAX_SEARCH_LIMIT,p as createDocsMcpFetchHandler,A as createDocsMcpServer,t as createRemoteDocsIndex,S as docsResources,U as docsTools,E as fromDocsUri,a as normalizeDocUrl,e as toDocsSearchHits,I as toDocsUri};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,30 +1,371 @@
|
|
|
1
1
|
import { LunoraClient } from '@lunora/client';
|
|
2
|
+
import { T as ToolDefinition, f as ToolResult, e as ToolInputSchema, a as McpFetchHandler, b as McpTool } from "./packem_shared/serve-stateless.d-B_q8q39X.mjs";
|
|
3
|
+
export { type d as McpServerInfo, g as createToolServer, s as serveStateless } from "./packem_shared/serve-stateless.d-B_q8q39X.mjs";
|
|
2
4
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
7
|
+
/**
|
|
8
|
+
* The observability tools. Descriptions say WHEN to call the tool, not just
|
|
9
|
+
* what it returns — an agent picking between five similar reads needs the
|
|
10
|
+
* trigger, and it pays for these strings on every turn.
|
|
11
|
+
*/
|
|
12
|
+
declare const OBSERVABILITY_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
|
|
13
|
+
/** The read-only tool surface: introspection + query. Always exposed. */
|
|
14
|
+
declare const READ_ONLY_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
|
|
15
|
+
/** The write tool surface (mutations + actions). Exposed ONLY when writes are enabled. */
|
|
16
|
+
declare const WRITE_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
|
|
17
|
+
/**
|
|
18
|
+
* The tools this server advertises, in three tiers:
|
|
19
|
+
*
|
|
20
|
+
* - the read-only surface, always exposed;
|
|
21
|
+
* - the observability surface, exposed only when an admin token resolved —
|
|
22
|
+
* read-only, but it surfaces production logs and grouped errors, so an
|
|
23
|
+
* unauthenticated server must not even advertise that it exists;
|
|
24
|
+
* - the write surface, exposed only when `allowWrites` is set.
|
|
25
|
+
*
|
|
26
|
+
* Both gates OMIT rather than refuse: an AI agent can't invoke what it can't
|
|
27
|
+
* see. Dispatch re-checks both in {@link callTool}, so the guarantee does not
|
|
28
|
+
* depend on a client honouring the advertised list.
|
|
29
|
+
*/
|
|
30
|
+
declare const toolDefinitions: (allowWrites: boolean, hasAdminToken?: boolean) => ReadonlyArray<ToolDefinition>;
|
|
31
|
+
/**
|
|
32
|
+
* Dispatch a tool call against `client`. Unknown tools and thrown errors are
|
|
33
|
+
* returned as `isError` results (rather than rejections) so the calling model
|
|
34
|
+
* sees the failure as tool output, per the MCP convention.
|
|
35
|
+
*
|
|
36
|
+
* `allowWrites` gates the mutation/action tools and `hasAdminToken` gates the
|
|
37
|
+
* observability tools: when either is false a call to the gated tool is refused
|
|
38
|
+
* even if the client somehow names it, so both guarantees hold at dispatch, not
|
|
39
|
+
* just in the advertised tool list.
|
|
40
|
+
*/
|
|
41
|
+
declare const callTool: (client: LunoraClient, name: string, input: Record<string, unknown>, allowWrites?: boolean, hasAdminToken?: boolean) => Promise<ToolResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Agent exposure for the MCP server: a durable `@lunora/agent` run fronted as an
|
|
44
|
+
* MCP tool an external agent can call. The capability boundary is the MCP-server
|
|
45
|
+
* process + its token, so WHICH agents are exposed is config on the server (like
|
|
46
|
+
* `allowWrites`), not on `defineAgent` — keeping `@lunora/agent` codegen
|
|
47
|
+
* byte-identical.
|
|
48
|
+
*/
|
|
49
|
+
interface McpAgentExposure {
|
|
50
|
+
/** What the agent does — shown to the calling model, which decides from it. */
|
|
51
|
+
description: string;
|
|
52
|
+
/** The agent's export name (its `ctx.agents.<name>` / `AGENT_<NAME>` binding). */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Override the model-facing tool name (default `agent_<name>`). */
|
|
55
|
+
toolName?: string;
|
|
56
|
+
}
|
|
57
|
+
/** The generic status/poll tool advertised alongside the per-agent tools. */
|
|
58
|
+
declare const AGENT_STATUS_TOOL_NAME = "lunora_agent_status";
|
|
59
|
+
/**
|
|
60
|
+
* The uniform input schema every agent tool advertises. Agents share ONE run
|
|
61
|
+
* input (`@lunora/agent` has no per-agent validator), so there is nothing to
|
|
62
|
+
* derive per agent — a single static schema is reused for every agent tool.
|
|
63
|
+
*/
|
|
64
|
+
declare const AGENT_RUN_INPUT_SCHEMA: ToolInputSchema;
|
|
65
|
+
/**
|
|
66
|
+
* Parse `LUNORA_MCP_AGENTS` — a `;`-separated list of `name:description` pairs,
|
|
67
|
+
* e.g. `"support:Handles support questions;billing:Billing help"`. The
|
|
68
|
+
* description may itself contain colons (only the FIRST colon splits). Blank
|
|
69
|
+
* entries and entries with an empty name/description are skipped.
|
|
70
|
+
*/
|
|
71
|
+
declare const parseAgentsEnv: (raw: string | undefined) => McpAgentExposure[];
|
|
72
|
+
/**
|
|
73
|
+
* The tools this module advertises. Fail-closed: only the boolean `true` opts
|
|
74
|
+
* in (an env-plumbed caller could pass a truthy string), and the tools appear
|
|
75
|
+
* ONLY when at least one agent is exposed — so an agent-free or non-opted-in
|
|
76
|
+
* server never lists them.
|
|
77
|
+
*/
|
|
78
|
+
declare const agentToolDefinitions: (exposures: ReadonlyArray<McpAgentExposure>, allowAgents: boolean) => ReadonlyArray<ToolDefinition>;
|
|
79
|
+
/** Options threaded into a single agent tool dispatch. */
|
|
80
|
+
interface CallAgentToolOptions {
|
|
81
|
+
/** Opt-in gate — must be exactly `true` or the call is refused fail-closed. */
|
|
82
|
+
allowAgents: boolean;
|
|
83
|
+
/** The exposures advertised by this server. */
|
|
84
|
+
exposures: ReadonlyArray<McpAgentExposure>;
|
|
85
|
+
/** Wall-clock budget a single call awaits before returning a pending result. */
|
|
86
|
+
maxWaitMs?: number;
|
|
87
|
+
/** Delay between thread-status polls. */
|
|
88
|
+
pollIntervalMs?: number;
|
|
89
|
+
/** Test seam replacing the between-poll wait; production uses a real timer. */
|
|
90
|
+
wait?: (ms: number) => Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Dispatch an agent tool call: start a durable run via `agents:agentRun`, then
|
|
94
|
+
* await-with-timeout — poll `agents:agentThread` until terminal (returning the
|
|
95
|
+
* final answer from `agents:agentMessages`) or, on budget exhaustion, return a
|
|
96
|
+
* NON-error pending payload the caller resumes with `lunora_agent_status`.
|
|
97
|
+
*
|
|
98
|
+
* Fail-closed: refused at dispatch unless `allowAgents === true`, mirroring the
|
|
99
|
+
* `allowWrites` guard — starting a run is a side effect and must not ride the
|
|
100
|
+
* read-only default.
|
|
101
|
+
*/
|
|
102
|
+
declare const callAgentTool: (client: LunoraClient, name: string, input: Record<string, unknown>, options: CallAgentToolOptions) => Promise<ToolResult>;
|
|
3
103
|
interface LunoraMcpServerOptions {
|
|
104
|
+
/** Wall-clock budget a single agent tool call awaits before returning a pending result. */
|
|
105
|
+
agentMaxWaitMs?: number;
|
|
106
|
+
/** Delay between agent thread-status polls. */
|
|
107
|
+
agentPollIntervalMs?: number;
|
|
108
|
+
/** The agents this server fronts as MCP tools (see `allowAgents`). */
|
|
109
|
+
agents?: ReadonlyArray<McpAgentExposure>;
|
|
110
|
+
/**
|
|
111
|
+
* Expose the per-agent tools (`agent_<name>` + the generic
|
|
112
|
+
* `lunora_agent_status`). Defaults to `false`, mirroring `allowWrites`:
|
|
113
|
+
* starting a durable agent run is a side effect, so the agent tools are
|
|
114
|
+
* omitted from the advertised list AND refused at dispatch unless explicitly
|
|
115
|
+
* opted in. Only takes effect together with a non-empty `agents` list.
|
|
116
|
+
*/
|
|
117
|
+
allowAgents?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Expose the write tools (`lunora_run_mutation` / `lunora_run_action`).
|
|
120
|
+
* Defaults to `false`: the server is READ-ONLY unless explicitly opted in,
|
|
121
|
+
* so a prompt-injected or misaligned agent can't mutate the deployment with
|
|
122
|
+
* the configured token. When false the write tools are omitted from the
|
|
123
|
+
* advertised tool list AND refused at dispatch.
|
|
124
|
+
*/
|
|
125
|
+
allowWrites?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Pre-built client (test injection). When omitted a `LunoraClient` is
|
|
128
|
+
* created from `url`/`token`/`fetch`.
|
|
129
|
+
*/
|
|
4
130
|
client?: LunoraClient;
|
|
131
|
+
/** `fetch` implementation; defaults to the ambient global. */
|
|
5
132
|
fetch?: typeof fetch;
|
|
133
|
+
/**
|
|
134
|
+
* Bearer token sent on every RPC. This must be the deployment's **admin
|
|
135
|
+
* bearer**: the introspection/allowlist path every tool depends on
|
|
136
|
+
* (`lunora_list_functions`, `lunora_list_tables`, and the `assertRunnable`
|
|
137
|
+
* precheck that runs before every `run` tool) hits admin-gated
|
|
138
|
+
* `/_lunora/admin/*` routes, so no scoped/app token works today — it would
|
|
139
|
+
* 403 (`ADMIN_FORBIDDEN`) on the first tool call. The read-only guarantee is
|
|
140
|
+
* therefore NOT enforced by the token's scope; it is enforced in-process via
|
|
141
|
+
* `allowWrites: false` (the default), which omits the write tools from the
|
|
142
|
+
* advertised list and refuses them at dispatch.
|
|
143
|
+
*
|
|
144
|
+
* Its presence is also what gates the observability tools (logs, Issues,
|
|
145
|
+
* advisories, query insights, migration status): without a token they are
|
|
146
|
+
* omitted from `ListTools` and refused at dispatch.
|
|
147
|
+
*/
|
|
6
148
|
token?: string;
|
|
149
|
+
/** Base URL of the deployed Lunora Worker. Required unless `client` is given. */
|
|
7
150
|
url?: string;
|
|
8
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Build an MCP `Server` whose tools talk to a Lunora deployment. The server is
|
|
154
|
+
* transport-agnostic — call `.connect(transport)` yourself, or use
|
|
155
|
+
* `connectStdio` for the common stdio case.
|
|
156
|
+
*
|
|
157
|
+
* Tool calls are dispatched through `callTool`, which the deployment reaches
|
|
158
|
+
* over HTTP RPC. No WebSocket is opened (the tools never subscribe), so this is
|
|
159
|
+
* safe to run as a short-lived stdio process.
|
|
160
|
+
*/
|
|
9
161
|
declare const createLunoraMcpServer: (options: LunoraMcpServerOptions) => Server;
|
|
162
|
+
/**
|
|
163
|
+
* Build the server and connect it over stdio — the transport MCP clients use
|
|
164
|
+
* when they spawn the `lunora-mcp` binary. Resolves once the transport is
|
|
165
|
+
* connected; the process then stays alive serving requests.
|
|
166
|
+
*/
|
|
10
167
|
declare const connectStdio: (options: LunoraMcpServerOptions) => Promise<Server>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Build a stateless Streamable-HTTP fetch handler for a Lunora MCP server. Each
|
|
170
|
+
* invocation constructs a fresh proxy server and serves the request through
|
|
171
|
+
* {@link serveStateless}.
|
|
172
|
+
*/
|
|
173
|
+
declare const createMcpFetchHandler: (options: LunoraMcpServerOptions) => McpFetchHandler;
|
|
174
|
+
/** A Lunora deployment the tools dispatch against. */
|
|
175
|
+
interface LocalDeployment {
|
|
176
|
+
token?: string;
|
|
177
|
+
url: string;
|
|
15
178
|
}
|
|
16
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Where the deployment comes from: a fixed value, or a function consulted on
|
|
181
|
+
* every tool call.
|
|
182
|
+
*
|
|
183
|
+
* The resolver form exists because an editor spawns this server when the
|
|
184
|
+
* project opens — routinely *before* `lunora dev` is running, and it keeps the
|
|
185
|
+
* process alive across every restart afterwards. A URL captured once at startup
|
|
186
|
+
* would therefore be absent for the entire first session and stale after the
|
|
187
|
+
* first restart.
|
|
188
|
+
*/
|
|
189
|
+
type LocalDeploymentSource = (() => LocalDeployment | undefined) | LocalDeployment;
|
|
190
|
+
interface LocalMcpServerOptions {
|
|
191
|
+
/**
|
|
192
|
+
* Expose the deployment write tools (`lunora_run_mutation` /
|
|
193
|
+
* `lunora_run_action`). Defaults to `false` — the same fail-closed default
|
|
194
|
+
* as the remote server. Locally the blast radius is dev data rather than
|
|
195
|
+
* production, but a mutation is still a side effect an agent should be
|
|
196
|
+
* granted deliberately.
|
|
197
|
+
*/
|
|
198
|
+
allowWrites?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* The Lunora deployment (usually the running dev server) to expose. Omit to
|
|
201
|
+
* leave the deployment tools out entirely.
|
|
202
|
+
*/
|
|
203
|
+
deployment?: LocalDeploymentSource;
|
|
204
|
+
/** Docs site origin backing the documentation tools; `false` omits them. */
|
|
205
|
+
docs?: false | {
|
|
206
|
+
baseUrl?: string;
|
|
207
|
+
};
|
|
208
|
+
/** Extra tools to compose in, e.g. the CLI's local dev-server tools. */
|
|
209
|
+
extraTools?: ReadonlyArray<McpTool>;
|
|
210
|
+
/** `fetch` implementation; defaults to the ambient global. */
|
|
211
|
+
fetch?: typeof fetch;
|
|
212
|
+
/** Version reported in the MCP handshake — the host CLI's, not this package's. */
|
|
213
|
+
version?: string;
|
|
214
|
+
}
|
|
215
|
+
/** Server identity advertised in the MCP `initialize` handshake. */
|
|
216
|
+
declare const LOCAL_SERVER_NAME = "lunora";
|
|
217
|
+
/** Shown when a deployment tool is called and no dev server can be found. */
|
|
218
|
+
declare const NO_DEPLOYMENT_MESSAGE = "no Lunora dev server is running for this project — start one with `lunora dev`, then call this tool again (call lunora_dev_status to check).";
|
|
219
|
+
/**
|
|
220
|
+
* Assemble the tool list, in the order it is advertised: docs first (the
|
|
221
|
+
* surface that always works), then the caller's extras, then the deployment
|
|
222
|
+
* tools. Order also decides precedence — `createToolServer` keeps the first
|
|
223
|
+
* registration of a duplicated name.
|
|
224
|
+
*
|
|
225
|
+
* `clientFor` is the shared client cache built once by
|
|
226
|
+
* {@link createLocalMcpServer} and threaded into both the tool and resource
|
|
227
|
+
* surfaces. Exported (and called directly by tests) without going through
|
|
228
|
+
* `createLocalMcpServer`, so a caller that omits it gets a private,
|
|
229
|
+
* call-scoped cache — same shape as before this surface was shared, just
|
|
230
|
+
* without the cross-surface sharing that only matters once a resource
|
|
231
|
+
* surface exists alongside it.
|
|
232
|
+
*/
|
|
233
|
+
declare const localTools: (options: LocalMcpServerOptions, clientFor?: (deployment: LocalDeployment) => LunoraClient) => ReadonlyArray<McpTool>;
|
|
234
|
+
/** Build the composed local server without connecting a transport. */
|
|
235
|
+
declare const createLocalMcpServer: (options?: LocalMcpServerOptions) => Server;
|
|
236
|
+
/**
|
|
237
|
+
* Build the composed local server and connect it over stdio — the transport an
|
|
238
|
+
* MCP client uses when it spawns `lunora mcp serve`. Resolves once connected;
|
|
239
|
+
* the process then stays alive serving requests.
|
|
240
|
+
*/
|
|
241
|
+
declare const connectLocalStdio: (options?: LocalMcpServerOptions) => Promise<Server>;
|
|
242
|
+
/** A tool handler: receives the call's `arguments` bag, returns an MCP tool result. */
|
|
243
|
+
/**
|
|
244
|
+
* The x402 vocabulary this module needs, declared here rather than imported.
|
|
245
|
+
*
|
|
246
|
+
* The x402 package is an optional peer, and a type import from its `charge`
|
|
247
|
+
* entry puts its `.d.ts` back into this package's build graph:
|
|
248
|
+
* a consumer that never installs x402 never builds it either, so the dts bundler
|
|
249
|
+
* looks for a `dist/` that does not exist and fails. That is not hypothetical —
|
|
250
|
+
* it broke the docs site build, which runs a filtered build over the docs app and its dependency closure
|
|
251
|
+
* and therefore never builds x402.
|
|
252
|
+
*
|
|
253
|
+
* Declaring them locally is safe because this module never *inspects* a charge
|
|
254
|
+
* config; it forwards it whole to `createChargeMiddleware`. The index signature
|
|
255
|
+
* keeps a real charge config assignable as x402 grows fields.
|
|
256
|
+
*/
|
|
257
|
+
/** Mirrors x402's `X402Price` — a decimal string like `"$0.05"`, or a number. */
|
|
258
|
+
type X402Price = number | string;
|
|
259
|
+
/** Mirrors x402's charge config with the per-tool price omitted. */
|
|
260
|
+
interface X402ChargeSettings {
|
|
261
|
+
/** Network this resource settles on. */
|
|
262
|
+
readonly network: string;
|
|
263
|
+
/** Everything else x402 accepts, forwarded untouched. */
|
|
264
|
+
readonly [key: string]: unknown;
|
|
265
|
+
/** Payout wallet(s), per network family. */
|
|
266
|
+
readonly recipient: {
|
|
267
|
+
readonly evm?: string;
|
|
268
|
+
readonly svm?: string;
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
type ToolHandler = (arguments_: Record<string, unknown>) => Promise<ToolResult> | ToolResult;
|
|
272
|
+
/** Registration shape for a free tool. */
|
|
273
|
+
interface RegisterToolOptions {
|
|
274
|
+
/** Optional MCP tool annotations (`readOnlyHint`, `title`, …). */
|
|
275
|
+
annotations?: Tool["annotations"];
|
|
276
|
+
/** Human/model-facing description of what the tool does. */
|
|
17
277
|
description: string;
|
|
278
|
+
/** JSON-Schema object describing the tool's arguments. */
|
|
18
279
|
inputSchema: ToolInputSchema;
|
|
280
|
+
/** Unique tool name (the MCP `tools/call` `name`). */
|
|
19
281
|
name: string;
|
|
20
282
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
283
|
+
/** Registration shape for a paid tool: a {@link RegisterToolOptions} plus its USD price. */
|
|
284
|
+
interface RegisterPaidToolOptions extends RegisterToolOptions {
|
|
285
|
+
/** USD price per call (e.g. `"$0.05"`), charged via x402 before dispatch. */
|
|
286
|
+
price: X402Price;
|
|
287
|
+
}
|
|
288
|
+
/** x402 settlement vocabulary shared by every paid tool (network, recipient, facilitator); price is per-tool. */
|
|
289
|
+
type PaidMcpChargeConfig = X402ChargeSettings;
|
|
290
|
+
/** Config for `createPaidMcpServer`. */
|
|
291
|
+
interface PaidMcpServerConfig {
|
|
292
|
+
/** The worker-level x402 charge config; each paid tool supplies only its own `price`. */
|
|
293
|
+
charge: PaidMcpChargeConfig;
|
|
294
|
+
/** Name/version advertised in the MCP `initialize` handshake. Defaults to `lunora-paid-mcp`. */
|
|
295
|
+
serverInfo?: {
|
|
296
|
+
name: string;
|
|
297
|
+
version: string;
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/** A paid MCP server: register free/paid tools, then serve over Streamable HTTP. */
|
|
301
|
+
interface PaidMcpServer {
|
|
302
|
+
/** The Streamable-HTTP fetch handler; gates each paid `tools/call` behind x402. */
|
|
303
|
+
readonly fetchHandler: McpFetchHandler;
|
|
304
|
+
/** Register a **paid** tool: its dispatch runs the x402 charge middleware first. */
|
|
305
|
+
paidTool: (options: RegisterPaidToolOptions, handler: ToolHandler) => void;
|
|
306
|
+
/** Register a **free** tool (coexists with paid tools on the same server). */
|
|
307
|
+
tool: (options: RegisterToolOptions, handler: ToolHandler) => void;
|
|
27
308
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Create a paid MCP server. Register free tools with `tool()` and priced tools
|
|
311
|
+
* with `paidTool()` (they coexist), then serve `fetchHandler` over HTTP.
|
|
312
|
+
*
|
|
313
|
+
* The server is **stateless**: `fetchHandler` builds a fresh `Server` per
|
|
314
|
+
* request (reading the live tool registry), so tools registered before the
|
|
315
|
+
* first request are all visible. Each priced tool memoises one initialised
|
|
316
|
+
* `ChargeMiddleware` (keyed by tool name, baking that tool's price and naming
|
|
317
|
+
* the tool as the challenge `resource`); a failed init is not cached, so a
|
|
318
|
+
* transient facilitator outage retries on the next call.
|
|
319
|
+
*/
|
|
320
|
+
declare const createPaidMcpServer: (config: PaidMcpServerConfig) => PaidMcpServer;
|
|
321
|
+
export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME,
|
|
322
|
+
/**
|
|
323
|
+
* `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
|
|
324
|
+
* a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
|
|
325
|
+
* framework's *documentation* (credential-free, and safe to host publicly).
|
|
326
|
+
*
|
|
327
|
+
* The deployment server: It registers tools for introspecting a deployment
|
|
328
|
+
* (`lunora_list_functions`, `lunora_list_tables`) and invoking its functions
|
|
329
|
+
* (`lunora_run_query`, plus `lunora_run_mutation` and `lunora_run_action` when
|
|
330
|
+
* writes are enabled), each backed by `LunoraClient` over HTTP RPC. It also
|
|
331
|
+
* exposes the deployment's observability reads (`lunora_get_logs`,
|
|
332
|
+
* `lunora_get_issues`, `lunora_get_advisories`, `lunora_get_query_insights`,
|
|
333
|
+
* `lunora_get_migration_status`) whenever an admin token resolved — read-only,
|
|
334
|
+
* but privileged, so they are omitted entirely without one. The server is
|
|
335
|
+
* read-only by default — the write tools are exposed only when `allowWrites`
|
|
336
|
+
* (or the `LUNORA_MCP_ALLOW_WRITES` env) is set, and every run tool is
|
|
337
|
+
* allowlisted against the deployment's discovered public functions. It can also
|
|
338
|
+
* front durable `@lunora/agent` runs as `agent_<name>` tools when `allowAgents`
|
|
339
|
+
* (or `LUNORA_MCP_ALLOW_AGENTS` + `LUNORA_MCP_AGENTS`) is set. Run the
|
|
340
|
+
* `lunora-mcp` binary (configured via the `LUNORA_URL`, `LUNORA_ADMIN_TOKEN`,
|
|
341
|
+
* and `LUNORA_MCP_ALLOW_WRITES` env vars) for the stdio transport, serve the
|
|
342
|
+
* server remotely over Streamable HTTP with `createMcpFetchHandler` (a
|
|
343
|
+
* Workers-ready `Request` → `Response` handler), or build a server
|
|
344
|
+
* programmatically with `createLunoraMcpServer` and connect any transport.
|
|
345
|
+
*/
|
|
346
|
+
type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDeploymentSource, type LocalMcpServerOptions, type LunoraMcpServerOptions,
|
|
347
|
+
/**
|
|
348
|
+
* `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
|
|
349
|
+
* a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
|
|
350
|
+
* framework's *documentation* (credential-free, and safe to host publicly).
|
|
351
|
+
*
|
|
352
|
+
* The deployment server: It registers tools for introspecting a deployment
|
|
353
|
+
* (`lunora_list_functions`, `lunora_list_tables`) and invoking its functions
|
|
354
|
+
* (`lunora_run_query`, plus `lunora_run_mutation` and `lunora_run_action` when
|
|
355
|
+
* writes are enabled), each backed by `LunoraClient` over HTTP RPC. It also
|
|
356
|
+
* exposes the deployment's observability reads (`lunora_get_logs`,
|
|
357
|
+
* `lunora_get_issues`, `lunora_get_advisories`, `lunora_get_query_insights`,
|
|
358
|
+
* `lunora_get_migration_status`) whenever an admin token resolved — read-only,
|
|
359
|
+
* but privileged, so they are omitted entirely without one. The server is
|
|
360
|
+
* read-only by default — the write tools are exposed only when `allowWrites`
|
|
361
|
+
* (or the `LUNORA_MCP_ALLOW_WRITES` env) is set, and every run tool is
|
|
362
|
+
* allowlisted against the deployment's discovered public functions. It can also
|
|
363
|
+
* front durable `@lunora/agent` runs as `agent_<name>` tools when `allowAgents`
|
|
364
|
+
* (or `LUNORA_MCP_ALLOW_AGENTS` + `LUNORA_MCP_AGENTS`) is set. Run the
|
|
365
|
+
* `lunora-mcp` binary (configured via the `LUNORA_URL`, `LUNORA_ADMIN_TOKEN`,
|
|
366
|
+
* and `LUNORA_MCP_ALLOW_WRITES` env vars) for the stdio transport, serve the
|
|
367
|
+
* server remotely over Streamable HTTP with `createMcpFetchHandler` (a
|
|
368
|
+
* Workers-ready `Request` → `Response` handler), or build a server
|
|
369
|
+
* programmatically with `createLunoraMcpServer` and connect any transport.
|
|
370
|
+
*/
|
|
371
|
+
type McpAgentExposure, type McpFetchHandler, type McpTool, NO_DEPLOYMENT_MESSAGE, OBSERVABILITY_TOOL_DEFINITIONS, type PaidMcpChargeConfig, type PaidMcpServer, type PaidMcpServerConfig, READ_ONLY_TOOL_DEFINITIONS, type RegisterPaidToolOptions, type RegisterToolOptions, type ToolDefinition, type ToolHandler, type ToolInputSchema, type ToolResult, WRITE_TOOL_DEFINITIONS, agentToolDefinitions, callAgentTool, callTool, connectLocalStdio, connectStdio, createLocalMcpServer, createLunoraMcpServer, createMcpFetchHandler, createPaidMcpServer, localTools, parseAgentsEnv, toolDefinitions };
|