@lunora/mcp 1.0.0-alpha.26 → 1.0.0-alpha.28

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
@@ -3,6 +3,15 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
4
4
  import { X402ChargeConfig, X402Price } from '@lunora/x402/charge';
5
5
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
6
+ /**
7
+ * The tool surface this MCP server exposes. Each tool maps onto a method the
8
+ * `LunoraClient` already provides, so an AI agent can introspect a deployment
9
+ * (functions, global tables) and invoke its functions over HTTP RPC.
10
+ *
11
+ * Definitions and dispatch live here — separate from the server wiring — so the
12
+ * behaviour is unit-testable against a mock client without driving a transport.
13
+ */
14
+ /** A JSON-Schema object describing a tool's arguments, per the MCP spec. */
6
15
  interface ToolInputSchema {
7
16
  properties: Record<string, unknown>;
8
17
  required?: ReadonlyArray<string>;
@@ -13,6 +22,7 @@ interface ToolDefinition {
13
22
  inputSchema: ToolInputSchema;
14
23
  name: string;
15
24
  }
25
+ /** The MCP `CallToolResult` shape this server returns. */
16
26
  interface ToolResult {
17
27
  content: {
18
28
  text: string;
@@ -20,64 +30,205 @@ interface ToolResult {
20
30
  }[];
21
31
  isError?: boolean;
22
32
  }
33
+ /** The read-only tool surface: introspection + query. Always exposed. */
23
34
  declare const READ_ONLY_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
35
+ /** The write tool surface (mutations + actions). Exposed ONLY when writes are enabled. */
24
36
  declare const WRITE_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
37
+ /**
38
+ * The tools this server advertises. When `allowWrites` is false (the default),
39
+ * only the read-only surface is exposed — the mutation/action tools are omitted
40
+ * from `ListTools` entirely, so an AI agent can't invoke a write it can't see.
41
+ */
25
42
  declare const toolDefinitions: (allowWrites: boolean) => ReadonlyArray<ToolDefinition>;
43
+ /**
44
+ * Dispatch a tool call against `client`. Unknown tools and thrown errors are
45
+ * returned as `isError` results (rather than rejections) so the calling model
46
+ * sees the failure as tool output, per the MCP convention.
47
+ *
48
+ * `allowWrites` gates the mutation/action tools: when false (the default) a call
49
+ * to a write tool is refused even if the client somehow names it, so the
50
+ * read-only guarantee holds at dispatch, not just in the advertised tool list.
51
+ */
26
52
  declare const callTool: (client: LunoraClient, name: string, input: Record<string, unknown>, allowWrites?: boolean) => Promise<ToolResult>;
53
+ /**
54
+ * Agent exposure for the MCP server: a durable `@lunora/agent` run fronted as an
55
+ * MCP tool an external agent can call. The capability boundary is the MCP-server
56
+ * process + its token, so WHICH agents are exposed is config on the server (like
57
+ * `allowWrites`), not on `defineAgent` — keeping `@lunora/agent` codegen
58
+ * byte-identical.
59
+ */
27
60
  interface McpAgentExposure {
61
+ /** What the agent does — shown to the calling model, which decides from it. */
28
62
  description: string;
63
+ /** The agent's export name (its `ctx.agents.&lt;name>` / `AGENT_&lt;NAME>` binding). */
29
64
  name: string;
65
+ /** Override the model-facing tool name (default `agent_&lt;name>`). */
30
66
  toolName?: string;
31
67
  }
68
+ /** The generic status/poll tool advertised alongside the per-agent tools. */
32
69
  declare const AGENT_STATUS_TOOL_NAME = "lunora_agent_status";
70
+ /**
71
+ * The uniform input schema every agent tool advertises. Agents share ONE run
72
+ * input (`@lunora/agent` has no per-agent validator), so there is nothing to
73
+ * derive per agent — a single static schema is reused for every agent tool.
74
+ */
33
75
  declare const AGENT_RUN_INPUT_SCHEMA: ToolInputSchema;
76
+ /**
77
+ * Parse `LUNORA_MCP_AGENTS` — a `;`-separated list of `name:description` pairs,
78
+ * e.g. `"support:Handles support questions;billing:Billing help"`. The
79
+ * description may itself contain colons (only the FIRST colon splits). Blank
80
+ * entries and entries with an empty name/description are skipped.
81
+ */
34
82
  declare const parseAgentsEnv: (raw: string | undefined) => McpAgentExposure[];
83
+ /**
84
+ * The tools this module advertises. Fail-closed: only the boolean `true` opts
85
+ * in (an env-plumbed caller could pass a truthy string), and the tools appear
86
+ * ONLY when at least one agent is exposed — so an agent-free or non-opted-in
87
+ * server never lists them.
88
+ */
35
89
  declare const agentToolDefinitions: (exposures: ReadonlyArray<McpAgentExposure>, allowAgents: boolean) => ReadonlyArray<ToolDefinition>;
90
+ /** Options threaded into a single agent tool dispatch. */
36
91
  interface CallAgentToolOptions {
92
+ /** Opt-in gate — must be exactly `true` or the call is refused fail-closed. */
37
93
  allowAgents: boolean;
94
+ /** The exposures advertised by this server. */
38
95
  exposures: ReadonlyArray<McpAgentExposure>;
96
+ /** Wall-clock budget a single call awaits before returning a pending result. */
39
97
  maxWaitMs?: number;
98
+ /** Delay between thread-status polls. */
40
99
  pollIntervalMs?: number;
100
+ /** Test seam replacing the between-poll wait; production uses a real timer. */
41
101
  wait?: (ms: number) => Promise<void>;
42
102
  }
103
+ /**
104
+ * Dispatch an agent tool call: start a durable run via `agents:agentRun`, then
105
+ * await-with-timeout — poll `agents:agentThread` until terminal (returning the
106
+ * final answer from `agents:agentMessages`) or, on budget exhaustion, return a
107
+ * NON-error pending payload the caller resumes with `lunora_agent_status`.
108
+ *
109
+ * Fail-closed: refused at dispatch unless `allowAgents === true`, mirroring the
110
+ * `allowWrites` guard — starting a run is a side effect and must not ride the
111
+ * read-only default.
112
+ */
43
113
  declare const callAgentTool: (client: LunoraClient, name: string, input: Record<string, unknown>, options: CallAgentToolOptions) => Promise<ToolResult>;
44
114
  interface LunoraMcpServerOptions {
115
+ /** Wall-clock budget a single agent tool call awaits before returning a pending result. */
45
116
  agentMaxWaitMs?: number;
117
+ /** Delay between agent thread-status polls. */
46
118
  agentPollIntervalMs?: number;
119
+ /** The agents this server fronts as MCP tools (see `allowAgents`). */
47
120
  agents?: ReadonlyArray<McpAgentExposure>;
121
+ /**
122
+ * Expose the per-agent tools (`agent_&lt;name>` + the generic
123
+ * `lunora_agent_status`). Defaults to `false`, mirroring `allowWrites`:
124
+ * starting a durable agent run is a side effect, so the agent tools are
125
+ * omitted from the advertised list AND refused at dispatch unless explicitly
126
+ * opted in. Only takes effect together with a non-empty `agents` list.
127
+ */
48
128
  allowAgents?: boolean;
129
+ /**
130
+ * Expose the write tools (`lunora_run_mutation` / `lunora_run_action`).
131
+ * Defaults to `false`: the server is READ-ONLY unless explicitly opted in,
132
+ * so a prompt-injected or misaligned agent can't mutate the deployment with
133
+ * the configured token. When false the write tools are omitted from the
134
+ * advertised tool list AND refused at dispatch.
135
+ */
49
136
  allowWrites?: boolean;
137
+ /**
138
+ * Pre-built client (test injection). When omitted a `LunoraClient` is
139
+ * created from `url`/`token`/`fetch`.
140
+ */
50
141
  client?: LunoraClient;
142
+ /** `fetch` implementation; defaults to the ambient global. */
51
143
  fetch?: typeof fetch;
144
+ /**
145
+ * Bearer token sent on every RPC. This must be the deployment's **admin
146
+ * bearer**: the introspection/allowlist path every tool depends on
147
+ * (`lunora_list_functions`, `lunora_list_tables`, and the `assertRunnable`
148
+ * precheck that runs before every `run` tool) hits admin-gated
149
+ * `/_lunora/admin/*` routes, so no scoped/app token works today — it would
150
+ * 403 (`ADMIN_FORBIDDEN`) on the first tool call. The read-only guarantee is
151
+ * therefore NOT enforced by the token's scope; it is enforced in-process via
152
+ * `allowWrites: false` (the default), which omits the write tools from the
153
+ * advertised list and refuses them at dispatch.
154
+ */
52
155
  token?: string;
156
+ /** Base URL of the deployed Lunora Worker. Required unless `client` is given. */
53
157
  url?: string;
54
158
  }
159
+ /**
160
+ * Build an MCP `Server` whose tools talk to a Lunora deployment. The server is
161
+ * transport-agnostic — call `.connect(transport)` yourself, or use
162
+ * `connectStdio` for the common stdio case.
163
+ *
164
+ * Tool calls are dispatched through `callTool`, which the deployment reaches
165
+ * over HTTP RPC. No WebSocket is opened (the tools never subscribe), so this is
166
+ * safe to run as a short-lived stdio process.
167
+ */
55
168
  declare const createLunoraMcpServer: (options: LunoraMcpServerOptions) => Server;
169
+ /**
170
+ * Build the server and connect it over stdio — the transport MCP clients use
171
+ * when they spawn the `lunora-mcp` binary. Resolves once the transport is
172
+ * connected; the process then stays alive serving requests.
173
+ */
56
174
  declare const connectStdio: (options: LunoraMcpServerOptions) => Promise<Server>;
175
+ /** A Web-Standard fetch handler: takes a `Request`, returns the MCP `Response`. */
57
176
  type McpFetchHandler = (request: Request) => Promise<Response>;
177
+ /**
178
+ * Build a stateless Streamable-HTTP fetch handler for a Lunora MCP server. Each
179
+ * invocation constructs a fresh proxy server and serves the request through
180
+ * {@link serveStateless}.
181
+ */
58
182
  declare const createMcpFetchHandler: (options: LunoraMcpServerOptions) => McpFetchHandler;
183
+ /** A tool handler: receives the call's `arguments` bag, returns an MCP tool result. */
59
184
  type ToolHandler = (arguments_: Record<string, unknown>) => Promise<ToolResult> | ToolResult;
185
+ /** Registration shape for a free tool. */
60
186
  interface RegisterToolOptions {
187
+ /** Optional MCP tool annotations (`readOnlyHint`, `title`, …). */
61
188
  annotations?: Tool["annotations"];
189
+ /** Human/model-facing description of what the tool does. */
62
190
  description: string;
191
+ /** JSON-Schema object describing the tool's arguments. */
63
192
  inputSchema: ToolInputSchema;
193
+ /** Unique tool name (the MCP `tools/call` `name`). */
64
194
  name: string;
65
195
  }
196
+ /** Registration shape for a paid tool: a {@link RegisterToolOptions} plus its USD price. */
66
197
  interface RegisterPaidToolOptions extends RegisterToolOptions {
198
+ /** USD price per call (e.g. `"$0.05"`), charged via x402 before dispatch. */
67
199
  price: X402Price;
68
200
  }
201
+ /** x402 settlement vocabulary shared by every paid tool (network, recipient, facilitator); price is per-tool. */
69
202
  type PaidMcpChargeConfig = Omit<X402ChargeConfig, "price">;
203
+ /** Config for `createPaidMcpServer`. */
70
204
  interface PaidMcpServerConfig {
205
+ /** The worker-level x402 charge config; each paid tool supplies only its own `price`. */
71
206
  charge: PaidMcpChargeConfig;
207
+ /** Name/version advertised in the MCP `initialize` handshake. Defaults to `lunora-paid-mcp`. */
72
208
  serverInfo?: {
73
209
  name: string;
74
210
  version: string;
75
211
  };
76
212
  }
213
+ /** A paid MCP server: register free/paid tools, then serve over Streamable HTTP. */
77
214
  interface PaidMcpServer {
215
+ /** The Streamable-HTTP fetch handler; gates each paid `tools/call` behind x402. */
78
216
  readonly fetchHandler: McpFetchHandler;
217
+ /** Register a **paid** tool: its dispatch runs the x402 charge middleware first. */
79
218
  paidTool: (options: RegisterPaidToolOptions, handler: ToolHandler) => void;
219
+ /** Register a **free** tool (coexists with paid tools on the same server). */
80
220
  tool: (options: RegisterToolOptions, handler: ToolHandler) => void;
81
221
  }
222
+ /**
223
+ * Create a paid MCP server. Register free tools with `tool()` and priced tools
224
+ * with `paidTool()` (they coexist), then serve `fetchHandler` over HTTP.
225
+ *
226
+ * The server is **stateless**: `fetchHandler` builds a fresh `Server` per
227
+ * request (reading the live tool registry), so tools registered before the
228
+ * first request are all visible. Each priced tool memoises one initialised
229
+ * `ChargeMiddleware` (keyed by tool name, baking that tool's price and naming
230
+ * the tool as the challenge `resource`); a failed init is not cached, so a
231
+ * transient facilitator outage retries on the next call.
232
+ */
82
233
  declare const createPaidMcpServer: (config: PaidMcpServerConfig) => PaidMcpServer;
83
234
  export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME, type CallAgentToolOptions, type LunoraMcpServerOptions, type McpAgentExposure, type McpFetchHandler, 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, connectStdio, createLunoraMcpServer, createMcpFetchHandler, createPaidMcpServer, parseAgentsEnv, toolDefinitions };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,15 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
4
4
  import { X402ChargeConfig, X402Price } from '@lunora/x402/charge';
5
5
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
6
+ /**
7
+ * The tool surface this MCP server exposes. Each tool maps onto a method the
8
+ * `LunoraClient` already provides, so an AI agent can introspect a deployment
9
+ * (functions, global tables) and invoke its functions over HTTP RPC.
10
+ *
11
+ * Definitions and dispatch live here — separate from the server wiring — so the
12
+ * behaviour is unit-testable against a mock client without driving a transport.
13
+ */
14
+ /** A JSON-Schema object describing a tool's arguments, per the MCP spec. */
6
15
  interface ToolInputSchema {
7
16
  properties: Record<string, unknown>;
8
17
  required?: ReadonlyArray<string>;
@@ -13,6 +22,7 @@ interface ToolDefinition {
13
22
  inputSchema: ToolInputSchema;
14
23
  name: string;
15
24
  }
25
+ /** The MCP `CallToolResult` shape this server returns. */
16
26
  interface ToolResult {
17
27
  content: {
18
28
  text: string;
@@ -20,64 +30,205 @@ interface ToolResult {
20
30
  }[];
21
31
  isError?: boolean;
22
32
  }
33
+ /** The read-only tool surface: introspection + query. Always exposed. */
23
34
  declare const READ_ONLY_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
35
+ /** The write tool surface (mutations + actions). Exposed ONLY when writes are enabled. */
24
36
  declare const WRITE_TOOL_DEFINITIONS: ReadonlyArray<ToolDefinition>;
37
+ /**
38
+ * The tools this server advertises. When `allowWrites` is false (the default),
39
+ * only the read-only surface is exposed — the mutation/action tools are omitted
40
+ * from `ListTools` entirely, so an AI agent can't invoke a write it can't see.
41
+ */
25
42
  declare const toolDefinitions: (allowWrites: boolean) => ReadonlyArray<ToolDefinition>;
43
+ /**
44
+ * Dispatch a tool call against `client`. Unknown tools and thrown errors are
45
+ * returned as `isError` results (rather than rejections) so the calling model
46
+ * sees the failure as tool output, per the MCP convention.
47
+ *
48
+ * `allowWrites` gates the mutation/action tools: when false (the default) a call
49
+ * to a write tool is refused even if the client somehow names it, so the
50
+ * read-only guarantee holds at dispatch, not just in the advertised tool list.
51
+ */
26
52
  declare const callTool: (client: LunoraClient, name: string, input: Record<string, unknown>, allowWrites?: boolean) => Promise<ToolResult>;
53
+ /**
54
+ * Agent exposure for the MCP server: a durable `@lunora/agent` run fronted as an
55
+ * MCP tool an external agent can call. The capability boundary is the MCP-server
56
+ * process + its token, so WHICH agents are exposed is config on the server (like
57
+ * `allowWrites`), not on `defineAgent` — keeping `@lunora/agent` codegen
58
+ * byte-identical.
59
+ */
27
60
  interface McpAgentExposure {
61
+ /** What the agent does — shown to the calling model, which decides from it. */
28
62
  description: string;
63
+ /** The agent's export name (its `ctx.agents.&lt;name>` / `AGENT_&lt;NAME>` binding). */
29
64
  name: string;
65
+ /** Override the model-facing tool name (default `agent_&lt;name>`). */
30
66
  toolName?: string;
31
67
  }
68
+ /** The generic status/poll tool advertised alongside the per-agent tools. */
32
69
  declare const AGENT_STATUS_TOOL_NAME = "lunora_agent_status";
70
+ /**
71
+ * The uniform input schema every agent tool advertises. Agents share ONE run
72
+ * input (`@lunora/agent` has no per-agent validator), so there is nothing to
73
+ * derive per agent — a single static schema is reused for every agent tool.
74
+ */
33
75
  declare const AGENT_RUN_INPUT_SCHEMA: ToolInputSchema;
76
+ /**
77
+ * Parse `LUNORA_MCP_AGENTS` — a `;`-separated list of `name:description` pairs,
78
+ * e.g. `"support:Handles support questions;billing:Billing help"`. The
79
+ * description may itself contain colons (only the FIRST colon splits). Blank
80
+ * entries and entries with an empty name/description are skipped.
81
+ */
34
82
  declare const parseAgentsEnv: (raw: string | undefined) => McpAgentExposure[];
83
+ /**
84
+ * The tools this module advertises. Fail-closed: only the boolean `true` opts
85
+ * in (an env-plumbed caller could pass a truthy string), and the tools appear
86
+ * ONLY when at least one agent is exposed — so an agent-free or non-opted-in
87
+ * server never lists them.
88
+ */
35
89
  declare const agentToolDefinitions: (exposures: ReadonlyArray<McpAgentExposure>, allowAgents: boolean) => ReadonlyArray<ToolDefinition>;
90
+ /** Options threaded into a single agent tool dispatch. */
36
91
  interface CallAgentToolOptions {
92
+ /** Opt-in gate — must be exactly `true` or the call is refused fail-closed. */
37
93
  allowAgents: boolean;
94
+ /** The exposures advertised by this server. */
38
95
  exposures: ReadonlyArray<McpAgentExposure>;
96
+ /** Wall-clock budget a single call awaits before returning a pending result. */
39
97
  maxWaitMs?: number;
98
+ /** Delay between thread-status polls. */
40
99
  pollIntervalMs?: number;
100
+ /** Test seam replacing the between-poll wait; production uses a real timer. */
41
101
  wait?: (ms: number) => Promise<void>;
42
102
  }
103
+ /**
104
+ * Dispatch an agent tool call: start a durable run via `agents:agentRun`, then
105
+ * await-with-timeout — poll `agents:agentThread` until terminal (returning the
106
+ * final answer from `agents:agentMessages`) or, on budget exhaustion, return a
107
+ * NON-error pending payload the caller resumes with `lunora_agent_status`.
108
+ *
109
+ * Fail-closed: refused at dispatch unless `allowAgents === true`, mirroring the
110
+ * `allowWrites` guard — starting a run is a side effect and must not ride the
111
+ * read-only default.
112
+ */
43
113
  declare const callAgentTool: (client: LunoraClient, name: string, input: Record<string, unknown>, options: CallAgentToolOptions) => Promise<ToolResult>;
44
114
  interface LunoraMcpServerOptions {
115
+ /** Wall-clock budget a single agent tool call awaits before returning a pending result. */
45
116
  agentMaxWaitMs?: number;
117
+ /** Delay between agent thread-status polls. */
46
118
  agentPollIntervalMs?: number;
119
+ /** The agents this server fronts as MCP tools (see `allowAgents`). */
47
120
  agents?: ReadonlyArray<McpAgentExposure>;
121
+ /**
122
+ * Expose the per-agent tools (`agent_&lt;name>` + the generic
123
+ * `lunora_agent_status`). Defaults to `false`, mirroring `allowWrites`:
124
+ * starting a durable agent run is a side effect, so the agent tools are
125
+ * omitted from the advertised list AND refused at dispatch unless explicitly
126
+ * opted in. Only takes effect together with a non-empty `agents` list.
127
+ */
48
128
  allowAgents?: boolean;
129
+ /**
130
+ * Expose the write tools (`lunora_run_mutation` / `lunora_run_action`).
131
+ * Defaults to `false`: the server is READ-ONLY unless explicitly opted in,
132
+ * so a prompt-injected or misaligned agent can't mutate the deployment with
133
+ * the configured token. When false the write tools are omitted from the
134
+ * advertised tool list AND refused at dispatch.
135
+ */
49
136
  allowWrites?: boolean;
137
+ /**
138
+ * Pre-built client (test injection). When omitted a `LunoraClient` is
139
+ * created from `url`/`token`/`fetch`.
140
+ */
50
141
  client?: LunoraClient;
142
+ /** `fetch` implementation; defaults to the ambient global. */
51
143
  fetch?: typeof fetch;
144
+ /**
145
+ * Bearer token sent on every RPC. This must be the deployment's **admin
146
+ * bearer**: the introspection/allowlist path every tool depends on
147
+ * (`lunora_list_functions`, `lunora_list_tables`, and the `assertRunnable`
148
+ * precheck that runs before every `run` tool) hits admin-gated
149
+ * `/_lunora/admin/*` routes, so no scoped/app token works today — it would
150
+ * 403 (`ADMIN_FORBIDDEN`) on the first tool call. The read-only guarantee is
151
+ * therefore NOT enforced by the token's scope; it is enforced in-process via
152
+ * `allowWrites: false` (the default), which omits the write tools from the
153
+ * advertised list and refuses them at dispatch.
154
+ */
52
155
  token?: string;
156
+ /** Base URL of the deployed Lunora Worker. Required unless `client` is given. */
53
157
  url?: string;
54
158
  }
159
+ /**
160
+ * Build an MCP `Server` whose tools talk to a Lunora deployment. The server is
161
+ * transport-agnostic — call `.connect(transport)` yourself, or use
162
+ * `connectStdio` for the common stdio case.
163
+ *
164
+ * Tool calls are dispatched through `callTool`, which the deployment reaches
165
+ * over HTTP RPC. No WebSocket is opened (the tools never subscribe), so this is
166
+ * safe to run as a short-lived stdio process.
167
+ */
55
168
  declare const createLunoraMcpServer: (options: LunoraMcpServerOptions) => Server;
169
+ /**
170
+ * Build the server and connect it over stdio — the transport MCP clients use
171
+ * when they spawn the `lunora-mcp` binary. Resolves once the transport is
172
+ * connected; the process then stays alive serving requests.
173
+ */
56
174
  declare const connectStdio: (options: LunoraMcpServerOptions) => Promise<Server>;
175
+ /** A Web-Standard fetch handler: takes a `Request`, returns the MCP `Response`. */
57
176
  type McpFetchHandler = (request: Request) => Promise<Response>;
177
+ /**
178
+ * Build a stateless Streamable-HTTP fetch handler for a Lunora MCP server. Each
179
+ * invocation constructs a fresh proxy server and serves the request through
180
+ * {@link serveStateless}.
181
+ */
58
182
  declare const createMcpFetchHandler: (options: LunoraMcpServerOptions) => McpFetchHandler;
183
+ /** A tool handler: receives the call's `arguments` bag, returns an MCP tool result. */
59
184
  type ToolHandler = (arguments_: Record<string, unknown>) => Promise<ToolResult> | ToolResult;
185
+ /** Registration shape for a free tool. */
60
186
  interface RegisterToolOptions {
187
+ /** Optional MCP tool annotations (`readOnlyHint`, `title`, …). */
61
188
  annotations?: Tool["annotations"];
189
+ /** Human/model-facing description of what the tool does. */
62
190
  description: string;
191
+ /** JSON-Schema object describing the tool's arguments. */
63
192
  inputSchema: ToolInputSchema;
193
+ /** Unique tool name (the MCP `tools/call` `name`). */
64
194
  name: string;
65
195
  }
196
+ /** Registration shape for a paid tool: a {@link RegisterToolOptions} plus its USD price. */
66
197
  interface RegisterPaidToolOptions extends RegisterToolOptions {
198
+ /** USD price per call (e.g. `"$0.05"`), charged via x402 before dispatch. */
67
199
  price: X402Price;
68
200
  }
201
+ /** x402 settlement vocabulary shared by every paid tool (network, recipient, facilitator); price is per-tool. */
69
202
  type PaidMcpChargeConfig = Omit<X402ChargeConfig, "price">;
203
+ /** Config for `createPaidMcpServer`. */
70
204
  interface PaidMcpServerConfig {
205
+ /** The worker-level x402 charge config; each paid tool supplies only its own `price`. */
71
206
  charge: PaidMcpChargeConfig;
207
+ /** Name/version advertised in the MCP `initialize` handshake. Defaults to `lunora-paid-mcp`. */
72
208
  serverInfo?: {
73
209
  name: string;
74
210
  version: string;
75
211
  };
76
212
  }
213
+ /** A paid MCP server: register free/paid tools, then serve over Streamable HTTP. */
77
214
  interface PaidMcpServer {
215
+ /** The Streamable-HTTP fetch handler; gates each paid `tools/call` behind x402. */
78
216
  readonly fetchHandler: McpFetchHandler;
217
+ /** Register a **paid** tool: its dispatch runs the x402 charge middleware first. */
79
218
  paidTool: (options: RegisterPaidToolOptions, handler: ToolHandler) => void;
219
+ /** Register a **free** tool (coexists with paid tools on the same server). */
80
220
  tool: (options: RegisterToolOptions, handler: ToolHandler) => void;
81
221
  }
222
+ /**
223
+ * Create a paid MCP server. Register free tools with `tool()` and priced tools
224
+ * with `paidTool()` (they coexist), then serve `fetchHandler` over HTTP.
225
+ *
226
+ * The server is **stateless**: `fetchHandler` builds a fresh `Server` per
227
+ * request (reading the live tool registry), so tools registered before the
228
+ * first request are all visible. Each priced tool memoises one initialised
229
+ * `ChargeMiddleware` (keyed by tool name, baking that tool's price and naming
230
+ * the tool as the challenge `resource`); a failed init is not cached, so a
231
+ * transient facilitator outage retries on the next call.
232
+ */
82
233
  declare const createPaidMcpServer: (config: PaidMcpServerConfig) => PaidMcpServer;
83
234
  export { AGENT_RUN_INPUT_SCHEMA, AGENT_STATUS_TOOL_NAME, type CallAgentToolOptions, type LunoraMcpServerOptions, type McpAgentExposure, type McpFetchHandler, 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, connectStdio, createLunoraMcpServer, createMcpFetchHandler, createPaidMcpServer, parseAgentsEnv, toolDefinitions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/mcp",
3
- "version": "1.0.0-alpha.26",
3
+ "version": "1.0.0-alpha.28",
4
4
  "description": "Model Context Protocol server exposing a Lunora deployment to AI agents",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -49,9 +49,9 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@lunora/client": "1.0.0-alpha.24",
53
- "@lunora/errors": "1.0.0-alpha.5",
54
- "@lunora/x402": "1.0.0-alpha.4",
52
+ "@lunora/client": "1.0.0-alpha.26",
53
+ "@lunora/errors": "1.0.0-alpha.6",
54
+ "@lunora/x402": "1.0.0-alpha.5",
55
55
  "@modelcontextprotocol/sdk": "^1.29.0"
56
56
  },
57
57
  "engines": {