@lunora/mcp 1.0.0-alpha.13 → 1.0.0-alpha.131
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 +157 -10
- package/dist/bin.mjs +4 -35
- package/dist/docs/index.d.mts +258 -0
- package/dist/docs/index.d.ts +258 -0
- package/dist/docs/index.mjs +1 -0
- package/dist/index.d.mts +511 -14
- package/dist/index.d.ts +511 -14
- package/dist/index.mjs +1 -2
- package/dist/packem_shared/AGENT_RUN_INPUT_SCHEMA-hKbpa3Dg.mjs +1 -0
- package/dist/packem_shared/DEFAULT_DOCS_BASE_URL-CZ3fVsSc.mjs +4 -0
- package/dist/packem_shared/DEFAULT_MAX_REQUEST_BYTES-CbbpkHRK.mjs +1 -0
- package/dist/packem_shared/DEFAULT_SEARCH_LIMIT-BqSYN5vr.mjs +3 -0
- package/dist/packem_shared/DOCS_SERVER_NAME-BMeAWi5h.mjs +1 -0
- package/dist/packem_shared/DOCS_URI_SCHEME-Buo752CV.mjs +3 -0
- package/dist/packem_shared/LOCAL_SERVER_NAME-DPay9JzK.mjs +1 -0
- package/dist/packem_shared/OBSERVABILITY_TOOL_DEFINITIONS-Byqgb9wh.mjs +1 -0
- package/dist/packem_shared/READ_ONLY_TOOL_DEFINITIONS-_aG40yWx.mjs +1 -0
- package/dist/packem_shared/connectStdio-BBtfW4UB.mjs +1 -0
- package/dist/packem_shared/createAuthedMcpFetchHandler-DwOzAueC.mjs +1 -0
- package/dist/packem_shared/createMcpFetchHandler-DSK2X9Hd.mjs +1 -0
- package/dist/packem_shared/createPaidMcpServer-BIBKMtxs.mjs +1 -0
- package/dist/packem_shared/createToolServer-BtGuPyMU.mjs +1 -0
- package/dist/packem_shared/observability-tools-B-g9Y9IT.mjs +1 -0
- package/dist/packem_shared/serve-stateless.d-CKsbI0fP.d.mts +154 -0
- package/dist/packem_shared/serve-stateless.d-CKsbI0fP.d.ts +154 -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,258 @@
|
|
|
1
|
+
import { M as McpResourceProvider, a as McpFetchHandler, T as ToolDefinition, b as McpTool } from "../packem_shared/serve-stateless.d-CKsbI0fP.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-CKsbI0fP.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
|
+
/**
|
|
139
|
+
* Largest accepted request body, in bytes — enforced while the body streams
|
|
140
|
+
* in, not after it is buffered. Defaults to `DEFAULT_MAX_REQUEST_BYTES`
|
|
141
|
+
* (re-exported at the foot of this module), which a value that is not a
|
|
142
|
+
* non-negative safe integer also falls back to.
|
|
143
|
+
*/
|
|
144
|
+
maxRequestBytes?: number;
|
|
145
|
+
/**
|
|
146
|
+
* Version reported in the handshake. Defaults to `"0.0.0"` — a docs site
|
|
147
|
+
* bundles this code rather than installing it, so it, not the package, is
|
|
148
|
+
* the thing whose version a client would want to see.
|
|
149
|
+
*/
|
|
150
|
+
version?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build a transport-agnostic MCP server exposing the documentation tools.
|
|
154
|
+
* Connect it yourself, or use {@link createDocsMcpFetchHandler} for the remote
|
|
155
|
+
* HTTP case.
|
|
156
|
+
*/
|
|
157
|
+
declare const createDocsMcpServer: (options: DocsMcpServerOptions) => Server;
|
|
158
|
+
/**
|
|
159
|
+
* Build a stateless Streamable-HTTP fetch handler serving the documentation
|
|
160
|
+
* tools — the `Request` → `Response` function a docs site mounts at `/mcp`.
|
|
161
|
+
*
|
|
162
|
+
* A fresh server per request keeps the handler safe on platforms that fan
|
|
163
|
+
* requests across isolates, where nothing may be assumed to persist between
|
|
164
|
+
* them.
|
|
165
|
+
*/
|
|
166
|
+
declare const createDocsMcpFetchHandler: (options: DocsMcpServerOptions) => McpFetchHandler;
|
|
167
|
+
/** Hits returned when the caller doesn't ask for a specific number. */
|
|
168
|
+
declare const DEFAULT_SEARCH_LIMIT = 10;
|
|
169
|
+
/**
|
|
170
|
+
* Ceiling on hits per call. Search results are pasted into the model's context
|
|
171
|
+
* verbatim, so an unbounded `limit` is a context-exhaustion foot-gun rather
|
|
172
|
+
* than a useful option.
|
|
173
|
+
*/
|
|
174
|
+
declare const MAX_SEARCH_LIMIT = 50;
|
|
175
|
+
/** The advertised surface, in the order a caller should reach for it. */
|
|
176
|
+
declare const DOCS_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
|
|
177
|
+
/**
|
|
178
|
+
* Normalize whatever a model passes as a page URL into the site-relative form
|
|
179
|
+
* an index stores.
|
|
180
|
+
*
|
|
181
|
+
* Models copy URLs from anywhere — a search hit (`/docs/sharding`), the browser
|
|
182
|
+
* (`https://lunora.sh/docs/sharding`), or their own memory of the slug
|
|
183
|
+
* (`sharding`, `docs/sharding`). All four are the same page, and failing three
|
|
184
|
+
* of them would push the model into a guess-and-retry loop, so resolve them to
|
|
185
|
+
* one form. A trailing slash is dropped for the same reason.
|
|
186
|
+
*
|
|
187
|
+
* A `..` segment is REJECTED rather than resolved. The remote backend appends
|
|
188
|
+
* this path to `/llms.mdx`, so `../../api/search` would walk back out of the
|
|
189
|
+
* documentation tree and pull an unrelated path on the docs origin into the
|
|
190
|
+
* model's context — harmless against a public site, less so against the
|
|
191
|
+
* internal host a self-hosted `--docs-url` may point at. Percent-encoded
|
|
192
|
+
* forms (`%2e%2e`, doubled `%252e`) are rejected the same way: WHATWG URL
|
|
193
|
+
* parsing at fetch time decodes and collapses them into the very traversal
|
|
194
|
+
* the literal check would have caught.
|
|
195
|
+
*/
|
|
196
|
+
declare const normalizeDocUrl: (raw: string) => string;
|
|
197
|
+
/**
|
|
198
|
+
* The documentation surface, bound to `index`.
|
|
199
|
+
*
|
|
200
|
+
* Each tool carries its own handler rather than routing through a shared
|
|
201
|
+
* `switch`: `createToolServer` already dispatches by name, so a second switch
|
|
202
|
+
* here would be a duplicate table with an unreachable `default`. It also owns
|
|
203
|
+
* the throw-to-`isError` conversion, so these handlers signal argument problems
|
|
204
|
+
* by throwing and return `isError` only for the expected misses a model should
|
|
205
|
+
* read and act on.
|
|
206
|
+
*/
|
|
207
|
+
declare const docsTools: (index: DocsIndex) => ReadonlyArray<McpTool>;
|
|
208
|
+
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,
|
|
209
|
+
/**
|
|
210
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
211
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
212
|
+
*
|
|
213
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
214
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
215
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
216
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
217
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
218
|
+
* unauthenticated.
|
|
219
|
+
*
|
|
220
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
221
|
+
* its own in-process search index, while anything else (the CLI's
|
|
222
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
223
|
+
* published site over HTTP.
|
|
224
|
+
*
|
|
225
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
226
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
227
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
228
|
+
*
|
|
229
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
230
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
231
|
+
* both entries gets one implementation rather than two copies.
|
|
232
|
+
*/
|
|
233
|
+
type McpResourceProvider,
|
|
234
|
+
/**
|
|
235
|
+
* `@lunora/mcp/docs` — the documentation tool surface: `lunora_search_docs`,
|
|
236
|
+
* `lunora_get_doc`, and `lunora_list_docs`.
|
|
237
|
+
*
|
|
238
|
+
* Where the package's main entry exposes a deployment to an agent (its
|
|
239
|
+
* functions and data, behind an admin token), this entry exposes the
|
|
240
|
+
* framework's documentation, so an agent writing Lunora code can look up the
|
|
241
|
+
* real API instead of inventing one. It reads published docs only — no
|
|
242
|
+
* credentials, no writes — so a server built from it is safe to host
|
|
243
|
+
* unauthenticated.
|
|
244
|
+
*
|
|
245
|
+
* Two backends implement the same `DocsIndex` contract: a docs site wires up
|
|
246
|
+
* its own in-process search index, while anything else (the CLI's
|
|
247
|
+
* `lunora mcp serve`, a script) uses `createRemoteDocsIndex` to read a
|
|
248
|
+
* published site over HTTP.
|
|
249
|
+
*
|
|
250
|
+
* This entry is free of Node built-ins and of `@lunora/client`, so it runs on
|
|
251
|
+
* Workers, Netlify/Vercel functions, Deno, and Bun unchanged —
|
|
252
|
+
* `scripts/check-dist-production.js` asserts that against the emitted chunks.
|
|
253
|
+
*
|
|
254
|
+
* Only the documentation surface lives here. The generic composition primitive
|
|
255
|
+
* (`createToolServer`) is exported from the package root, so a consumer using
|
|
256
|
+
* both entries gets one implementation rather than two copies.
|
|
257
|
+
*/
|
|
258
|
+
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-Buo752CV.mjs";import{DOCS_SERVER_NAME as R,createDocsMcpFetchHandler as p,createDocsMcpServer as A}from"../packem_shared/DOCS_SERVER_NAME-BMeAWi5h.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-BqSYN5vr.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};
|