@lunora/mcp 1.0.0-alpha.80 → 1.0.0-alpha.82

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/dist/index.d.mts CHANGED
@@ -165,6 +165,73 @@ declare const createLunoraMcpServer: (options: LunoraMcpServerOptions) => Server
165
165
  * connected; the process then stays alive serving requests.
166
166
  */
167
167
  declare const connectStdio: (options: LunoraMcpServerOptions) => Promise<Server>;
168
+ /**
169
+ * The verified access-token payload better-auth hands a protected handler.
170
+ *
171
+ * A JWT payload is an open bag of claims, so this is deliberately an index
172
+ * signature with the two entries this module reads named. It is structurally
173
+ * satisfied by `jose`'s `JWTPayload`, which is what better-auth passes.
174
+ */
175
+ interface McpAccessTokenClaims {
176
+ readonly [claim: string]: unknown;
177
+ /** Space-delimited granted scopes (RFC 6749 §3.3). */
178
+ readonly scope?: unknown;
179
+ /** Subject — the user the token was issued for. */
180
+ readonly sub?: string;
181
+ }
182
+ /**
183
+ * The MCP auth gate: wraps a claims-aware handler into a plain fetch handler.
184
+ *
185
+ * Declared structurally here rather than imported from `@better-auth/mcp`,
186
+ * following the same rule `./paid` follows for `@lunora/x402`: a type import
187
+ * from a package this one does not depend on puts that package's `.d.ts` into
188
+ * the build graph, and a consumer that never installs it never builds it
189
+ * either — so the dts bundler looks for a `dist/` that does not exist and fails
190
+ * the build. Structural typing costs nothing here because this module never
191
+ * inspects the gate; it only applies it.
192
+ *
193
+ * Both better-auth entry points partially apply to this shape:
194
+ * `(handler) => requireMcpAuth(auth, handler, opts)` and
195
+ * `(handler) => createMcpProtectedRequestHandler(options, handler)`.
196
+ */
197
+ type McpAuthProtect = (handler: (request: Request, claims: McpAccessTokenClaims) => Promise<Response>) => McpFetchHandler;
198
+ /** Server options, or a function deriving them from the request's verified claims. */
199
+ type AuthedMcpServerOptions = ((claims: McpAccessTokenClaims) => LunoraMcpServerOptions | Promise<LunoraMcpServerOptions>) | LunoraMcpServerOptions;
200
+ interface AuthedMcpFetchHandlerOptions {
201
+ /**
202
+ * The OAuth gate to mount the MCP server behind. Pass
203
+ * `(handler) => requireMcpAuth(auth, handler, opts)` from
204
+ * `@lunora/auth/plugins`.
205
+ */
206
+ protect: McpAuthProtect;
207
+ /**
208
+ * The Lunora MCP server to serve once a request is authorized — either a
209
+ * fixed options object, or a function of the verified token claims so tool
210
+ * exposure can follow the scopes the token actually carries.
211
+ */
212
+ server: AuthedMcpServerOptions;
213
+ }
214
+ /**
215
+ * Parse an access token's `scope` claim into a set.
216
+ *
217
+ * RFC 6749 §3.3 makes `scope` a space-delimited string, and better-auth issues
218
+ * it that way; anything else (absent, or a non-string an extension wrote)
219
+ * yields an empty set rather than throwing, so a scope check on a malformed
220
+ * token denies instead of crashing the tool call.
221
+ */
222
+ declare const mcpTokenScopes: (claims: McpAccessTokenClaims) => ReadonlySet<string>;
223
+ /**
224
+ * Build an OAuth-protected stateless Streamable-HTTP fetch handler for a Lunora
225
+ * MCP server.
226
+ *
227
+ * Unauthenticated requests never reach the MCP server at all: `protect` answers
228
+ * them with the RFC 9728 `WWW-Authenticate` challenge that starts the client's
229
+ * authorization flow. An authorized request builds a fresh proxy server from
230
+ * `server` (resolved against the verified claims) and serves it through
231
+ * {@link serveStateless}, exactly as the unprotected `createMcpFetchHandler`
232
+ * does — the transport behaviour is identical, only the gate is new.
233
+ */
234
+ declare const createAuthedMcpFetchHandler: (options: AuthedMcpFetchHandlerOptions) => McpFetchHandler;
168
235
  /**
169
236
  * Build a stateless Streamable-HTTP fetch handler for a Lunora MCP server. Each
170
237
  * invocation constructs a fresh proxy server and serves the request through
@@ -318,7 +385,7 @@ interface PaidMcpServer {
318
385
  * transient facilitator outage retries on the next call.
319
386
  */
320
387
  declare const createPaidMcpServer: (config: PaidMcpServerConfig) => PaidMcpServer;
321
- export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME,
388
+ export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME, type AuthedMcpFetchHandlerOptions, type AuthedMcpServerOptions,
322
389
  /**
323
390
  * `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
324
391
  * a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
@@ -342,8 +409,14 @@ export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME,
342
409
  * server remotely over Streamable HTTP with `createMcpFetchHandler` (a
343
410
  * Workers-ready `Request` → `Response` handler), or build a server
344
411
  * programmatically with `createLunoraMcpServer` and connect any transport.
412
+ *
413
+ * A remote endpoint is reachable by anyone who knows its URL, and the tools
414
+ * carry the deployment's admin bearer — so for a public deployment use
415
+ * `createAuthedMcpFetchHandler` instead, which mounts the same server behind
416
+ * better-auth's MCP OAuth gate (`requireMcpAuth` from `@lunora/auth/plugins`)
417
+ * and can scope tool exposure to the access token's own scopes.
345
418
  */
346
- type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDeploymentSource, type LocalMcpServerOptions, type LunoraMcpServerOptions,
419
+ type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDeploymentSource, type LocalMcpServerOptions, type LunoraMcpServerOptions, type McpAccessTokenClaims,
347
420
  /**
348
421
  * `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
349
422
  * a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
@@ -367,5 +440,11 @@ type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDe
367
440
  * server remotely over Streamable HTTP with `createMcpFetchHandler` (a
368
441
  * Workers-ready `Request` → `Response` handler), or build a server
369
442
  * programmatically with `createLunoraMcpServer` and connect any transport.
443
+ *
444
+ * A remote endpoint is reachable by anyone who knows its URL, and the tools
445
+ * carry the deployment's admin bearer — so for a public deployment use
446
+ * `createAuthedMcpFetchHandler` instead, which mounts the same server behind
447
+ * better-auth's MCP OAuth gate (`requireMcpAuth` from `@lunora/auth/plugins`)
448
+ * and can scope tool exposure to the access token's own scopes.
370
449
  */
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 };
450
+ type McpAgentExposure, type McpAuthProtect, 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, createAuthedMcpFetchHandler, createLocalMcpServer, createLunoraMcpServer, createMcpFetchHandler, createPaidMcpServer, localTools, mcpTokenScopes, parseAgentsEnv, toolDefinitions };
package/dist/index.d.ts CHANGED
@@ -165,6 +165,73 @@ declare const createLunoraMcpServer: (options: LunoraMcpServerOptions) => Server
165
165
  * connected; the process then stays alive serving requests.
166
166
  */
167
167
  declare const connectStdio: (options: LunoraMcpServerOptions) => Promise<Server>;
168
+ /**
169
+ * The verified access-token payload better-auth hands a protected handler.
170
+ *
171
+ * A JWT payload is an open bag of claims, so this is deliberately an index
172
+ * signature with the two entries this module reads named. It is structurally
173
+ * satisfied by `jose`'s `JWTPayload`, which is what better-auth passes.
174
+ */
175
+ interface McpAccessTokenClaims {
176
+ readonly [claim: string]: unknown;
177
+ /** Space-delimited granted scopes (RFC 6749 §3.3). */
178
+ readonly scope?: unknown;
179
+ /** Subject — the user the token was issued for. */
180
+ readonly sub?: string;
181
+ }
182
+ /**
183
+ * The MCP auth gate: wraps a claims-aware handler into a plain fetch handler.
184
+ *
185
+ * Declared structurally here rather than imported from `@better-auth/mcp`,
186
+ * following the same rule `./paid` follows for `@lunora/x402`: a type import
187
+ * from a package this one does not depend on puts that package's `.d.ts` into
188
+ * the build graph, and a consumer that never installs it never builds it
189
+ * either — so the dts bundler looks for a `dist/` that does not exist and fails
190
+ * the build. Structural typing costs nothing here because this module never
191
+ * inspects the gate; it only applies it.
192
+ *
193
+ * Both better-auth entry points partially apply to this shape:
194
+ * `(handler) => requireMcpAuth(auth, handler, opts)` and
195
+ * `(handler) => createMcpProtectedRequestHandler(options, handler)`.
196
+ */
197
+ type McpAuthProtect = (handler: (request: Request, claims: McpAccessTokenClaims) => Promise<Response>) => McpFetchHandler;
198
+ /** Server options, or a function deriving them from the request's verified claims. */
199
+ type AuthedMcpServerOptions = ((claims: McpAccessTokenClaims) => LunoraMcpServerOptions | Promise<LunoraMcpServerOptions>) | LunoraMcpServerOptions;
200
+ interface AuthedMcpFetchHandlerOptions {
201
+ /**
202
+ * The OAuth gate to mount the MCP server behind. Pass
203
+ * `(handler) => requireMcpAuth(auth, handler, opts)` from
204
+ * `@lunora/auth/plugins`.
205
+ */
206
+ protect: McpAuthProtect;
207
+ /**
208
+ * The Lunora MCP server to serve once a request is authorized — either a
209
+ * fixed options object, or a function of the verified token claims so tool
210
+ * exposure can follow the scopes the token actually carries.
211
+ */
212
+ server: AuthedMcpServerOptions;
213
+ }
214
+ /**
215
+ * Parse an access token's `scope` claim into a set.
216
+ *
217
+ * RFC 6749 §3.3 makes `scope` a space-delimited string, and better-auth issues
218
+ * it that way; anything else (absent, or a non-string an extension wrote)
219
+ * yields an empty set rather than throwing, so a scope check on a malformed
220
+ * token denies instead of crashing the tool call.
221
+ */
222
+ declare const mcpTokenScopes: (claims: McpAccessTokenClaims) => ReadonlySet<string>;
223
+ /**
224
+ * Build an OAuth-protected stateless Streamable-HTTP fetch handler for a Lunora
225
+ * MCP server.
226
+ *
227
+ * Unauthenticated requests never reach the MCP server at all: `protect` answers
228
+ * them with the RFC 9728 `WWW-Authenticate` challenge that starts the client's
229
+ * authorization flow. An authorized request builds a fresh proxy server from
230
+ * `server` (resolved against the verified claims) and serves it through
231
+ * {@link serveStateless}, exactly as the unprotected `createMcpFetchHandler`
232
+ * does — the transport behaviour is identical, only the gate is new.
233
+ */
234
+ declare const createAuthedMcpFetchHandler: (options: AuthedMcpFetchHandlerOptions) => McpFetchHandler;
168
235
  /**
169
236
  * Build a stateless Streamable-HTTP fetch handler for a Lunora MCP server. Each
170
237
  * invocation constructs a fresh proxy server and serves the request through
@@ -318,7 +385,7 @@ interface PaidMcpServer {
318
385
  * transient facilitator outage retries on the next call.
319
386
  */
320
387
  declare const createPaidMcpServer: (config: PaidMcpServerConfig) => PaidMcpServer;
321
- export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME,
388
+ export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME, type AuthedMcpFetchHandlerOptions, type AuthedMcpServerOptions,
322
389
  /**
323
390
  * `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
324
391
  * a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
@@ -342,8 +409,14 @@ export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME,
342
409
  * server remotely over Streamable HTTP with `createMcpFetchHandler` (a
343
410
  * Workers-ready `Request` → `Response` handler), or build a server
344
411
  * programmatically with `createLunoraMcpServer` and connect any transport.
412
+ *
413
+ * A remote endpoint is reachable by anyone who knows its URL, and the tools
414
+ * carry the deployment's admin bearer — so for a public deployment use
415
+ * `createAuthedMcpFetchHandler` instead, which mounts the same server behind
416
+ * better-auth's MCP OAuth gate (`requireMcpAuth` from `@lunora/auth/plugins`)
417
+ * and can scope tool exposure to the access token's own scopes.
345
418
  */
346
- type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDeploymentSource, type LocalMcpServerOptions, type LunoraMcpServerOptions,
419
+ type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDeploymentSource, type LocalMcpServerOptions, type LunoraMcpServerOptions, type McpAccessTokenClaims,
347
420
  /**
348
421
  * `@lunora/mcp` — Model Context Protocol servers for Lunora. This entry exposes
349
422
  * a *deployment* to AI agents; the `@lunora/mcp/docs` subpath exposes the
@@ -367,5 +440,11 @@ type CallAgentToolOptions, LOCAL_SERVER_NAME, type LocalDeployment, type LocalDe
367
440
  * server remotely over Streamable HTTP with `createMcpFetchHandler` (a
368
441
  * Workers-ready `Request` → `Response` handler), or build a server
369
442
  * programmatically with `createLunoraMcpServer` and connect any transport.
443
+ *
444
+ * A remote endpoint is reachable by anyone who knows its URL, and the tools
445
+ * carry the deployment's admin bearer — so for a public deployment use
446
+ * `createAuthedMcpFetchHandler` instead, which mounts the same server behind
447
+ * better-auth's MCP OAuth gate (`requireMcpAuth` from `@lunora/auth/plugins`)
448
+ * and can scope tool exposure to the access token's own scopes.
370
449
  */
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 };
450
+ type McpAgentExposure, type McpAuthProtect, 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, createAuthedMcpFetchHandler, createLocalMcpServer, createLunoraMcpServer, createMcpFetchHandler, createPaidMcpServer, localTools, mcpTokenScopes, parseAgentsEnv, toolDefinitions };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{AGENT_RUN_INPUT_SCHEMA as r,AGENT_STATUS_TOOL_NAME as t,agentToolDefinitions as T,callAgentTool as c,parseAgentsEnv as E}from"./packem_shared/AGENT_RUN_INPUT_SCHEMA-DRSY74ed.mjs";import{createToolServer as O}from"./packem_shared/createToolServer-BtGuPyMU.mjs";import{createMcpFetchHandler as _}from"./packem_shared/createMcpFetchHandler-TKDnZTGs.mjs";import{LOCAL_SERVER_NAME as N,NO_DEPLOYMENT_MESSAGE as n,connectLocalStdio as p,createLocalMcpServer as I,localTools as A}from"./packem_shared/LOCAL_SERVER_NAME-CisKTqzv.mjs";import{createPaidMcpServer as f}from"./packem_shared/createPaidMcpServer-CQO-59WV.mjs";import{connectStdio as m,createLunoraMcpServer as s}from"./packem_shared/connectStdio-BCeI0Wqu.mjs";import{READ_ONLY_TOOL_DEFINITIONS as M,WRITE_TOOL_DEFINITIONS as D,callTool as v,toolDefinitions as R}from"./packem_shared/READ_ONLY_TOOL_DEFINITIONS-DGexf3Tn.mjs";import{O as F}from"./packem_shared/observability-tools-Ce0YK58T.mjs";import{serveStateless as G}from"./packem_shared/serveStateless-Db7J3pAO.mjs";export{r as AGENT_RUN_INPUT_SCHEMA,t as AGENT_STATUS_TOOL_NAME,N as LOCAL_SERVER_NAME,n as NO_DEPLOYMENT_MESSAGE,F as OBSERVABILITY_TOOL_DEFINITIONS,M as READ_ONLY_TOOL_DEFINITIONS,D as WRITE_TOOL_DEFINITIONS,T as agentToolDefinitions,c as callAgentTool,v as callTool,p as connectLocalStdio,m as connectStdio,I as createLocalMcpServer,s as createLunoraMcpServer,_ as createMcpFetchHandler,f as createPaidMcpServer,O as createToolServer,A as localTools,E as parseAgentsEnv,G as serveStateless,R as toolDefinitions};
1
+ import{AGENT_RUN_INPUT_SCHEMA as r,AGENT_STATUS_TOOL_NAME as t,agentToolDefinitions as c,callAgentTool as T,parseAgentsEnv as a}from"./packem_shared/AGENT_RUN_INPUT_SCHEMA-DRSY74ed.mjs";import{createAuthedMcpFetchHandler as E,mcpTokenScopes as S}from"./packem_shared/createAuthedMcpFetchHandler-BUoCjrxu.mjs";import{createToolServer as O}from"./packem_shared/createToolServer-BtGuPyMU.mjs";import{createMcpFetchHandler as n}from"./packem_shared/createMcpFetchHandler-TKDnZTGs.mjs";import{LOCAL_SERVER_NAME as A,NO_DEPLOYMENT_MESSAGE as I,connectLocalStdio as f,createLocalMcpServer as L,localTools as m}from"./packem_shared/LOCAL_SERVER_NAME-CisKTqzv.mjs";import{createPaidMcpServer as x}from"./packem_shared/createPaidMcpServer-CQO-59WV.mjs";import{connectStdio as i,createLunoraMcpServer as D}from"./packem_shared/connectStdio-BCeI0Wqu.mjs";import{READ_ONLY_TOOL_DEFINITIONS as v,WRITE_TOOL_DEFINITIONS as R,callTool as F,toolDefinitions as g}from"./packem_shared/READ_ONLY_TOOL_DEFINITIONS-DGexf3Tn.mjs";import{O as G}from"./packem_shared/observability-tools-Ce0YK58T.mjs";import{serveStateless as P}from"./packem_shared/serveStateless-Db7J3pAO.mjs";export{r as AGENT_RUN_INPUT_SCHEMA,t as AGENT_STATUS_TOOL_NAME,A as LOCAL_SERVER_NAME,I as NO_DEPLOYMENT_MESSAGE,G as OBSERVABILITY_TOOL_DEFINITIONS,v as READ_ONLY_TOOL_DEFINITIONS,R as WRITE_TOOL_DEFINITIONS,c as agentToolDefinitions,T as callAgentTool,F as callTool,f as connectLocalStdio,i as connectStdio,E as createAuthedMcpFetchHandler,L as createLocalMcpServer,D as createLunoraMcpServer,n as createMcpFetchHandler,x as createPaidMcpServer,O as createToolServer,m as localTools,S as mcpTokenScopes,a as parseAgentsEnv,P as serveStateless,g as toolDefinitions};
@@ -0,0 +1 @@
1
+ import{serveStateless as n}from"./serveStateless-Db7J3pAO.mjs";import{createLunoraMcpServer as o}from"./connectStdio-BCeI0Wqu.mjs";const a=e=>typeof e.scope!="string"?new Set:new Set(e.scope.split(" ").filter(r=>r!=="")),f=e=>e.protect(async(r,t)=>{const c=typeof e.server=="function"?await e.server(t):e.server;return await n(o(c),r)});export{f as createAuthedMcpFetchHandler,a as mcpTokenScopes};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/mcp",
3
- "version": "1.0.0-alpha.80",
3
+ "version": "1.0.0-alpha.82",
4
4
  "description": "Model Context Protocol server exposing a Lunora deployment to AI agents",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -53,9 +53,9 @@
53
53
  "access": "public"
54
54
  },
55
55
  "dependencies": {
56
- "@lunora/client": "1.0.0-alpha.55",
56
+ "@lunora/client": "1.0.0-alpha.56",
57
57
  "@lunora/errors": "1.0.0-alpha.22",
58
- "@lunora/shard-engine": "1.0.0-alpha.33",
58
+ "@lunora/shard-engine": "1.0.0-alpha.34",
59
59
  "@modelcontextprotocol/sdk": "^1.30.0"
60
60
  },
61
61
  "peerDependencies": {