lurqrun 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +311 -139
  2. package/dist/auditHandler-VWCXSDVO.js +24 -0
  3. package/dist/autopilotInit-Q62MX5M6.js +178 -0
  4. package/dist/bin/lurq.js +3255 -23319
  5. package/dist/browserAuth-J7APSD4P.js +96 -0
  6. package/dist/cache-AEAKCV4I.js +12 -0
  7. package/dist/check-2JTQDQA6.js +2613 -0
  8. package/dist/check-PQSQ2MMA.js +192 -0
  9. package/dist/checkUpgrade-5YW77OBL.js +24 -0
  10. package/dist/chunk-2GAYNIHG.js +40 -0
  11. package/dist/chunk-2O6Z37IT.js +423 -0
  12. package/dist/chunk-2WD4QAH4.js +116 -0
  13. package/dist/chunk-3676XOBU.js +2235 -0
  14. package/dist/chunk-3D2MPGOQ.js +181 -0
  15. package/dist/chunk-3GHJR7XR.js +2049 -0
  16. package/dist/chunk-4ESO33J6.js +34 -0
  17. package/dist/chunk-4JHDSVIN.js +1229 -0
  18. package/dist/chunk-4KCPOMG6.js +68 -0
  19. package/dist/chunk-53SG6XWA.js +141 -0
  20. package/dist/chunk-5ABNDB3I.js +37 -0
  21. package/dist/chunk-5ALIJFDA.js +114 -0
  22. package/dist/chunk-63MUJNZL.js +318 -0
  23. package/dist/chunk-64ZF7KO4.js +1571 -0
  24. package/dist/chunk-6DM6UQFD.js +318 -0
  25. package/dist/chunk-6EQ3ARXA.js +304 -0
  26. package/dist/chunk-6L67QMCP.js +92 -0
  27. package/dist/chunk-72Y2FDVS.js +172 -0
  28. package/dist/chunk-A3TYI2TF.js +288 -0
  29. package/dist/chunk-B2UUYRBX.js +536 -0
  30. package/dist/chunk-BJT2LHAR.js +320 -0
  31. package/dist/chunk-BM3LF5T6.js +132 -0
  32. package/dist/chunk-BN3NM47Q.js +214 -0
  33. package/dist/chunk-BUALU27S.js +123 -0
  34. package/dist/chunk-C6GLE626.js +160 -0
  35. package/dist/chunk-D3K6IZVR.js +12845 -0
  36. package/dist/chunk-D3VTZS7V.js +222 -0
  37. package/dist/chunk-DM37MTOO.js +636 -0
  38. package/dist/chunk-DONTW3NE.js +171 -0
  39. package/dist/chunk-DSROTZ3Z.js +38 -0
  40. package/dist/chunk-ELGCAM7P.js +184 -0
  41. package/dist/chunk-EQCXENKZ.js +130 -0
  42. package/dist/chunk-EYAKM6YN.js +96 -0
  43. package/dist/chunk-FDFPMBCA.js +112 -0
  44. package/dist/chunk-FVYFV5HA.js +154 -0
  45. package/dist/chunk-GE37NVLN.js +15 -0
  46. package/dist/chunk-GM5Y555O.js +143 -0
  47. package/dist/chunk-GRJXQBQZ.js +793 -0
  48. package/dist/chunk-HWFX4BC4.js +177 -0
  49. package/dist/chunk-I3M2KJXB.js +56 -0
  50. package/dist/chunk-IFNONGRQ.js +603 -0
  51. package/dist/chunk-J3U2CPSK.js +136 -0
  52. package/dist/chunk-J6XQ7OPZ.js +74 -0
  53. package/dist/chunk-KMV4Y6R3.js +127 -0
  54. package/dist/chunk-KP5ZDDPE.js +340 -0
  55. package/dist/chunk-KYKSZ3XZ.js +202 -0
  56. package/dist/chunk-LEGPB7DO.js +81 -0
  57. package/dist/chunk-LUAKDHLZ.js +40 -0
  58. package/dist/chunk-MHUEVBVO.js +35 -0
  59. package/dist/chunk-MYGSLK44.js +37 -0
  60. package/dist/chunk-NEZNAPPN.js +41 -0
  61. package/dist/chunk-NPVN2THM.js +197 -0
  62. package/dist/chunk-NYZU5NCW.js +23 -0
  63. package/dist/chunk-O4KHCV6I.js +320 -0
  64. package/dist/chunk-ONDVTXUO.js +240 -0
  65. package/dist/chunk-OTJFHESY.js +176 -0
  66. package/dist/chunk-P6MIKSPY.js +243 -0
  67. package/dist/chunk-Q5VPF4WI.js +26 -0
  68. package/dist/chunk-QCRBX3LV.js +165 -0
  69. package/dist/chunk-QKGYDMWB.js +7409 -0
  70. package/dist/chunk-QSL6QN5X.js +115 -0
  71. package/dist/chunk-QUIMQ7YL.js +73 -0
  72. package/dist/chunk-RG3YLU6E.js +49 -0
  73. package/dist/chunk-SHCEBP3J.js +107 -0
  74. package/dist/chunk-SHZFOSXC.js +462 -0
  75. package/dist/chunk-SOXFMMXC.js +151 -0
  76. package/dist/chunk-TDTYV6QI.js +119 -0
  77. package/dist/chunk-TNTXWSYA.js +19 -0
  78. package/dist/chunk-TUXQ32WE.js +2251 -0
  79. package/dist/chunk-VGCDRK3S.js +37 -0
  80. package/dist/chunk-VLRHFMGJ.js +58 -0
  81. package/dist/chunk-WHX2ZFCG.js +4048 -0
  82. package/dist/chunk-X4W64MHU.js +2005 -0
  83. package/dist/chunk-XBQA4I36.js +92 -0
  84. package/dist/chunk-XGOV6KV4.js +413 -0
  85. package/dist/chunk-XIFQIFSZ.js +940 -0
  86. package/dist/chunk-XLXPVN3Y.js +15393 -0
  87. package/dist/chunk-ZJMLQ37G.js +90 -0
  88. package/dist/client-MU4EUDZV.js +15 -0
  89. package/dist/commands-UOOTMBKA.js +1023 -0
  90. package/dist/compat-Q5DVPITN.js +201 -0
  91. package/dist/constants-DJFOFZ44.js +24 -0
  92. package/dist/dashboardIssue-KBKLQMGC.js +274 -0
  93. package/dist/diff-I4SNUHU3.js +13 -0
  94. package/dist/dist-4XXIXHHZ.js +12945 -0
  95. package/dist/domains-VRT4BRVZ.js +14 -0
  96. package/dist/e2b-FVPHDULZ.js +172 -0
  97. package/dist/env-UN6KGZ7S.js +15 -0
  98. package/dist/envCheck-KUPTORFQ.js +71 -0
  99. package/dist/extract-6WG265BL.js +455 -0
  100. package/dist/fetch-PJ3SC32M.js +22 -0
  101. package/dist/firstTouch-COJCMOB3.js +55 -0
  102. package/dist/fix-3EDWNKW3.js +220 -0
  103. package/dist/handlers-4Q37WIFT.js +55 -0
  104. package/dist/hook-NA66XJLC.js +412 -0
  105. package/dist/http-25GJ6SKK.js +6928 -0
  106. package/dist/ingestQueue-FSVJC3AA.js +37 -0
  107. package/dist/install-G2HHXYJ2.js +20 -0
  108. package/dist/installSkill-5TIMYIJZ.js +70 -0
  109. package/dist/inventory-5AWSLJYU.js +31 -0
  110. package/dist/local-XPZMRH5R.js +13 -0
  111. package/dist/manifest-ENMIC54B.js +13 -0
  112. package/dist/mcp-PENLL2PK.js +500 -0
  113. package/dist/mcpConfig-3LYPRY5Q.js +80 -0
  114. package/dist/mcpHandlers-PO7GENA7.js +22 -0
  115. package/dist/mcpScan-ULP626TQ.js +1735 -0
  116. package/dist/mcpScanWorkflow-27O44FOE.js +98 -0
  117. package/dist/mcpStack-ZNYIFXZ5.js +20 -0
  118. package/dist/model-ASMZWLM7.js +214 -0
  119. package/dist/packages-RWF2LXST.js +40 -0
  120. package/dist/plan-SDILIDZT.js +465 -0
  121. package/dist/planView-ZAKRTGVS.js +82 -0
  122. package/dist/policy-JAGNMQJI.js +115 -0
  123. package/dist/probe-3IK646WN.js +610 -0
  124. package/dist/publicUpgrades-WTBGLDIK.js +42 -0
  125. package/dist/references-I6Y4BSRR.js +16 -0
  126. package/dist/release-7IU2R4YG.js +128 -0
  127. package/dist/remote-FN6225AH.js +42 -0
  128. package/dist/rename-OS6JYBZQ.js +204 -0
  129. package/dist/reportRuns-O4X7ZFTX.js +77 -0
  130. package/dist/safeFetch-COERXGFN.js +19 -0
  131. package/dist/sandbox-SAPSRKEI.js +39 -0
  132. package/dist/sarif-WLVJFJ7U.js +125 -0
  133. package/dist/server-OLTY3NYT.js +59 -0
  134. package/dist/surface-7MHE3RL7.js +143 -0
  135. package/dist/surface-JS2XU3U3.js +38 -0
  136. package/dist/surfaceHandlers-4B6TMZ34.js +20 -0
  137. package/dist/typecheck-NGOKNAJY.js +282 -0
  138. package/dist/types-M5JP2W3D.js +10 -0
  139. package/dist/uninstall-I2IJP5JZ.js +200 -0
  140. package/dist/upgrade-FS26DJGG.js +650 -0
  141. package/dist/upgradePlan-ZS5IOVMZ.js +181 -0
  142. package/dist/upkeepHandler-VFGYXJKB.js +13 -0
  143. package/dist/userConfig-ICASHI47.js +20 -0
  144. package/dist/watch-OCNEUXG6.js +204 -0
  145. package/package.json +26 -20
  146. package/templates/agent-rules.md +4 -4
  147. package/templates/skill-instructions.md +35 -17
  148. package/dist/bin/lurq.js.map +0 -1
  149. package/dist/index.d.ts +0 -805
  150. package/dist/index.js +0 -23570
  151. package/dist/index.js.map +0 -1
  152. package/drizzle/0000_confused_fabian_cortez.sql +0 -54
  153. package/drizzle/0001_aspiring_timeslip.sql +0 -15
  154. package/drizzle/0002_lyrical_lila_cheney.sql +0 -14
  155. package/drizzle/0003_violet_giant_girl.sql +0 -14
  156. package/drizzle/0004_slim_valeria_richards.sql +0 -15
  157. package/drizzle/0005_petite_luke_cage.sql +0 -12
  158. package/drizzle/0006_calm_nighthawk.sql +0 -3
  159. package/drizzle/0007_slimy_naoko.sql +0 -1
  160. package/drizzle/0008_peaceful_tigra.sql +0 -1
  161. package/drizzle/0009_smooth_harrier.sql +0 -10
  162. package/drizzle/0010_curved_amphibian.sql +0 -2
  163. package/drizzle/0011_compat_provenance_closures.sql +0 -11
  164. package/drizzle/0012_api_surfaces.sql +0 -9
  165. package/drizzle/0013_nice_thanos.sql +0 -1
  166. package/drizzle/0014_luxuriant_malcolm_colcord.sql +0 -10
  167. package/drizzle/0015_past_fat_cobra.sql +0 -11
  168. package/drizzle/0016_futuristic_junta.sql +0 -50
  169. package/drizzle/0017_absent_grandmaster.sql +0 -20
  170. package/drizzle/0018_rainy_proemial_gods.sql +0 -1
  171. package/drizzle/0019_dashing_korvac.sql +0 -11
  172. package/drizzle/0020_normal_vulture.sql +0 -3
  173. package/drizzle/0021_dazzling_blue_shield.sql +0 -17
  174. package/drizzle/0022_massive_ghost_rider.sql +0 -24
  175. package/drizzle/0023_next_shatterstar.sql +0 -1
  176. package/drizzle/0024_dusty_maelstrom.sql +0 -15
  177. package/drizzle/0025_gifted_harpoon.sql +0 -5
  178. package/drizzle/0026_awesome_mordo.sql +0 -1
  179. package/drizzle/0027_charming_ulik.sql +0 -2
  180. package/drizzle/0028_romantic_loners.sql +0 -2
  181. package/drizzle/0029_busy_korvac.sql +0 -16
  182. package/drizzle/0030_steady_mathemanic.sql +0 -6
  183. package/drizzle/0031_redundant_maginty.sql +0 -2
  184. package/drizzle/0032_stack_resolutions.sql +0 -14
  185. package/drizzle/0033_graceful_tyger_tiger.sql +0 -3
  186. package/drizzle/0034_uneven_thunderbird.sql +0 -1
  187. package/drizzle/0035_api_key_scopes.sql +0 -1
  188. package/drizzle/0036_policy_audit.sql +0 -21
  189. package/drizzle/0037_subscription_seats.sql +0 -1
  190. package/drizzle/0038_symbol_offsets.sql +0 -2
  191. package/drizzle/0039_mcp_runtime_scans.sql +0 -80
  192. package/drizzle/0040_subscription_overage_and_interval.sql +0 -4
  193. package/drizzle/0041_account_email.sql +0 -38
  194. package/drizzle/0042_alert_channels.sql +0 -21
  195. package/drizzle/meta/0000_snapshot.json +0 -370
  196. package/drizzle/meta/0001_snapshot.json +0 -482
  197. package/drizzle/meta/0002_snapshot.json +0 -575
  198. package/drizzle/meta/0003_snapshot.json +0 -667
  199. package/drizzle/meta/0004_snapshot.json +0 -769
  200. package/drizzle/meta/0005_snapshot.json +0 -864
  201. package/drizzle/meta/0006_snapshot.json +0 -882
  202. package/drizzle/meta/0007_snapshot.json +0 -876
  203. package/drizzle/meta/0008_snapshot.json +0 -882
  204. package/drizzle/meta/0009_snapshot.json +0 -948
  205. package/drizzle/meta/0010_snapshot.json +0 -969
  206. package/drizzle/meta/0011_snapshot.json +0 -1049
  207. package/drizzle/meta/0012_snapshot.json +0 -1115
  208. package/drizzle/meta/0013_snapshot.json +0 -1121
  209. package/drizzle/meta/0014_snapshot.json +0 -1190
  210. package/drizzle/meta/0015_snapshot.json +0 -1280
  211. package/drizzle/meta/0016_snapshot.json +0 -1683
  212. package/drizzle/meta/0017_snapshot.json +0 -1834
  213. package/drizzle/meta/0018_snapshot.json +0 -1834
  214. package/drizzle/meta/0019_snapshot.json +0 -1909
  215. package/drizzle/meta/0020_snapshot.json +0 -1921
  216. package/drizzle/meta/0021_snapshot.json +0 -2045
  217. package/drizzle/meta/0022_snapshot.json +0 -2246
  218. package/drizzle/meta/0023_snapshot.json +0 -2252
  219. package/drizzle/meta/0024_snapshot.json +0 -2375
  220. package/drizzle/meta/0025_snapshot.json +0 -2407
  221. package/drizzle/meta/0026_snapshot.json +0 -2413
  222. package/drizzle/meta/0027_snapshot.json +0 -2425
  223. package/drizzle/meta/0028_snapshot.json +0 -2438
  224. package/drizzle/meta/0029_snapshot.json +0 -2546
  225. package/drizzle/meta/0030_snapshot.json +0 -2586
  226. package/drizzle/meta/0031_snapshot.json +0 -2598
  227. package/drizzle/meta/0032_snapshot.json +0 -2699
  228. package/drizzle/meta/0033_snapshot.json +0 -2712
  229. package/drizzle/meta/0034_snapshot.json +0 -2719
  230. package/drizzle/meta/0035_snapshot.json +0 -2726
  231. package/drizzle/meta/0036_snapshot.json +0 -2876
  232. package/drizzle/meta/0037_snapshot.json +0 -2883
  233. package/drizzle/meta/0038_snapshot.json +0 -2895
  234. package/drizzle/meta/0039_snapshot.json +0 -3501
  235. package/drizzle/meta/0040_snapshot.json +0 -3527
  236. package/drizzle/meta/0041_snapshot.json +0 -3824
  237. package/drizzle/meta/0042_snapshot.json +0 -3960
  238. package/drizzle/meta/_journal.json +0 -307
  239. package/src/data/seed.json +0 -253
@@ -0,0 +1,2235 @@
1
+ import { createRequire as __lurqCreateRequire } from 'node:module'; const require = __lurqCreateRequire(import.meta.url);
2
+ import {
3
+ handleAudit
4
+ } from "./chunk-B2UUYRBX.js";
5
+ import {
6
+ ReadBuffer,
7
+ serializeMessage
8
+ } from "./chunk-NEZNAPPN.js";
9
+ import {
10
+ searchCapabilities
11
+ } from "./chunk-KP5ZDDPE.js";
12
+ import {
13
+ handleMcpDrift,
14
+ handleMcpSurface
15
+ } from "./chunk-BN3NM47Q.js";
16
+ import {
17
+ handleDiffSurface,
18
+ handleResolveSurface
19
+ } from "./chunk-BJT2LHAR.js";
20
+ import {
21
+ AjvJsonSchemaValidator,
22
+ Protocol,
23
+ assertClientRequestTaskCapability,
24
+ assertToolsCallTaskCapability,
25
+ getLiteralValue,
26
+ getObjectShape,
27
+ getParseErrorMessage,
28
+ getSchemaDescription,
29
+ isSchemaOptional,
30
+ isZ4Schema,
31
+ mergeCapabilities,
32
+ normalizeObjectSchema,
33
+ objectFromShape,
34
+ safeParse,
35
+ safeParseAsync,
36
+ toJsonSchemaCompat
37
+ } from "./chunk-XLXPVN3Y.js";
38
+ import {
39
+ CallToolRequestSchema,
40
+ CallToolResultSchema,
41
+ CompleteRequestSchema,
42
+ CreateMessageResultSchema,
43
+ CreateMessageResultWithToolsSchema,
44
+ CreateTaskResultSchema,
45
+ ElicitResultSchema,
46
+ EmptyResultSchema,
47
+ ErrorCode,
48
+ GetPromptRequestSchema,
49
+ InitializeRequestSchema,
50
+ InitializedNotificationSchema,
51
+ LATEST_PROTOCOL_VERSION,
52
+ ListPromptsRequestSchema,
53
+ ListResourceTemplatesRequestSchema,
54
+ ListResourcesRequestSchema,
55
+ ListRootsResultSchema,
56
+ ListToolsRequestSchema,
57
+ LoggingLevelSchema,
58
+ McpError,
59
+ ReadResourceRequestSchema,
60
+ SUPPORTED_PROTOCOL_VERSIONS,
61
+ SetLevelRequestSchema,
62
+ assertCompleteRequestPrompt,
63
+ assertCompleteRequestResourceTemplate
64
+ } from "./chunk-D3K6IZVR.js";
65
+ import {
66
+ handleDiagram
67
+ } from "./chunk-EQCXENKZ.js";
68
+ import {
69
+ handleCompare,
70
+ handleCompat,
71
+ handleEvaluate,
72
+ handlePolicy,
73
+ handleReportOutcome,
74
+ handleUsage,
75
+ handleVerify
76
+ } from "./chunk-64ZF7KO4.js";
77
+ import {
78
+ createDb
79
+ } from "./chunk-VGCDRK3S.js";
80
+ import {
81
+ ownerUsageDaily
82
+ } from "./chunk-4JHDSVIN.js";
83
+ import {
84
+ require_semver
85
+ } from "./chunk-3GHJR7XR.js";
86
+ import {
87
+ external_exports,
88
+ getConfig
89
+ } from "./chunk-GRJXQBQZ.js";
90
+ import {
91
+ ZodOptional
92
+ } from "./chunk-WHX2ZFCG.js";
93
+ import {
94
+ logger
95
+ } from "./chunk-MYGSLK44.js";
96
+ import {
97
+ SERVER_NAME,
98
+ VERSION
99
+ } from "./chunk-72Y2FDVS.js";
100
+ import {
101
+ __toESM,
102
+ init_esm_shims
103
+ } from "./chunk-I3M2KJXB.js";
104
+
105
+ // src/mcp/server.ts
106
+ init_esm_shims();
107
+
108
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
109
+ init_esm_shims();
110
+
111
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
112
+ init_esm_shims();
113
+
114
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
115
+ init_esm_shims();
116
+ var ExperimentalServerTasks = class {
117
+ constructor(_server) {
118
+ this._server = _server;
119
+ }
120
+ /**
121
+ * Sends a request and returns an AsyncGenerator that yields response messages.
122
+ * The generator is guaranteed to end with either a 'result' or 'error' message.
123
+ *
124
+ * This method provides streaming access to request processing, allowing you to
125
+ * observe intermediate task status updates for task-augmented requests.
126
+ *
127
+ * @param request - The request to send
128
+ * @param resultSchema - Zod schema for validating the result
129
+ * @param options - Optional request options (timeout, signal, task creation params, etc.)
130
+ * @returns AsyncGenerator that yields ResponseMessage objects
131
+ *
132
+ * @experimental
133
+ */
134
+ requestStream(request, resultSchema, options) {
135
+ return this._server.requestStream(request, resultSchema, options);
136
+ }
137
+ /**
138
+ * Sends a sampling request and returns an AsyncGenerator that yields response messages.
139
+ * The generator is guaranteed to end with either a 'result' or 'error' message.
140
+ *
141
+ * For task-augmented requests, yields 'taskCreated' and 'taskStatus' messages
142
+ * before the final result.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const stream = server.experimental.tasks.createMessageStream({
147
+ * messages: [{ role: 'user', content: { type: 'text', text: 'Hello' } }],
148
+ * maxTokens: 100
149
+ * }, {
150
+ * onprogress: (progress) => {
151
+ * // Handle streaming tokens via progress notifications
152
+ * console.log('Progress:', progress.message);
153
+ * }
154
+ * });
155
+ *
156
+ * for await (const message of stream) {
157
+ * switch (message.type) {
158
+ * case 'taskCreated':
159
+ * console.log('Task created:', message.task.taskId);
160
+ * break;
161
+ * case 'taskStatus':
162
+ * console.log('Task status:', message.task.status);
163
+ * break;
164
+ * case 'result':
165
+ * console.log('Final result:', message.result);
166
+ * break;
167
+ * case 'error':
168
+ * console.error('Error:', message.error);
169
+ * break;
170
+ * }
171
+ * }
172
+ * ```
173
+ *
174
+ * @param params - The sampling request parameters
175
+ * @param options - Optional request options (timeout, signal, task creation params, onprogress, etc.)
176
+ * @returns AsyncGenerator that yields ResponseMessage objects
177
+ *
178
+ * @experimental
179
+ */
180
+ createMessageStream(params, options) {
181
+ const clientCapabilities = this._server.getClientCapabilities();
182
+ if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
183
+ throw new Error("Client does not support sampling tools capability.");
184
+ }
185
+ if (params.messages.length > 0) {
186
+ const lastMessage = params.messages[params.messages.length - 1];
187
+ const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
188
+ const hasToolResults = lastContent.some((c) => c.type === "tool_result");
189
+ const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : void 0;
190
+ const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
191
+ const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
192
+ if (hasToolResults) {
193
+ if (lastContent.some((c) => c.type !== "tool_result")) {
194
+ throw new Error("The last message must contain only tool_result content if any is present");
195
+ }
196
+ if (!hasPreviousToolUse) {
197
+ throw new Error("tool_result blocks are not matching any tool_use from the previous message");
198
+ }
199
+ }
200
+ if (hasPreviousToolUse) {
201
+ const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
202
+ const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
203
+ if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
204
+ throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
205
+ }
206
+ }
207
+ }
208
+ return this.requestStream({
209
+ method: "sampling/createMessage",
210
+ params
211
+ }, CreateMessageResultSchema, options);
212
+ }
213
+ /**
214
+ * Sends an elicitation request and returns an AsyncGenerator that yields response messages.
215
+ * The generator is guaranteed to end with either a 'result' or 'error' message.
216
+ *
217
+ * For task-augmented requests (especially URL-based elicitation), yields 'taskCreated'
218
+ * and 'taskStatus' messages before the final result.
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const stream = server.experimental.tasks.elicitInputStream({
223
+ * mode: 'url',
224
+ * message: 'Please authenticate',
225
+ * elicitationId: 'auth-123',
226
+ * url: 'https://example.com/auth'
227
+ * }, {
228
+ * task: { ttl: 300000 } // Task-augmented for long-running auth flow
229
+ * });
230
+ *
231
+ * for await (const message of stream) {
232
+ * switch (message.type) {
233
+ * case 'taskCreated':
234
+ * console.log('Task created:', message.task.taskId);
235
+ * break;
236
+ * case 'taskStatus':
237
+ * console.log('Task status:', message.task.status);
238
+ * break;
239
+ * case 'result':
240
+ * console.log('User action:', message.result.action);
241
+ * break;
242
+ * case 'error':
243
+ * console.error('Error:', message.error);
244
+ * break;
245
+ * }
246
+ * }
247
+ * ```
248
+ *
249
+ * @param params - The elicitation request parameters
250
+ * @param options - Optional request options (timeout, signal, task creation params, etc.)
251
+ * @returns AsyncGenerator that yields ResponseMessage objects
252
+ *
253
+ * @experimental
254
+ */
255
+ elicitInputStream(params, options) {
256
+ const clientCapabilities = this._server.getClientCapabilities();
257
+ const mode = params.mode ?? "form";
258
+ switch (mode) {
259
+ case "url": {
260
+ if (!clientCapabilities?.elicitation?.url) {
261
+ throw new Error("Client does not support url elicitation.");
262
+ }
263
+ break;
264
+ }
265
+ case "form": {
266
+ if (!clientCapabilities?.elicitation?.form) {
267
+ throw new Error("Client does not support form elicitation.");
268
+ }
269
+ break;
270
+ }
271
+ }
272
+ const normalizedParams = mode === "form" && params.mode === void 0 ? { ...params, mode: "form" } : params;
273
+ return this.requestStream({
274
+ method: "elicitation/create",
275
+ params: normalizedParams
276
+ }, ElicitResultSchema, options);
277
+ }
278
+ /**
279
+ * Gets the current status of a task.
280
+ *
281
+ * @param taskId - The task identifier
282
+ * @param options - Optional request options
283
+ * @returns The task status
284
+ *
285
+ * @experimental
286
+ */
287
+ async getTask(taskId, options) {
288
+ return this._server.getTask({ taskId }, options);
289
+ }
290
+ /**
291
+ * Retrieves the result of a completed task.
292
+ *
293
+ * @param taskId - The task identifier
294
+ * @param resultSchema - Zod schema for validating the result
295
+ * @param options - Optional request options
296
+ * @returns The task result
297
+ *
298
+ * @experimental
299
+ */
300
+ async getTaskResult(taskId, resultSchema, options) {
301
+ return this._server.getTaskResult({ taskId }, resultSchema, options);
302
+ }
303
+ /**
304
+ * Lists tasks with optional pagination.
305
+ *
306
+ * @param cursor - Optional pagination cursor
307
+ * @param options - Optional request options
308
+ * @returns List of tasks with optional next cursor
309
+ *
310
+ * @experimental
311
+ */
312
+ async listTasks(cursor, options) {
313
+ return this._server.listTasks(cursor ? { cursor } : void 0, options);
314
+ }
315
+ /**
316
+ * Cancels a running task.
317
+ *
318
+ * @param taskId - The task identifier
319
+ * @param options - Optional request options
320
+ *
321
+ * @experimental
322
+ */
323
+ async cancelTask(taskId, options) {
324
+ return this._server.cancelTask({ taskId }, options);
325
+ }
326
+ };
327
+
328
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
329
+ var Server = class extends Protocol {
330
+ /**
331
+ * Initializes this server with the given name and version information.
332
+ */
333
+ constructor(_serverInfo, options) {
334
+ super(options);
335
+ this._serverInfo = _serverInfo;
336
+ this._loggingLevels = /* @__PURE__ */ new Map();
337
+ this.LOG_LEVEL_SEVERITY = new Map(LoggingLevelSchema.options.map((level, index) => [level, index]));
338
+ this.isMessageIgnored = (level, sessionId) => {
339
+ const currentLevel = this._loggingLevels.get(sessionId);
340
+ return currentLevel ? this.LOG_LEVEL_SEVERITY.get(level) < this.LOG_LEVEL_SEVERITY.get(currentLevel) : false;
341
+ };
342
+ this._capabilities = options?.capabilities ?? {};
343
+ this._instructions = options?.instructions;
344
+ this._jsonSchemaValidator = options?.jsonSchemaValidator ?? new AjvJsonSchemaValidator();
345
+ this.setRequestHandler(InitializeRequestSchema, (request) => this._oninitialize(request));
346
+ this.setNotificationHandler(InitializedNotificationSchema, () => this.oninitialized?.());
347
+ if (this._capabilities.logging) {
348
+ this.setRequestHandler(SetLevelRequestSchema, async (request, extra) => {
349
+ const transportSessionId = extra.sessionId || extra.requestInfo?.headers["mcp-session-id"] || void 0;
350
+ const { level } = request.params;
351
+ const parseResult = LoggingLevelSchema.safeParse(level);
352
+ if (parseResult.success) {
353
+ this._loggingLevels.set(transportSessionId, parseResult.data);
354
+ }
355
+ return {};
356
+ });
357
+ }
358
+ }
359
+ /**
360
+ * Access experimental features.
361
+ *
362
+ * WARNING: These APIs are experimental and may change without notice.
363
+ *
364
+ * @experimental
365
+ */
366
+ get experimental() {
367
+ if (!this._experimental) {
368
+ this._experimental = {
369
+ tasks: new ExperimentalServerTasks(this)
370
+ };
371
+ }
372
+ return this._experimental;
373
+ }
374
+ /**
375
+ * Registers new capabilities. This can only be called before connecting to a transport.
376
+ *
377
+ * The new capabilities will be merged with any existing capabilities previously given (e.g., at initialization).
378
+ */
379
+ registerCapabilities(capabilities) {
380
+ if (this.transport) {
381
+ throw new Error("Cannot register capabilities after connecting to transport");
382
+ }
383
+ this._capabilities = mergeCapabilities(this._capabilities, capabilities);
384
+ }
385
+ /**
386
+ * Override request handler registration to enforce server-side validation for tools/call.
387
+ */
388
+ setRequestHandler(requestSchema, handler) {
389
+ const shape = getObjectShape(requestSchema);
390
+ const methodSchema = shape?.method;
391
+ if (!methodSchema) {
392
+ throw new Error("Schema is missing a method literal");
393
+ }
394
+ let methodValue;
395
+ if (isZ4Schema(methodSchema)) {
396
+ const v4Schema = methodSchema;
397
+ const v4Def = v4Schema._zod?.def;
398
+ methodValue = v4Def?.value ?? v4Schema.value;
399
+ } else {
400
+ const v3Schema = methodSchema;
401
+ const legacyDef = v3Schema._def;
402
+ methodValue = legacyDef?.value ?? v3Schema.value;
403
+ }
404
+ if (typeof methodValue !== "string") {
405
+ throw new Error("Schema method literal must be a string");
406
+ }
407
+ const method = methodValue;
408
+ if (method === "tools/call") {
409
+ const wrappedHandler = async (request, extra) => {
410
+ const validatedRequest = safeParse(CallToolRequestSchema, request);
411
+ if (!validatedRequest.success) {
412
+ const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
413
+ throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
414
+ }
415
+ const { params } = validatedRequest.data;
416
+ const result = await Promise.resolve(handler(request, extra));
417
+ if (params.task) {
418
+ const taskValidationResult = safeParse(CreateTaskResultSchema, result);
419
+ if (!taskValidationResult.success) {
420
+ const errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
421
+ throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
422
+ }
423
+ return taskValidationResult.data;
424
+ }
425
+ const validationResult = safeParse(CallToolResultSchema, result);
426
+ if (!validationResult.success) {
427
+ const errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
428
+ throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
429
+ }
430
+ return validationResult.data;
431
+ };
432
+ return super.setRequestHandler(requestSchema, wrappedHandler);
433
+ }
434
+ return super.setRequestHandler(requestSchema, handler);
435
+ }
436
+ assertCapabilityForMethod(method) {
437
+ switch (method) {
438
+ case "sampling/createMessage":
439
+ if (!this._clientCapabilities?.sampling) {
440
+ throw new Error(`Client does not support sampling (required for ${method})`);
441
+ }
442
+ break;
443
+ case "elicitation/create":
444
+ if (!this._clientCapabilities?.elicitation) {
445
+ throw new Error(`Client does not support elicitation (required for ${method})`);
446
+ }
447
+ break;
448
+ case "roots/list":
449
+ if (!this._clientCapabilities?.roots) {
450
+ throw new Error(`Client does not support listing roots (required for ${method})`);
451
+ }
452
+ break;
453
+ case "ping":
454
+ break;
455
+ }
456
+ }
457
+ assertNotificationCapability(method) {
458
+ switch (method) {
459
+ case "notifications/message":
460
+ if (!this._capabilities.logging) {
461
+ throw new Error(`Server does not support logging (required for ${method})`);
462
+ }
463
+ break;
464
+ case "notifications/resources/updated":
465
+ case "notifications/resources/list_changed":
466
+ if (!this._capabilities.resources) {
467
+ throw new Error(`Server does not support notifying about resources (required for ${method})`);
468
+ }
469
+ break;
470
+ case "notifications/tools/list_changed":
471
+ if (!this._capabilities.tools) {
472
+ throw new Error(`Server does not support notifying of tool list changes (required for ${method})`);
473
+ }
474
+ break;
475
+ case "notifications/prompts/list_changed":
476
+ if (!this._capabilities.prompts) {
477
+ throw new Error(`Server does not support notifying of prompt list changes (required for ${method})`);
478
+ }
479
+ break;
480
+ case "notifications/elicitation/complete":
481
+ if (!this._clientCapabilities?.elicitation?.url) {
482
+ throw new Error(`Client does not support URL elicitation (required for ${method})`);
483
+ }
484
+ break;
485
+ case "notifications/cancelled":
486
+ break;
487
+ case "notifications/progress":
488
+ break;
489
+ }
490
+ }
491
+ assertRequestHandlerCapability(method) {
492
+ if (!this._capabilities) {
493
+ return;
494
+ }
495
+ switch (method) {
496
+ case "completion/complete":
497
+ if (!this._capabilities.completions) {
498
+ throw new Error(`Server does not support completions (required for ${method})`);
499
+ }
500
+ break;
501
+ case "logging/setLevel":
502
+ if (!this._capabilities.logging) {
503
+ throw new Error(`Server does not support logging (required for ${method})`);
504
+ }
505
+ break;
506
+ case "prompts/get":
507
+ case "prompts/list":
508
+ if (!this._capabilities.prompts) {
509
+ throw new Error(`Server does not support prompts (required for ${method})`);
510
+ }
511
+ break;
512
+ case "resources/list":
513
+ case "resources/templates/list":
514
+ case "resources/read":
515
+ if (!this._capabilities.resources) {
516
+ throw new Error(`Server does not support resources (required for ${method})`);
517
+ }
518
+ break;
519
+ case "tools/call":
520
+ case "tools/list":
521
+ if (!this._capabilities.tools) {
522
+ throw new Error(`Server does not support tools (required for ${method})`);
523
+ }
524
+ break;
525
+ case "tasks/get":
526
+ case "tasks/list":
527
+ case "tasks/result":
528
+ case "tasks/cancel":
529
+ if (!this._capabilities.tasks) {
530
+ throw new Error(`Server does not support tasks capability (required for ${method})`);
531
+ }
532
+ break;
533
+ case "ping":
534
+ case "initialize":
535
+ break;
536
+ }
537
+ }
538
+ assertTaskCapability(method) {
539
+ assertClientRequestTaskCapability(this._clientCapabilities?.tasks?.requests, method, "Client");
540
+ }
541
+ assertTaskHandlerCapability(method) {
542
+ if (!this._capabilities) {
543
+ return;
544
+ }
545
+ assertToolsCallTaskCapability(this._capabilities.tasks?.requests, method, "Server");
546
+ }
547
+ async _oninitialize(request) {
548
+ const requestedVersion = request.params.protocolVersion;
549
+ this._clientCapabilities = request.params.capabilities;
550
+ this._clientVersion = request.params.clientInfo;
551
+ const protocolVersion = SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion) ? requestedVersion : LATEST_PROTOCOL_VERSION;
552
+ return {
553
+ protocolVersion,
554
+ capabilities: this.getCapabilities(),
555
+ serverInfo: this._serverInfo,
556
+ ...this._instructions && { instructions: this._instructions }
557
+ };
558
+ }
559
+ /**
560
+ * After initialization has completed, this will be populated with the client's reported capabilities.
561
+ */
562
+ getClientCapabilities() {
563
+ return this._clientCapabilities;
564
+ }
565
+ /**
566
+ * After initialization has completed, this will be populated with information about the client's name and version.
567
+ */
568
+ getClientVersion() {
569
+ return this._clientVersion;
570
+ }
571
+ getCapabilities() {
572
+ return this._capabilities;
573
+ }
574
+ async ping() {
575
+ return this.request({ method: "ping" }, EmptyResultSchema);
576
+ }
577
+ // Implementation
578
+ async createMessage(params, options) {
579
+ if (params.tools || params.toolChoice) {
580
+ if (!this._clientCapabilities?.sampling?.tools) {
581
+ throw new Error("Client does not support sampling tools capability.");
582
+ }
583
+ }
584
+ if (params.messages.length > 0) {
585
+ const lastMessage = params.messages[params.messages.length - 1];
586
+ const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
587
+ const hasToolResults = lastContent.some((c) => c.type === "tool_result");
588
+ const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : void 0;
589
+ const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
590
+ const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
591
+ if (hasToolResults) {
592
+ if (lastContent.some((c) => c.type !== "tool_result")) {
593
+ throw new Error("The last message must contain only tool_result content if any is present");
594
+ }
595
+ if (!hasPreviousToolUse) {
596
+ throw new Error("tool_result blocks are not matching any tool_use from the previous message");
597
+ }
598
+ }
599
+ if (hasPreviousToolUse) {
600
+ const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
601
+ const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
602
+ if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
603
+ throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
604
+ }
605
+ }
606
+ }
607
+ if (params.tools) {
608
+ return this.request({ method: "sampling/createMessage", params }, CreateMessageResultWithToolsSchema, options);
609
+ }
610
+ return this.request({ method: "sampling/createMessage", params }, CreateMessageResultSchema, options);
611
+ }
612
+ /**
613
+ * Creates an elicitation request for the given parameters.
614
+ * For backwards compatibility, `mode` may be omitted for form requests and will default to `'form'`.
615
+ * @param params The parameters for the elicitation request.
616
+ * @param options Optional request options.
617
+ * @returns The result of the elicitation request.
618
+ */
619
+ async elicitInput(params, options) {
620
+ const mode = params.mode ?? "form";
621
+ switch (mode) {
622
+ case "url": {
623
+ if (!this._clientCapabilities?.elicitation?.url) {
624
+ throw new Error("Client does not support url elicitation.");
625
+ }
626
+ const urlParams = params;
627
+ return this.request({ method: "elicitation/create", params: urlParams }, ElicitResultSchema, options);
628
+ }
629
+ case "form": {
630
+ if (!this._clientCapabilities?.elicitation?.form) {
631
+ throw new Error("Client does not support form elicitation.");
632
+ }
633
+ const formParams = params.mode === "form" ? params : { ...params, mode: "form" };
634
+ const result = await this.request({ method: "elicitation/create", params: formParams }, ElicitResultSchema, options);
635
+ if (result.action === "accept" && result.content && formParams.requestedSchema) {
636
+ try {
637
+ const validator = this._jsonSchemaValidator.getValidator(formParams.requestedSchema);
638
+ const validationResult = validator(result.content);
639
+ if (!validationResult.valid) {
640
+ throw new McpError(ErrorCode.InvalidParams, `Elicitation response content does not match requested schema: ${validationResult.errorMessage}`);
641
+ }
642
+ } catch (error) {
643
+ if (error instanceof McpError) {
644
+ throw error;
645
+ }
646
+ throw new McpError(ErrorCode.InternalError, `Error validating elicitation response: ${error instanceof Error ? error.message : String(error)}`);
647
+ }
648
+ }
649
+ return result;
650
+ }
651
+ }
652
+ }
653
+ /**
654
+ * Creates a reusable callback that, when invoked, will send a `notifications/elicitation/complete`
655
+ * notification for the specified elicitation ID.
656
+ *
657
+ * @param elicitationId The ID of the elicitation to mark as complete.
658
+ * @param options Optional notification options. Useful when the completion notification should be related to a prior request.
659
+ * @returns A function that emits the completion notification when awaited.
660
+ */
661
+ createElicitationCompletionNotifier(elicitationId, options) {
662
+ if (!this._clientCapabilities?.elicitation?.url) {
663
+ throw new Error("Client does not support URL elicitation (required for notifications/elicitation/complete)");
664
+ }
665
+ return () => this.notification({
666
+ method: "notifications/elicitation/complete",
667
+ params: {
668
+ elicitationId
669
+ }
670
+ }, options);
671
+ }
672
+ async listRoots(params, options) {
673
+ return this.request({ method: "roots/list", params }, ListRootsResultSchema, options);
674
+ }
675
+ /**
676
+ * Sends a logging message to the client, if connected.
677
+ * Note: You only need to send the parameters object, not the entire JSON RPC message
678
+ * @see LoggingMessageNotification
679
+ * @param params
680
+ * @param sessionId optional for stateless and backward compatibility
681
+ */
682
+ async sendLoggingMessage(params, sessionId) {
683
+ if (this._capabilities.logging) {
684
+ if (!this.isMessageIgnored(params.level, sessionId)) {
685
+ return this.notification({ method: "notifications/message", params });
686
+ }
687
+ }
688
+ }
689
+ async sendResourceUpdated(params) {
690
+ return this.notification({
691
+ method: "notifications/resources/updated",
692
+ params
693
+ });
694
+ }
695
+ async sendResourceListChanged() {
696
+ return this.notification({
697
+ method: "notifications/resources/list_changed"
698
+ });
699
+ }
700
+ async sendToolListChanged() {
701
+ return this.notification({ method: "notifications/tools/list_changed" });
702
+ }
703
+ async sendPromptListChanged() {
704
+ return this.notification({ method: "notifications/prompts/list_changed" });
705
+ }
706
+ };
707
+
708
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
709
+ init_esm_shims();
710
+ var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
711
+ function isCompletable(schema) {
712
+ return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
713
+ }
714
+ function getCompleter(schema) {
715
+ const meta = schema[COMPLETABLE_SYMBOL];
716
+ return meta?.complete;
717
+ }
718
+ var McpZodTypeKind;
719
+ (function(McpZodTypeKind2) {
720
+ McpZodTypeKind2["Completable"] = "McpCompletable";
721
+ })(McpZodTypeKind || (McpZodTypeKind = {}));
722
+
723
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
724
+ init_esm_shims();
725
+
726
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
727
+ init_esm_shims();
728
+ var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
729
+ function validateToolName(name) {
730
+ const warnings = [];
731
+ if (name.length === 0) {
732
+ return {
733
+ isValid: false,
734
+ warnings: ["Tool name cannot be empty"]
735
+ };
736
+ }
737
+ if (name.length > 128) {
738
+ return {
739
+ isValid: false,
740
+ warnings: [`Tool name exceeds maximum length of 128 characters (current: ${name.length})`]
741
+ };
742
+ }
743
+ if (name.includes(" ")) {
744
+ warnings.push("Tool name contains spaces, which may cause parsing issues");
745
+ }
746
+ if (name.includes(",")) {
747
+ warnings.push("Tool name contains commas, which may cause parsing issues");
748
+ }
749
+ if (name.startsWith("-") || name.endsWith("-")) {
750
+ warnings.push("Tool name starts or ends with a dash, which may cause parsing issues in some contexts");
751
+ }
752
+ if (name.startsWith(".") || name.endsWith(".")) {
753
+ warnings.push("Tool name starts or ends with a dot, which may cause parsing issues in some contexts");
754
+ }
755
+ if (!TOOL_NAME_REGEX.test(name)) {
756
+ const invalidChars = name.split("").filter((char) => !/[A-Za-z0-9._-]/.test(char)).filter((char, index, arr) => arr.indexOf(char) === index);
757
+ warnings.push(`Tool name contains invalid characters: ${invalidChars.map((c) => `"${c}"`).join(", ")}`, "Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)");
758
+ return {
759
+ isValid: false,
760
+ warnings
761
+ };
762
+ }
763
+ return {
764
+ isValid: true,
765
+ warnings
766
+ };
767
+ }
768
+ function issueToolNameWarning(name, warnings) {
769
+ if (warnings.length > 0) {
770
+ console.warn(`Tool name validation warning for "${name}":`);
771
+ for (const warning of warnings) {
772
+ console.warn(` - ${warning}`);
773
+ }
774
+ console.warn("Tool registration will proceed, but this may cause compatibility issues.");
775
+ console.warn("Consider updating the tool name to conform to the MCP tool naming standard.");
776
+ console.warn("See SEP: Specify Format for Tool Names (https://github.com/modelcontextprotocol/modelcontextprotocol/issues/986) for more details.");
777
+ }
778
+ }
779
+ function validateAndWarnToolName(name) {
780
+ const result = validateToolName(name);
781
+ issueToolNameWarning(name, result.warnings);
782
+ return result.isValid;
783
+ }
784
+
785
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
786
+ init_esm_shims();
787
+ var ExperimentalMcpServerTasks = class {
788
+ constructor(_mcpServer) {
789
+ this._mcpServer = _mcpServer;
790
+ }
791
+ registerToolTask(name, config, handler) {
792
+ const execution = { taskSupport: "required", ...config.execution };
793
+ if (execution.taskSupport === "forbidden") {
794
+ throw new Error(`Cannot register task-based tool '${name}' with taskSupport 'forbidden'. Use registerTool() instead.`);
795
+ }
796
+ const mcpServerInternal = this._mcpServer;
797
+ return mcpServerInternal._createRegisteredTool(name, config.title, config.description, config.inputSchema, config.outputSchema, config.annotations, execution, config._meta, handler);
798
+ }
799
+ };
800
+
801
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
802
+ var McpServer = class {
803
+ constructor(serverInfo, options) {
804
+ this._registeredResources = {};
805
+ this._registeredResourceTemplates = {};
806
+ this._registeredTools = {};
807
+ this._registeredPrompts = {};
808
+ this._toolHandlersInitialized = false;
809
+ this._completionHandlerInitialized = false;
810
+ this._resourceHandlersInitialized = false;
811
+ this._promptHandlersInitialized = false;
812
+ this.server = new Server(serverInfo, options);
813
+ }
814
+ /**
815
+ * Access experimental features.
816
+ *
817
+ * WARNING: These APIs are experimental and may change without notice.
818
+ *
819
+ * @experimental
820
+ */
821
+ get experimental() {
822
+ if (!this._experimental) {
823
+ this._experimental = {
824
+ tasks: new ExperimentalMcpServerTasks(this)
825
+ };
826
+ }
827
+ return this._experimental;
828
+ }
829
+ /**
830
+ * Attaches to the given transport, starts it, and starts listening for messages.
831
+ *
832
+ * The `server` object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward.
833
+ */
834
+ async connect(transport) {
835
+ return await this.server.connect(transport);
836
+ }
837
+ /**
838
+ * Closes the connection.
839
+ */
840
+ async close() {
841
+ await this.server.close();
842
+ }
843
+ setToolRequestHandlers() {
844
+ if (this._toolHandlersInitialized) {
845
+ return;
846
+ }
847
+ this.server.assertCanSetRequestHandler(getMethodValue(ListToolsRequestSchema));
848
+ this.server.assertCanSetRequestHandler(getMethodValue(CallToolRequestSchema));
849
+ this.server.registerCapabilities({
850
+ tools: {
851
+ listChanged: true
852
+ }
853
+ });
854
+ this.server.setRequestHandler(ListToolsRequestSchema, () => ({
855
+ tools: Object.entries(this._registeredTools).filter(([, tool]) => tool.enabled).map(([name, tool]) => {
856
+ const toolDefinition = {
857
+ name,
858
+ title: tool.title,
859
+ description: tool.description,
860
+ inputSchema: (() => {
861
+ const obj = normalizeObjectSchema(tool.inputSchema);
862
+ return obj ? toJsonSchemaCompat(obj, {
863
+ strictUnions: true,
864
+ pipeStrategy: "input"
865
+ }) : EMPTY_OBJECT_JSON_SCHEMA;
866
+ })(),
867
+ annotations: tool.annotations,
868
+ execution: tool.execution,
869
+ _meta: tool._meta
870
+ };
871
+ if (tool.outputSchema) {
872
+ const obj = normalizeObjectSchema(tool.outputSchema);
873
+ if (obj) {
874
+ toolDefinition.outputSchema = toJsonSchemaCompat(obj, {
875
+ strictUnions: true,
876
+ pipeStrategy: "output"
877
+ });
878
+ }
879
+ }
880
+ return toolDefinition;
881
+ })
882
+ }));
883
+ this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
884
+ try {
885
+ const tool = this._registeredTools[request.params.name];
886
+ if (!tool) {
887
+ throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} not found`);
888
+ }
889
+ if (!tool.enabled) {
890
+ throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} disabled`);
891
+ }
892
+ const isTaskRequest = !!request.params.task;
893
+ const taskSupport = tool.execution?.taskSupport;
894
+ const isTaskHandler = "createTask" in tool.handler;
895
+ if ((taskSupport === "required" || taskSupport === "optional") && !isTaskHandler) {
896
+ throw new McpError(ErrorCode.InternalError, `Tool ${request.params.name} has taskSupport '${taskSupport}' but was not registered with registerToolTask`);
897
+ }
898
+ if (taskSupport === "required" && !isTaskRequest) {
899
+ throw new McpError(ErrorCode.MethodNotFound, `Tool ${request.params.name} requires task augmentation (taskSupport: 'required')`);
900
+ }
901
+ if (taskSupport === "optional" && !isTaskRequest && isTaskHandler) {
902
+ return await this.handleAutomaticTaskPolling(tool, request, extra);
903
+ }
904
+ const args = await this.validateToolInput(tool, request.params.arguments, request.params.name);
905
+ const result = await this.executeToolHandler(tool, args, extra);
906
+ if (isTaskRequest) {
907
+ return result;
908
+ }
909
+ await this.validateToolOutput(tool, result, request.params.name);
910
+ return result;
911
+ } catch (error) {
912
+ if (error instanceof McpError) {
913
+ if (error.code === ErrorCode.UrlElicitationRequired) {
914
+ throw error;
915
+ }
916
+ }
917
+ return this.createToolError(error instanceof Error ? error.message : String(error));
918
+ }
919
+ });
920
+ this._toolHandlersInitialized = true;
921
+ }
922
+ /**
923
+ * Creates a tool error result.
924
+ *
925
+ * @param errorMessage - The error message.
926
+ * @returns The tool error result.
927
+ */
928
+ createToolError(errorMessage) {
929
+ return {
930
+ content: [
931
+ {
932
+ type: "text",
933
+ text: errorMessage
934
+ }
935
+ ],
936
+ isError: true
937
+ };
938
+ }
939
+ /**
940
+ * Validates tool input arguments against the tool's input schema.
941
+ */
942
+ async validateToolInput(tool, args, toolName) {
943
+ if (!tool.inputSchema) {
944
+ return void 0;
945
+ }
946
+ const inputObj = normalizeObjectSchema(tool.inputSchema);
947
+ const schemaToParse = inputObj ?? tool.inputSchema;
948
+ const parseResult = await safeParseAsync(schemaToParse, args);
949
+ if (!parseResult.success) {
950
+ const error = "error" in parseResult ? parseResult.error : "Unknown error";
951
+ const errorMessage = getParseErrorMessage(error);
952
+ throw new McpError(ErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}`);
953
+ }
954
+ return parseResult.data;
955
+ }
956
+ /**
957
+ * Validates tool output against the tool's output schema.
958
+ */
959
+ async validateToolOutput(tool, result, toolName) {
960
+ if (!tool.outputSchema) {
961
+ return;
962
+ }
963
+ if (!("content" in result)) {
964
+ return;
965
+ }
966
+ if (result.isError) {
967
+ return;
968
+ }
969
+ if (!result.structuredContent) {
970
+ throw new McpError(ErrorCode.InvalidParams, `Output validation error: Tool ${toolName} has an output schema but no structured content was provided`);
971
+ }
972
+ const outputObj = normalizeObjectSchema(tool.outputSchema);
973
+ const parseResult = await safeParseAsync(outputObj, result.structuredContent);
974
+ if (!parseResult.success) {
975
+ const error = "error" in parseResult ? parseResult.error : "Unknown error";
976
+ const errorMessage = getParseErrorMessage(error);
977
+ throw new McpError(ErrorCode.InvalidParams, `Output validation error: Invalid structured content for tool ${toolName}: ${errorMessage}`);
978
+ }
979
+ }
980
+ /**
981
+ * Executes a tool handler (either regular or task-based).
982
+ */
983
+ async executeToolHandler(tool, args, extra) {
984
+ const handler = tool.handler;
985
+ const isTaskHandler = "createTask" in handler;
986
+ if (isTaskHandler) {
987
+ if (!extra.taskStore) {
988
+ throw new Error("No task store provided.");
989
+ }
990
+ const taskExtra = { ...extra, taskStore: extra.taskStore };
991
+ if (tool.inputSchema) {
992
+ const typedHandler = handler;
993
+ return await Promise.resolve(typedHandler.createTask(args, taskExtra));
994
+ } else {
995
+ const typedHandler = handler;
996
+ return await Promise.resolve(typedHandler.createTask(taskExtra));
997
+ }
998
+ }
999
+ if (tool.inputSchema) {
1000
+ const typedHandler = handler;
1001
+ return await Promise.resolve(typedHandler(args, extra));
1002
+ } else {
1003
+ const typedHandler = handler;
1004
+ return await Promise.resolve(typedHandler(extra));
1005
+ }
1006
+ }
1007
+ /**
1008
+ * Handles automatic task polling for tools with taskSupport 'optional'.
1009
+ */
1010
+ async handleAutomaticTaskPolling(tool, request, extra) {
1011
+ if (!extra.taskStore) {
1012
+ throw new Error("No task store provided for task-capable tool.");
1013
+ }
1014
+ const args = await this.validateToolInput(tool, request.params.arguments, request.params.name);
1015
+ const handler = tool.handler;
1016
+ const taskExtra = { ...extra, taskStore: extra.taskStore };
1017
+ const createTaskResult = args ? await Promise.resolve(handler.createTask(args, taskExtra)) : (
1018
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1019
+ await Promise.resolve(handler.createTask(taskExtra))
1020
+ );
1021
+ const taskId = createTaskResult.task.taskId;
1022
+ let task = createTaskResult.task;
1023
+ const pollInterval = task.pollInterval ?? 5e3;
1024
+ while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
1025
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
1026
+ const updatedTask = await extra.taskStore.getTask(taskId);
1027
+ if (!updatedTask) {
1028
+ throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
1029
+ }
1030
+ task = updatedTask;
1031
+ }
1032
+ return await extra.taskStore.getTaskResult(taskId);
1033
+ }
1034
+ setCompletionRequestHandler() {
1035
+ if (this._completionHandlerInitialized) {
1036
+ return;
1037
+ }
1038
+ this.server.assertCanSetRequestHandler(getMethodValue(CompleteRequestSchema));
1039
+ this.server.registerCapabilities({
1040
+ completions: {}
1041
+ });
1042
+ this.server.setRequestHandler(CompleteRequestSchema, async (request) => {
1043
+ switch (request.params.ref.type) {
1044
+ case "ref/prompt":
1045
+ assertCompleteRequestPrompt(request);
1046
+ return this.handlePromptCompletion(request, request.params.ref);
1047
+ case "ref/resource":
1048
+ assertCompleteRequestResourceTemplate(request);
1049
+ return this.handleResourceCompletion(request, request.params.ref);
1050
+ default:
1051
+ throw new McpError(ErrorCode.InvalidParams, `Invalid completion reference: ${request.params.ref}`);
1052
+ }
1053
+ });
1054
+ this._completionHandlerInitialized = true;
1055
+ }
1056
+ async handlePromptCompletion(request, ref) {
1057
+ const prompt = this._registeredPrompts[ref.name];
1058
+ if (!prompt) {
1059
+ throw new McpError(ErrorCode.InvalidParams, `Prompt ${ref.name} not found`);
1060
+ }
1061
+ if (!prompt.enabled) {
1062
+ throw new McpError(ErrorCode.InvalidParams, `Prompt ${ref.name} disabled`);
1063
+ }
1064
+ if (!prompt.argsSchema) {
1065
+ return EMPTY_COMPLETION_RESULT;
1066
+ }
1067
+ const promptShape = getObjectShape(prompt.argsSchema);
1068
+ const field = promptShape?.[request.params.argument.name];
1069
+ if (!isCompletable(field)) {
1070
+ return EMPTY_COMPLETION_RESULT;
1071
+ }
1072
+ const completer = getCompleter(field);
1073
+ if (!completer) {
1074
+ return EMPTY_COMPLETION_RESULT;
1075
+ }
1076
+ const suggestions = await completer(request.params.argument.value, request.params.context);
1077
+ return createCompletionResult(suggestions);
1078
+ }
1079
+ async handleResourceCompletion(request, ref) {
1080
+ const template = Object.values(this._registeredResourceTemplates).find((t) => t.resourceTemplate.uriTemplate.toString() === ref.uri);
1081
+ if (!template) {
1082
+ if (this._registeredResources[ref.uri]) {
1083
+ return EMPTY_COMPLETION_RESULT;
1084
+ }
1085
+ throw new McpError(ErrorCode.InvalidParams, `Resource template ${request.params.ref.uri} not found`);
1086
+ }
1087
+ const completer = template.resourceTemplate.completeCallback(request.params.argument.name);
1088
+ if (!completer) {
1089
+ return EMPTY_COMPLETION_RESULT;
1090
+ }
1091
+ const suggestions = await completer(request.params.argument.value, request.params.context);
1092
+ return createCompletionResult(suggestions);
1093
+ }
1094
+ setResourceRequestHandlers() {
1095
+ if (this._resourceHandlersInitialized) {
1096
+ return;
1097
+ }
1098
+ this.server.assertCanSetRequestHandler(getMethodValue(ListResourcesRequestSchema));
1099
+ this.server.assertCanSetRequestHandler(getMethodValue(ListResourceTemplatesRequestSchema));
1100
+ this.server.assertCanSetRequestHandler(getMethodValue(ReadResourceRequestSchema));
1101
+ this.server.registerCapabilities({
1102
+ resources: {
1103
+ listChanged: true
1104
+ }
1105
+ });
1106
+ this.server.setRequestHandler(ListResourcesRequestSchema, async (request, extra) => {
1107
+ const resources = Object.entries(this._registeredResources).filter(([_, resource]) => resource.enabled).map(([uri, resource]) => ({
1108
+ uri,
1109
+ name: resource.name,
1110
+ ...resource.metadata
1111
+ }));
1112
+ const templateResources = [];
1113
+ for (const template of Object.values(this._registeredResourceTemplates)) {
1114
+ if (!template.resourceTemplate.listCallback) {
1115
+ continue;
1116
+ }
1117
+ const result = await template.resourceTemplate.listCallback(extra);
1118
+ for (const resource of result.resources) {
1119
+ templateResources.push({
1120
+ ...template.metadata,
1121
+ // the defined resource metadata should override the template metadata if present
1122
+ ...resource
1123
+ });
1124
+ }
1125
+ }
1126
+ return { resources: [...resources, ...templateResources] };
1127
+ });
1128
+ this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
1129
+ const resourceTemplates = Object.entries(this._registeredResourceTemplates).map(([name, template]) => ({
1130
+ name,
1131
+ uriTemplate: template.resourceTemplate.uriTemplate.toString(),
1132
+ ...template.metadata
1133
+ }));
1134
+ return { resourceTemplates };
1135
+ });
1136
+ this.server.setRequestHandler(ReadResourceRequestSchema, async (request, extra) => {
1137
+ const uri = new URL(request.params.uri);
1138
+ const resource = this._registeredResources[uri.toString()];
1139
+ if (resource) {
1140
+ if (!resource.enabled) {
1141
+ throw new McpError(ErrorCode.InvalidParams, `Resource ${uri} disabled`);
1142
+ }
1143
+ return resource.readCallback(uri, extra);
1144
+ }
1145
+ for (const template of Object.values(this._registeredResourceTemplates)) {
1146
+ const variables = template.resourceTemplate.uriTemplate.match(uri.toString());
1147
+ if (variables) {
1148
+ return template.readCallback(uri, variables, extra);
1149
+ }
1150
+ }
1151
+ throw new McpError(ErrorCode.InvalidParams, `Resource ${uri} not found`);
1152
+ });
1153
+ this._resourceHandlersInitialized = true;
1154
+ }
1155
+ setPromptRequestHandlers() {
1156
+ if (this._promptHandlersInitialized) {
1157
+ return;
1158
+ }
1159
+ this.server.assertCanSetRequestHandler(getMethodValue(ListPromptsRequestSchema));
1160
+ this.server.assertCanSetRequestHandler(getMethodValue(GetPromptRequestSchema));
1161
+ this.server.registerCapabilities({
1162
+ prompts: {
1163
+ listChanged: true
1164
+ }
1165
+ });
1166
+ this.server.setRequestHandler(ListPromptsRequestSchema, () => ({
1167
+ prompts: Object.entries(this._registeredPrompts).filter(([, prompt]) => prompt.enabled).map(([name, prompt]) => {
1168
+ return {
1169
+ name,
1170
+ title: prompt.title,
1171
+ description: prompt.description,
1172
+ arguments: prompt.argsSchema ? promptArgumentsFromSchema(prompt.argsSchema) : void 0
1173
+ };
1174
+ })
1175
+ }));
1176
+ this.server.setRequestHandler(GetPromptRequestSchema, async (request, extra) => {
1177
+ const prompt = this._registeredPrompts[request.params.name];
1178
+ if (!prompt) {
1179
+ throw new McpError(ErrorCode.InvalidParams, `Prompt ${request.params.name} not found`);
1180
+ }
1181
+ if (!prompt.enabled) {
1182
+ throw new McpError(ErrorCode.InvalidParams, `Prompt ${request.params.name} disabled`);
1183
+ }
1184
+ if (prompt.argsSchema) {
1185
+ const argsObj = normalizeObjectSchema(prompt.argsSchema);
1186
+ const parseResult = await safeParseAsync(argsObj, request.params.arguments);
1187
+ if (!parseResult.success) {
1188
+ const error = "error" in parseResult ? parseResult.error : "Unknown error";
1189
+ const errorMessage = getParseErrorMessage(error);
1190
+ throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for prompt ${request.params.name}: ${errorMessage}`);
1191
+ }
1192
+ const args = parseResult.data;
1193
+ const cb = prompt.callback;
1194
+ return await Promise.resolve(cb(args, extra));
1195
+ } else {
1196
+ const cb = prompt.callback;
1197
+ return await Promise.resolve(cb(extra));
1198
+ }
1199
+ });
1200
+ this._promptHandlersInitialized = true;
1201
+ }
1202
+ resource(name, uriOrTemplate, ...rest) {
1203
+ let metadata;
1204
+ if (typeof rest[0] === "object") {
1205
+ metadata = rest.shift();
1206
+ }
1207
+ const readCallback = rest[0];
1208
+ if (typeof uriOrTemplate === "string") {
1209
+ if (this._registeredResources[uriOrTemplate]) {
1210
+ throw new Error(`Resource ${uriOrTemplate} is already registered`);
1211
+ }
1212
+ const registeredResource = this._createRegisteredResource(name, void 0, uriOrTemplate, metadata, readCallback);
1213
+ this.setResourceRequestHandlers();
1214
+ this.sendResourceListChanged();
1215
+ return registeredResource;
1216
+ } else {
1217
+ if (this._registeredResourceTemplates[name]) {
1218
+ throw new Error(`Resource template ${name} is already registered`);
1219
+ }
1220
+ const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, void 0, uriOrTemplate, metadata, readCallback);
1221
+ this.setResourceRequestHandlers();
1222
+ this.sendResourceListChanged();
1223
+ return registeredResourceTemplate;
1224
+ }
1225
+ }
1226
+ registerResource(name, uriOrTemplate, config, readCallback) {
1227
+ if (typeof uriOrTemplate === "string") {
1228
+ if (this._registeredResources[uriOrTemplate]) {
1229
+ throw new Error(`Resource ${uriOrTemplate} is already registered`);
1230
+ }
1231
+ const registeredResource = this._createRegisteredResource(name, config.title, uriOrTemplate, config, readCallback);
1232
+ this.setResourceRequestHandlers();
1233
+ this.sendResourceListChanged();
1234
+ return registeredResource;
1235
+ } else {
1236
+ if (this._registeredResourceTemplates[name]) {
1237
+ throw new Error(`Resource template ${name} is already registered`);
1238
+ }
1239
+ const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, config.title, uriOrTemplate, config, readCallback);
1240
+ this.setResourceRequestHandlers();
1241
+ this.sendResourceListChanged();
1242
+ return registeredResourceTemplate;
1243
+ }
1244
+ }
1245
+ _createRegisteredResource(name, title, uri, metadata, readCallback) {
1246
+ const registeredResource = {
1247
+ name,
1248
+ title,
1249
+ metadata,
1250
+ readCallback,
1251
+ enabled: true,
1252
+ disable: () => registeredResource.update({ enabled: false }),
1253
+ enable: () => registeredResource.update({ enabled: true }),
1254
+ remove: () => registeredResource.update({ uri: null }),
1255
+ update: (updates) => {
1256
+ if (typeof updates.uri !== "undefined" && updates.uri !== uri) {
1257
+ delete this._registeredResources[uri];
1258
+ if (updates.uri)
1259
+ this._registeredResources[updates.uri] = registeredResource;
1260
+ }
1261
+ if (typeof updates.name !== "undefined")
1262
+ registeredResource.name = updates.name;
1263
+ if (typeof updates.title !== "undefined")
1264
+ registeredResource.title = updates.title;
1265
+ if (typeof updates.metadata !== "undefined")
1266
+ registeredResource.metadata = updates.metadata;
1267
+ if (typeof updates.callback !== "undefined")
1268
+ registeredResource.readCallback = updates.callback;
1269
+ if (typeof updates.enabled !== "undefined")
1270
+ registeredResource.enabled = updates.enabled;
1271
+ this.sendResourceListChanged();
1272
+ }
1273
+ };
1274
+ this._registeredResources[uri] = registeredResource;
1275
+ return registeredResource;
1276
+ }
1277
+ _createRegisteredResourceTemplate(name, title, template, metadata, readCallback) {
1278
+ const registeredResourceTemplate = {
1279
+ resourceTemplate: template,
1280
+ title,
1281
+ metadata,
1282
+ readCallback,
1283
+ enabled: true,
1284
+ disable: () => registeredResourceTemplate.update({ enabled: false }),
1285
+ enable: () => registeredResourceTemplate.update({ enabled: true }),
1286
+ remove: () => registeredResourceTemplate.update({ name: null }),
1287
+ update: (updates) => {
1288
+ if (typeof updates.name !== "undefined" && updates.name !== name) {
1289
+ delete this._registeredResourceTemplates[name];
1290
+ if (updates.name)
1291
+ this._registeredResourceTemplates[updates.name] = registeredResourceTemplate;
1292
+ }
1293
+ if (typeof updates.title !== "undefined")
1294
+ registeredResourceTemplate.title = updates.title;
1295
+ if (typeof updates.template !== "undefined")
1296
+ registeredResourceTemplate.resourceTemplate = updates.template;
1297
+ if (typeof updates.metadata !== "undefined")
1298
+ registeredResourceTemplate.metadata = updates.metadata;
1299
+ if (typeof updates.callback !== "undefined")
1300
+ registeredResourceTemplate.readCallback = updates.callback;
1301
+ if (typeof updates.enabled !== "undefined")
1302
+ registeredResourceTemplate.enabled = updates.enabled;
1303
+ this.sendResourceListChanged();
1304
+ }
1305
+ };
1306
+ this._registeredResourceTemplates[name] = registeredResourceTemplate;
1307
+ const variableNames = template.uriTemplate.variableNames;
1308
+ const hasCompleter = Array.isArray(variableNames) && variableNames.some((v) => !!template.completeCallback(v));
1309
+ if (hasCompleter) {
1310
+ this.setCompletionRequestHandler();
1311
+ }
1312
+ return registeredResourceTemplate;
1313
+ }
1314
+ _createRegisteredPrompt(name, title, description, argsSchema, callback) {
1315
+ const registeredPrompt = {
1316
+ title,
1317
+ description,
1318
+ argsSchema: argsSchema === void 0 ? void 0 : objectFromShape(argsSchema),
1319
+ callback,
1320
+ enabled: true,
1321
+ disable: () => registeredPrompt.update({ enabled: false }),
1322
+ enable: () => registeredPrompt.update({ enabled: true }),
1323
+ remove: () => registeredPrompt.update({ name: null }),
1324
+ update: (updates) => {
1325
+ if (typeof updates.name !== "undefined" && updates.name !== name) {
1326
+ delete this._registeredPrompts[name];
1327
+ if (updates.name)
1328
+ this._registeredPrompts[updates.name] = registeredPrompt;
1329
+ }
1330
+ if (typeof updates.title !== "undefined")
1331
+ registeredPrompt.title = updates.title;
1332
+ if (typeof updates.description !== "undefined")
1333
+ registeredPrompt.description = updates.description;
1334
+ if (typeof updates.argsSchema !== "undefined")
1335
+ registeredPrompt.argsSchema = objectFromShape(updates.argsSchema);
1336
+ if (typeof updates.callback !== "undefined")
1337
+ registeredPrompt.callback = updates.callback;
1338
+ if (typeof updates.enabled !== "undefined")
1339
+ registeredPrompt.enabled = updates.enabled;
1340
+ this.sendPromptListChanged();
1341
+ }
1342
+ };
1343
+ this._registeredPrompts[name] = registeredPrompt;
1344
+ if (argsSchema) {
1345
+ const hasCompletable = Object.values(argsSchema).some((field) => {
1346
+ const inner = field instanceof ZodOptional ? field._def?.innerType : field;
1347
+ return isCompletable(inner);
1348
+ });
1349
+ if (hasCompletable) {
1350
+ this.setCompletionRequestHandler();
1351
+ }
1352
+ }
1353
+ return registeredPrompt;
1354
+ }
1355
+ _createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, execution, _meta, handler) {
1356
+ validateAndWarnToolName(name);
1357
+ const registeredTool = {
1358
+ title,
1359
+ description,
1360
+ inputSchema: getZodSchemaObject(inputSchema),
1361
+ outputSchema: getZodSchemaObject(outputSchema),
1362
+ annotations,
1363
+ execution,
1364
+ _meta,
1365
+ handler,
1366
+ enabled: true,
1367
+ disable: () => registeredTool.update({ enabled: false }),
1368
+ enable: () => registeredTool.update({ enabled: true }),
1369
+ remove: () => registeredTool.update({ name: null }),
1370
+ update: (updates) => {
1371
+ if (typeof updates.name !== "undefined" && updates.name !== name) {
1372
+ if (typeof updates.name === "string") {
1373
+ validateAndWarnToolName(updates.name);
1374
+ }
1375
+ delete this._registeredTools[name];
1376
+ if (updates.name)
1377
+ this._registeredTools[updates.name] = registeredTool;
1378
+ }
1379
+ if (typeof updates.title !== "undefined")
1380
+ registeredTool.title = updates.title;
1381
+ if (typeof updates.description !== "undefined")
1382
+ registeredTool.description = updates.description;
1383
+ if (typeof updates.paramsSchema !== "undefined")
1384
+ registeredTool.inputSchema = objectFromShape(updates.paramsSchema);
1385
+ if (typeof updates.outputSchema !== "undefined")
1386
+ registeredTool.outputSchema = objectFromShape(updates.outputSchema);
1387
+ if (typeof updates.callback !== "undefined")
1388
+ registeredTool.handler = updates.callback;
1389
+ if (typeof updates.annotations !== "undefined")
1390
+ registeredTool.annotations = updates.annotations;
1391
+ if (typeof updates._meta !== "undefined")
1392
+ registeredTool._meta = updates._meta;
1393
+ if (typeof updates.enabled !== "undefined")
1394
+ registeredTool.enabled = updates.enabled;
1395
+ this.sendToolListChanged();
1396
+ }
1397
+ };
1398
+ this._registeredTools[name] = registeredTool;
1399
+ this.setToolRequestHandlers();
1400
+ this.sendToolListChanged();
1401
+ return registeredTool;
1402
+ }
1403
+ /**
1404
+ * tool() implementation. Parses arguments passed to overrides defined above.
1405
+ */
1406
+ tool(name, ...rest) {
1407
+ if (this._registeredTools[name]) {
1408
+ throw new Error(`Tool ${name} is already registered`);
1409
+ }
1410
+ let description;
1411
+ let inputSchema;
1412
+ let outputSchema;
1413
+ let annotations;
1414
+ if (typeof rest[0] === "string") {
1415
+ description = rest.shift();
1416
+ }
1417
+ if (rest.length > 1) {
1418
+ const firstArg = rest[0];
1419
+ if (isZodRawShapeCompat(firstArg)) {
1420
+ inputSchema = rest.shift();
1421
+ if (rest.length > 1 && typeof rest[0] === "object" && rest[0] !== null && !isZodRawShapeCompat(rest[0])) {
1422
+ annotations = rest.shift();
1423
+ }
1424
+ } else if (typeof firstArg === "object" && firstArg !== null) {
1425
+ if (Object.values(firstArg).some((v) => typeof v === "object" && v !== null)) {
1426
+ throw new Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);
1427
+ }
1428
+ annotations = rest.shift();
1429
+ }
1430
+ }
1431
+ const callback = rest[0];
1432
+ return this._createRegisteredTool(name, void 0, description, inputSchema, outputSchema, annotations, { taskSupport: "forbidden" }, void 0, callback);
1433
+ }
1434
+ /**
1435
+ * Registers a tool with a config object and callback.
1436
+ */
1437
+ registerTool(name, config, cb) {
1438
+ if (this._registeredTools[name]) {
1439
+ throw new Error(`Tool ${name} is already registered`);
1440
+ }
1441
+ const { title, description, inputSchema, outputSchema, annotations, _meta } = config;
1442
+ return this._createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, { taskSupport: "forbidden" }, _meta, cb);
1443
+ }
1444
+ prompt(name, ...rest) {
1445
+ if (this._registeredPrompts[name]) {
1446
+ throw new Error(`Prompt ${name} is already registered`);
1447
+ }
1448
+ let description;
1449
+ if (typeof rest[0] === "string") {
1450
+ description = rest.shift();
1451
+ }
1452
+ let argsSchema;
1453
+ if (rest.length > 1) {
1454
+ argsSchema = rest.shift();
1455
+ }
1456
+ const cb = rest[0];
1457
+ const registeredPrompt = this._createRegisteredPrompt(name, void 0, description, argsSchema, cb);
1458
+ this.setPromptRequestHandlers();
1459
+ this.sendPromptListChanged();
1460
+ return registeredPrompt;
1461
+ }
1462
+ /**
1463
+ * Registers a prompt with a config object and callback.
1464
+ */
1465
+ registerPrompt(name, config, cb) {
1466
+ if (this._registeredPrompts[name]) {
1467
+ throw new Error(`Prompt ${name} is already registered`);
1468
+ }
1469
+ const { title, description, argsSchema } = config;
1470
+ const registeredPrompt = this._createRegisteredPrompt(name, title, description, argsSchema, cb);
1471
+ this.setPromptRequestHandlers();
1472
+ this.sendPromptListChanged();
1473
+ return registeredPrompt;
1474
+ }
1475
+ /**
1476
+ * Checks if the server is connected to a transport.
1477
+ * @returns True if the server is connected
1478
+ */
1479
+ isConnected() {
1480
+ return this.server.transport !== void 0;
1481
+ }
1482
+ /**
1483
+ * Sends a logging message to the client, if connected.
1484
+ * Note: You only need to send the parameters object, not the entire JSON RPC message
1485
+ * @see LoggingMessageNotification
1486
+ * @param params
1487
+ * @param sessionId optional for stateless and backward compatibility
1488
+ */
1489
+ async sendLoggingMessage(params, sessionId) {
1490
+ return this.server.sendLoggingMessage(params, sessionId);
1491
+ }
1492
+ /**
1493
+ * Sends a resource list changed event to the client, if connected.
1494
+ */
1495
+ sendResourceListChanged() {
1496
+ if (this.isConnected()) {
1497
+ this.server.sendResourceListChanged();
1498
+ }
1499
+ }
1500
+ /**
1501
+ * Sends a tool list changed event to the client, if connected.
1502
+ */
1503
+ sendToolListChanged() {
1504
+ if (this.isConnected()) {
1505
+ this.server.sendToolListChanged();
1506
+ }
1507
+ }
1508
+ /**
1509
+ * Sends a prompt list changed event to the client, if connected.
1510
+ */
1511
+ sendPromptListChanged() {
1512
+ if (this.isConnected()) {
1513
+ this.server.sendPromptListChanged();
1514
+ }
1515
+ }
1516
+ };
1517
+ var EMPTY_OBJECT_JSON_SCHEMA = {
1518
+ type: "object",
1519
+ properties: {}
1520
+ };
1521
+ function isZodTypeLike(value) {
1522
+ return value !== null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function";
1523
+ }
1524
+ function isZodSchemaInstance(obj) {
1525
+ return "_def" in obj || "_zod" in obj || isZodTypeLike(obj);
1526
+ }
1527
+ function isZodRawShapeCompat(obj) {
1528
+ if (typeof obj !== "object" || obj === null) {
1529
+ return false;
1530
+ }
1531
+ if (isZodSchemaInstance(obj)) {
1532
+ return false;
1533
+ }
1534
+ if (Object.keys(obj).length === 0) {
1535
+ return true;
1536
+ }
1537
+ return Object.values(obj).some(isZodTypeLike);
1538
+ }
1539
+ function getZodSchemaObject(schema) {
1540
+ if (!schema) {
1541
+ return void 0;
1542
+ }
1543
+ if (isZodRawShapeCompat(schema)) {
1544
+ return objectFromShape(schema);
1545
+ }
1546
+ if (!isZodSchemaInstance(schema)) {
1547
+ throw new Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");
1548
+ }
1549
+ return schema;
1550
+ }
1551
+ function promptArgumentsFromSchema(schema) {
1552
+ const shape = getObjectShape(schema);
1553
+ if (!shape)
1554
+ return [];
1555
+ return Object.entries(shape).map(([name, field]) => {
1556
+ const description = getSchemaDescription(field);
1557
+ const isOptional = isSchemaOptional(field);
1558
+ return {
1559
+ name,
1560
+ description,
1561
+ required: !isOptional
1562
+ };
1563
+ });
1564
+ }
1565
+ function getMethodValue(schema) {
1566
+ const shape = getObjectShape(schema);
1567
+ const methodSchema = shape?.method;
1568
+ if (!methodSchema) {
1569
+ throw new Error("Schema is missing a method literal");
1570
+ }
1571
+ const value = getLiteralValue(methodSchema);
1572
+ if (typeof value === "string") {
1573
+ return value;
1574
+ }
1575
+ throw new Error("Schema method literal must be a string");
1576
+ }
1577
+ function createCompletionResult(suggestions) {
1578
+ return {
1579
+ completion: {
1580
+ values: suggestions.slice(0, 100),
1581
+ total: suggestions.length,
1582
+ hasMore: suggestions.length > 100
1583
+ }
1584
+ };
1585
+ }
1586
+ var EMPTY_COMPLETION_RESULT = {
1587
+ completion: {
1588
+ values: [],
1589
+ hasMore: false
1590
+ }
1591
+ };
1592
+
1593
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
1594
+ init_esm_shims();
1595
+ import process2 from "process";
1596
+ var StdioServerTransport = class {
1597
+ constructor(_stdin = process2.stdin, _stdout = process2.stdout) {
1598
+ this._stdin = _stdin;
1599
+ this._stdout = _stdout;
1600
+ this._readBuffer = new ReadBuffer();
1601
+ this._started = false;
1602
+ this._ondata = (chunk) => {
1603
+ this._readBuffer.append(chunk);
1604
+ this.processReadBuffer();
1605
+ };
1606
+ this._onerror = (error) => {
1607
+ this.onerror?.(error);
1608
+ };
1609
+ }
1610
+ /**
1611
+ * Starts listening for messages on stdin.
1612
+ */
1613
+ async start() {
1614
+ if (this._started) {
1615
+ throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
1616
+ }
1617
+ this._started = true;
1618
+ this._stdin.on("data", this._ondata);
1619
+ this._stdin.on("error", this._onerror);
1620
+ }
1621
+ processReadBuffer() {
1622
+ while (true) {
1623
+ try {
1624
+ const message = this._readBuffer.readMessage();
1625
+ if (message === null) {
1626
+ break;
1627
+ }
1628
+ this.onmessage?.(message);
1629
+ } catch (error) {
1630
+ this.onerror?.(error);
1631
+ }
1632
+ }
1633
+ }
1634
+ async close() {
1635
+ this._stdin.off("data", this._ondata);
1636
+ this._stdin.off("error", this._onerror);
1637
+ const remainingDataListeners = this._stdin.listenerCount("data");
1638
+ if (remainingDataListeners === 0) {
1639
+ this._stdin.pause();
1640
+ }
1641
+ this._readBuffer.clear();
1642
+ this.onclose?.();
1643
+ }
1644
+ send(message) {
1645
+ return new Promise((resolve) => {
1646
+ const json2 = serializeMessage(message);
1647
+ if (this._stdout.write(json2)) {
1648
+ resolve();
1649
+ } else {
1650
+ this._stdout.once("drain", resolve);
1651
+ }
1652
+ });
1653
+ }
1654
+ };
1655
+
1656
+ // src/mcp/server.ts
1657
+ var import_semver = __toESM(require_semver(), 1);
1658
+
1659
+ // src/clients/types.ts
1660
+ init_esm_shims();
1661
+ var CLIENT_IDS = [
1662
+ "claude-code",
1663
+ "claude-desktop",
1664
+ "claude-ai",
1665
+ "claude-api",
1666
+ "chatgpt",
1667
+ "openai-responses",
1668
+ "codex",
1669
+ "gemini-cli",
1670
+ "cursor",
1671
+ "vscode",
1672
+ "windsurf",
1673
+ "zed",
1674
+ "jetbrains-ai",
1675
+ "junie",
1676
+ "cline",
1677
+ "continue",
1678
+ "goose",
1679
+ "lovable",
1680
+ "replit",
1681
+ "bolt",
1682
+ "v0"
1683
+ ];
1684
+
1685
+ // src/mcp/metrics.ts
1686
+ init_esm_shims();
1687
+ var stats = /* @__PURE__ */ new Map();
1688
+ function recordToolCall(tool, ok, ms) {
1689
+ const s = stats.get(tool) ?? { calls: 0, errors: 0, totalMs: 0 };
1690
+ s.calls += 1;
1691
+ if (!ok) s.errors += 1;
1692
+ s.totalMs += ms;
1693
+ stats.set(tool, s);
1694
+ }
1695
+ async function timed(tool, fn) {
1696
+ const start = Date.now();
1697
+ let ok = false;
1698
+ try {
1699
+ const result = await fn();
1700
+ ok = true;
1701
+ return result;
1702
+ } finally {
1703
+ recordToolCall(tool, ok, Date.now() - start);
1704
+ }
1705
+ }
1706
+ function renderPrometheus() {
1707
+ const lines = [
1708
+ "# HELP lurq_tool_calls_total Total MCP tool invocations.",
1709
+ "# TYPE lurq_tool_calls_total counter",
1710
+ "# HELP lurq_tool_errors_total MCP tool invocations that threw.",
1711
+ "# TYPE lurq_tool_errors_total counter",
1712
+ "# HELP lurq_tool_duration_ms_total Cumulative tool handler time in ms.",
1713
+ "# TYPE lurq_tool_duration_ms_total counter"
1714
+ ];
1715
+ for (const [tool, s] of stats) {
1716
+ const label = `{tool="${tool}"}`;
1717
+ lines.push(`lurq_tool_calls_total${label} ${s.calls}`);
1718
+ lines.push(`lurq_tool_errors_total${label} ${s.errors}`);
1719
+ lines.push(`lurq_tool_duration_ms_total${label} ${s.totalMs}`);
1720
+ }
1721
+ return lines.join("\n") + "\n";
1722
+ }
1723
+
1724
+ // src/mcp/compact.ts
1725
+ init_esm_shims();
1726
+ function compact(value) {
1727
+ if (value instanceof Date) return value;
1728
+ if (Array.isArray(value)) {
1729
+ return value.filter((v) => v !== null && v !== void 0).map((v) => compact(v));
1730
+ }
1731
+ if (value !== null && typeof value === "object") {
1732
+ const out = {};
1733
+ for (const [key, raw] of Object.entries(value)) {
1734
+ if (raw === null || raw === void 0) continue;
1735
+ out[key] = compact(raw);
1736
+ }
1737
+ return out;
1738
+ }
1739
+ return value;
1740
+ }
1741
+
1742
+ // src/mcp/toolDescriptions.ts
1743
+ init_esm_shims();
1744
+ var VERIFY_DESCRIPTION = "Confirm an npm package is real, healthy, and not risky before installing: guards against hallucinated or typosquatted names, deprecations and known advisories, and returns a safety verdict with its reasons and what was not checked. Checks the live registry. The cheap gate to call before every install; use evaluate when you need the full scores.";
1745
+ var COMPAT_DESCRIPTION = "Check whether a set of packages forms a coherent stack. Resolves the whole set the way npm would and returns a definitive verdict: compatible, conflict (with the exact clashing constraints), or unknown. Checks peer-dependency and engine ranges from declared metadata, plus any recorded sandbox conflicts. Read-only: never installs or executes package code. Not always instant: a set checked before answers immediately, but a new set is resolved live from registry metadata, which can take up to ~25 seconds. Call once with the whole stack before committing to it.";
1746
+ var COMPAT_PACKAGES_DESCRIPTION = "The full candidate stack to check together, 2\u201330 npm package names \u2014 a whole package.json dependency list is the intended input. Pass every package in one call: conflicts routinely appear only across the whole set (a peer range three packages deep), so checking pairs separately misses them and costs a round trip each.";
1747
+ var COMPAT_VERSIONS_DESCRIPTION = 'Optional exact versions keyed by package name, e.g. {"react":"19.0.0"} (use when not checking latest). Must be exact semver versions, not ranges.';
1748
+ var COMPAT_NODE_DESCRIPTION = 'Optional target Node runtime (e.g. "20" or "20.20.2") for engines.node checks';
1749
+
1750
+ // src/db/usage.ts
1751
+ init_esm_shims();
1752
+ import { and, desc, eq, gte, sql } from "drizzle-orm";
1753
+ function windowStart(days) {
1754
+ return sql`CURRENT_DATE - (${days}::int - 1)`;
1755
+ }
1756
+ async function recordUsage(db, ownerId, tool) {
1757
+ if (!ownerId) return;
1758
+ try {
1759
+ await db.insert(ownerUsageDaily).values({ ownerId, date: sql`CURRENT_DATE`, tool, count: 1 }).onConflictDoUpdate({
1760
+ target: [ownerUsageDaily.ownerId, ownerUsageDaily.date, ownerUsageDaily.tool],
1761
+ set: { count: sql`${ownerUsageDaily.count} + 1` }
1762
+ });
1763
+ } catch {
1764
+ }
1765
+ }
1766
+ async function getUsageSummary(db, ownerId, days) {
1767
+ const rows = await db.execute(sql`
1768
+ select
1769
+ to_char(d, 'YYYY-MM-DD') as date,
1770
+ coalesce(sum(u.count), 0)::int as count
1771
+ from generate_series(${windowStart(days)}, CURRENT_DATE, interval '1 day') as d
1772
+ left join ${ownerUsageDaily} u
1773
+ on u.date = d::date and u.owner_id = ${ownerId}
1774
+ group by d
1775
+ order by d
1776
+ `);
1777
+ const series = rows.map((r) => ({ date: String(r.date), count: Number(r.count) }));
1778
+ const today = series.at(-1)?.count ?? 0;
1779
+ return { today, series };
1780
+ }
1781
+ async function getUsageByTool(db, ownerId, days) {
1782
+ const rows = await db.select({
1783
+ tool: ownerUsageDaily.tool,
1784
+ count: sql`sum(${ownerUsageDaily.count})::int`
1785
+ }).from(ownerUsageDaily).where(and(eq(ownerUsageDaily.ownerId, ownerId), gte(ownerUsageDaily.date, windowStart(days)))).groupBy(ownerUsageDaily.tool).orderBy(desc(sql`sum(${ownerUsageDaily.count})`));
1786
+ return rows.map((r) => ({ tool: r.tool, count: Number(r.count) }));
1787
+ }
1788
+
1789
+ // src/core/analytics.ts
1790
+ init_esm_shims();
1791
+ var HOST = "https://us.i.posthog.com";
1792
+ var FLUSH_AT = 50;
1793
+ var FLUSH_MS = 1e4;
1794
+ var queue = [];
1795
+ var timer = null;
1796
+ function capture(distinctId, event, properties = {}) {
1797
+ if (!distinctId || !getConfig().LURQ_POSTHOG_KEY) return;
1798
+ queue.push({
1799
+ event,
1800
+ properties: { ...properties, distinct_id: distinctId },
1801
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1802
+ });
1803
+ if (queue.length >= FLUSH_AT) {
1804
+ void flush();
1805
+ } else if (!timer) {
1806
+ timer = setTimeout(() => void flush(), FLUSH_MS);
1807
+ timer.unref();
1808
+ }
1809
+ }
1810
+ async function flush() {
1811
+ if (timer) {
1812
+ clearTimeout(timer);
1813
+ timer = null;
1814
+ }
1815
+ const key = getConfig().LURQ_POSTHOG_KEY;
1816
+ if (!key || queue.length === 0) return;
1817
+ const batch = queue;
1818
+ queue = [];
1819
+ try {
1820
+ const res = await fetch(`${HOST}/batch/`, {
1821
+ method: "POST",
1822
+ headers: { "Content-Type": "application/json" },
1823
+ body: JSON.stringify({ api_key: key, batch }),
1824
+ signal: AbortSignal.timeout(5e3)
1825
+ });
1826
+ if (!res.ok)
1827
+ logger.warn(`posthog batch rejected (${res.status}), dropped ${batch.length} event(s)`);
1828
+ } catch (err) {
1829
+ logger.warn("posthog batch failed:", err instanceof Error ? err.message : String(err));
1830
+ }
1831
+ }
1832
+
1833
+ // src/mcp/server.ts
1834
+ var npmName = external_exports.string().trim().min(1).max(214).regex(/^(?:@[a-z0-9-][a-z0-9-._]*\/)?[a-z0-9-][a-z0-9-._]*$/i, "Invalid npm package name");
1835
+ var exactVersion = external_exports.string().trim().max(256).refine((v) => import_semver.default.valid(v) !== null, 'Must be an exact semver version, e.g. "19.0.0"');
1836
+ function json(obj) {
1837
+ return { content: [{ type: "text", text: JSON.stringify(compact(obj)) }] };
1838
+ }
1839
+ var SERVER_INSTRUCTIONS = [
1840
+ "lurq answers npm package questions from evidence instead of training data.",
1841
+ "Call verify before installing any package, compat before committing to a set of versions, and usage before writing code against a package API that may have moved.",
1842
+ "When choosing a library, bring the candidates you know and check them with compare or evaluate: lurq verifies choices, it does not search for them.",
1843
+ "If unsure which tool fits, call capabilities.",
1844
+ "When lurq flags a problem (a package that does not exist, a deprecation, an advisory, a version conflict), tell the user what it found and that it came from lurq, with the evidence it returned."
1845
+ ].join(" ");
1846
+ var READ_INDEX = { readOnlyHint: true, openWorldHint: false };
1847
+ var READ_LIVE = { readOnlyHint: true, openWorldHint: true };
1848
+ function buildMcpServer(db, ctx = {}) {
1849
+ const server = new McpServer(
1850
+ { name: SERVER_NAME, version: VERSION },
1851
+ { instructions: SERVER_INSTRUCTIONS }
1852
+ );
1853
+ const run = (tool, fn) => (async () => {
1854
+ let ok = false;
1855
+ try {
1856
+ const result = await timed(tool, fn);
1857
+ ok = true;
1858
+ return result;
1859
+ } finally {
1860
+ void recordUsage(db, ctx.ownerId ?? null, tool);
1861
+ capture(ctx.ownerId, "tool_called", { tool, ok, client: ctx.client ?? null });
1862
+ }
1863
+ })();
1864
+ const reply = (obj) => {
1865
+ const result = json(obj);
1866
+ if (ctx.notice) result.content.push({ type: "text", text: ctx.notice });
1867
+ return result;
1868
+ };
1869
+ server.registerTool(
1870
+ "evaluate",
1871
+ {
1872
+ title: "Evaluate a package",
1873
+ description: "Full evidence read for one npm package: health and quality scores and the signals behind them, advisories, the shared safety verdict, a summary and a usage guide. Use it when a choice needs more than verify's install gate. Enforces the account's dependency policy. A package lurq has never tracked is fetched and scored on demand, waiting up to ~4 seconds; if scoring takes longer the result is `tracked: false` with a note to retry in a few seconds, which is not an answer about the package.",
1874
+ annotations: READ_LIVE,
1875
+ inputSchema: {
1876
+ package: npmName.describe("npm package name")
1877
+ }
1878
+ },
1879
+ async (args) => reply(await run("evaluate", () => handleEvaluate(db, args, ctx.ownerId ?? null)))
1880
+ );
1881
+ server.registerTool(
1882
+ "policy",
1883
+ {
1884
+ title: "Read the dependency policy",
1885
+ description: "The rules this account's selection policy enforces on which packages you may add: denied packages (with the reason), license allowlist, confidence, advisory, adoption, staleness and bundle-size floors. Read it once before choosing dependencies so you pick an allowed package first; evaluate already enforces it. Read-only.",
1886
+ annotations: READ_INDEX,
1887
+ inputSchema: {}
1888
+ },
1889
+ async () => reply(await run("policy", () => handlePolicy(db, ctx.ownerId ?? null)))
1890
+ );
1891
+ server.registerTool(
1892
+ "compare",
1893
+ {
1894
+ title: "Compare packages",
1895
+ description: "Side-by-side comparison of 2\u20135 npm packages you are choosing between, ranked by health score. Untracked names are fetched on demand; one still being scored comes back under `pending` (retry shortly), and a name not on npm under `notFound`.",
1896
+ annotations: READ_LIVE,
1897
+ inputSchema: {
1898
+ packages: external_exports.array(npmName).min(2).max(5).describe("2\u20135 npm package names")
1899
+ }
1900
+ },
1901
+ async (args) => reply(await run("compare", () => handleCompare(db, args, ctx.ownerId ?? null)))
1902
+ );
1903
+ server.registerTool(
1904
+ "compat",
1905
+ {
1906
+ title: "Check package compatibility",
1907
+ description: COMPAT_DESCRIPTION,
1908
+ annotations: READ_LIVE,
1909
+ inputSchema: {
1910
+ packages: external_exports.array(npmName).min(2).max(30).describe(COMPAT_PACKAGES_DESCRIPTION),
1911
+ versions: external_exports.record(exactVersion).optional().describe(COMPAT_VERSIONS_DESCRIPTION),
1912
+ node: external_exports.string().optional().describe(COMPAT_NODE_DESCRIPTION)
1913
+ }
1914
+ },
1915
+ async (args) => reply(await run("compat", () => handleCompat(db, args)))
1916
+ );
1917
+ server.registerTool(
1918
+ "verify",
1919
+ {
1920
+ title: "Verify a package",
1921
+ description: VERIFY_DESCRIPTION,
1922
+ annotations: READ_LIVE,
1923
+ inputSchema: {
1924
+ package: npmName.describe("npm package name to verify")
1925
+ }
1926
+ },
1927
+ async (args) => {
1928
+ const result = await run("verify", () => handleVerify(db, args, ctx.ownerId ?? null));
1929
+ const usable = result.exists && result.verdict.level !== "invalid" && result.verdict.level !== "high";
1930
+ const next = `Before writing code against ${args.package}, call usage with it (and knownVersion if you remember one): its API may have moved since your training.`;
1931
+ return reply(usable ? { ...result, next } : result);
1932
+ }
1933
+ );
1934
+ server.registerTool(
1935
+ "usage",
1936
+ {
1937
+ title: "Version-exact API surface + drift",
1938
+ description: "A package version's TYPED API: exported symbols and their signatures from its shipped .d.ts (or DefinitelyTyped), exact to the version, none of it in the model's training data. Use before writing code against a package whose API may have moved. For whether a name exists at RUNTIME (what decides if an import throws) use resolve_surface; for is-it-safe-to-install use verify. Pass knownVersion (e.g. the version you were trained on) to get the precise delta: added, removed, renamed, changed. Also returns the version's declared engines (Node/runtime floor). Large surfaces are paged, 80 symbols per call: `totalSymbols` is the size, `query` filters by name, `offset` pages. `shallow: true` means the API lives on an interface's members that are not listed, and the note says where to read them. For framework file/convention changes (not exported symbols), consult the official migration guide / Context7 instead.",
1939
+ annotations: READ_LIVE,
1940
+ inputSchema: {
1941
+ package: npmName.describe("npm package name"),
1942
+ version: external_exports.string().optional().describe("Target version (defaults to latest)"),
1943
+ knownVersion: external_exports.string().optional().describe("A version you already know; returns the API delta from it to the target"),
1944
+ query: external_exports.string().max(100).optional().describe("Part of a symbol name (case-insensitive); returns only matching symbols"),
1945
+ offset: external_exports.number().int().min(0).optional().describe("Index of the first symbol to return, to page past the first 80")
1946
+ }
1947
+ },
1948
+ async (args) => reply(await run("usage", () => handleUsage(db, args)))
1949
+ );
1950
+ server.registerTool(
1951
+ "diagram",
1952
+ {
1953
+ title: "Reference architecture diagram",
1954
+ description: "Emit a reference-architecture Mermaid diagram for a stack you have already chosen (package names). A labeled starting point keyed by layer, not a validated architecture, and not an architecture designer.",
1955
+ annotations: READ_INDEX,
1956
+ inputSchema: {
1957
+ stack: external_exports.array(npmName).optional().describe("Package names that make up the stack; omit or empty to get usage guidance")
1958
+ }
1959
+ },
1960
+ async (args) => reply(await run("diagram", () => handleDiagram(db, args)))
1961
+ );
1962
+ server.registerTool(
1963
+ "resolve_surface",
1964
+ {
1965
+ title: "Version-exact runtime surface",
1966
+ description: "What a package version ACTUALLY exports at runtime, extracted from its shipped JavaScript rather than from documentation or the model's memory: names and arity, not type signatures (use usage for those). Call before writing code against a package whose API may have moved. Runtime existence is what decides whether an import throws; a removed type breaks tsc, a removed runtime symbol breaks the program. A miss returns UNKNOWN and queues extraction, UNKNOWN never means the symbol is absent.",
1967
+ annotations: READ_LIVE,
1968
+ inputSchema: {
1969
+ package: npmName.describe("npm package name"),
1970
+ version: external_exports.string().optional().describe("Exact version; omit for the latest extracted")
1971
+ }
1972
+ },
1973
+ async (args) => reply(await run("resolve_surface", () => handleResolveSurface(db, args)))
1974
+ );
1975
+ server.registerTool(
1976
+ "diff_surface",
1977
+ {
1978
+ title: "Surface diff between two versions",
1979
+ description: 'What changed in a package\'s runtime surface between two versions: symbols removed, added, and arity changes, plus renames the package itself proves (a removed name that shared one declaration with a name the new version still exports). Removals break `node`; type-only removals are returned separately because they break `tsc` instead. Answers "when did this stop working" from static comparison, with no install required. Use before an upgrade, and to explain a break after one.',
1980
+ annotations: READ_LIVE,
1981
+ inputSchema: {
1982
+ package: npmName.describe("npm package name"),
1983
+ fromVersion: external_exports.string().describe("Version you are on"),
1984
+ toVersion: external_exports.string().describe("Version you are moving to")
1985
+ }
1986
+ },
1987
+ async (args) => reply(
1988
+ await run("diff_surface", async () => {
1989
+ const diff = await handleDiffSurface(db, args);
1990
+ if (diff.verdict === "unknown") return diff;
1991
+ const { upgradeGuideFor } = await import("./publicUpgrades-WTBGLDIK.js");
1992
+ const guide = await upgradeGuideFor(
1993
+ db,
1994
+ args.package,
1995
+ args.fromVersion,
1996
+ args.toVersion,
1997
+ getConfig().LURQ_WEB_URL
1998
+ ).catch(() => null);
1999
+ return guide ? { ...diff, upgradeGuide: guide } : diff;
2000
+ })
2001
+ )
2002
+ );
2003
+ server.registerTool(
2004
+ "mcp_stack",
2005
+ {
2006
+ title: "Do these MCP servers coexist?",
2007
+ description: "Check whether a set of MCP servers can be wired into one agent together. The npm question does not apply \u2014 servers are separate processes with nothing to resolve between them. They clash in the single flat TOOL NAMESPACE the agent assembles from all of them: two servers exposing the same tool name leave the agent unable to express which it means, and nothing errors, one simply shadows the other. Also reports the standing context cost, since every tool's schema rides in every request. Pass `tools` for a server when you already hold its tool list (any server: remote, PyPI, Docker, private) and it is analysed as-is; otherwise the npm server's probed surface is used, and one that has not been probed makes the answer UNKNOWN, never clean.",
2008
+ annotations: READ_INDEX,
2009
+ inputSchema: {
2010
+ servers: external_exports.array(
2011
+ external_exports.object({
2012
+ server: external_exports.string().trim().min(1).max(300).describe(
2013
+ "npm package name of the MCP server, or any label when `tools` is given"
2014
+ ),
2015
+ version: external_exports.string().max(100).nullable().optional(),
2016
+ tools: external_exports.array(
2017
+ external_exports.object({
2018
+ name: external_exports.string().min(1).max(256),
2019
+ annotations: external_exports.record(external_exports.unknown()).optional()
2020
+ })
2021
+ ).max(2e3).optional().describe(
2022
+ "The tool list as the agent received it; names and annotations are enough"
2023
+ )
2024
+ }).refine((s) => s.tools !== void 0 || npmName.safeParse(s.server).success, {
2025
+ message: "server must be an npm package name unless tools are given"
2026
+ })
2027
+ ).min(1).max(50).describe("The servers configured into one agent")
2028
+ }
2029
+ },
2030
+ async (args) => reply(
2031
+ await run("mcp_stack", async () => {
2032
+ const { checkMcpStack } = await import("./mcpStack-ZNYIFXZ5.js");
2033
+ return checkMcpStack(
2034
+ db,
2035
+ args.servers.map((s) => ({
2036
+ server: s.server,
2037
+ version: s.version ?? null,
2038
+ tools: s.tools
2039
+ }))
2040
+ );
2041
+ })
2042
+ )
2043
+ );
2044
+ server.registerTool(
2045
+ "mcp_surface",
2046
+ {
2047
+ title: "An MCP server's tool contract",
2048
+ description: "What an MCP server ACTUALLY exposes: every tool, its required and optional parameters, and its behaviour annotations, read from a live `tools/list` handshake in a sandbox rather than from a README or the model's memory. Call before wiring an agent to a server, or when a tool call is failing for reasons the error does not explain. Also returns `requires` \u2014 the API keys and settings the server declares it needs \u2014 and `configRequest`, a ready-made line to put in front of your user when something is missing, so 'it needs a token' never presents as 'it is broken'. A miss returns UNKNOWN and queues a probe; UNKNOWN never means the server has no tools.",
2049
+ annotations: READ_LIVE,
2050
+ inputSchema: {
2051
+ server: npmName.describe("npm package name of the MCP server"),
2052
+ version: external_exports.string().optional().describe("Exact version; omit for the latest probed")
2053
+ }
2054
+ },
2055
+ async (args) => reply(await run("mcp_surface", () => handleMcpSurface(db, args)))
2056
+ );
2057
+ server.registerTool(
2058
+ "mcp_drift",
2059
+ {
2060
+ title: "MCP tool-contract drift between two versions",
2061
+ description: "What moved in an MCP server's tool contract between two versions: tools removed, parameters that became required, types narrowed, and annotation flips. Two findings here have no npm equivalent and are why this exists. SILENT DRIFT is a schema that changed while its description stayed byte-identical, invisible to anyone reading a changelog. PRIVILEGE WIDENING is a tool that stopped being read-only or started being destructive, which does not break anything and is worse than a break. Use before upgrading a server an agent depends on.",
2062
+ annotations: READ_INDEX,
2063
+ inputSchema: {
2064
+ server: npmName.describe("npm package name of the MCP server"),
2065
+ fromVersion: external_exports.string().describe("Version you are on"),
2066
+ toVersion: external_exports.string().describe("Version you are moving to")
2067
+ }
2068
+ },
2069
+ async (args) => reply(await run("mcp_drift", () => handleMcpDrift(db, args)))
2070
+ );
2071
+ server.registerTool(
2072
+ "connect_check",
2073
+ {
2074
+ title: "Will this MCP server work in my client?",
2075
+ description: "Before wiring an MCP server into a client, find out whether it will work there and exactly what it takes. Accepts an endpoint URL, an official-registry server name, or an npm package name. Answers per client (Claude Code, Claude.ai, ChatGPT, Cursor, VS Code, Codex, Gemini CLI and more): WORKS; NEEDS_SETUP with the steps (a key to send as a header, an OAuth client to pre-register and the redirect URIs to allow, a URL placeholder to fill); BLOCKED with the reason and which side causes it; or UNKNOWN when a decisive fact is not established. Built from a credential-free probe of the endpoint (whether it answers, how it authenticates, which OAuth registration methods it offers, spec deviations strict clients refuse, tool names and schemas) and from primary-sourced client constraints. Returns ready-to-paste config in each client's own format, with placeholder values. Tell the user what it found, including which client it was checked for. UNKNOWN never means it will not work.",
2076
+ annotations: READ_LIVE,
2077
+ inputSchema: {
2078
+ server: external_exports.string().trim().min(1).max(2048).describe(
2079
+ "Endpoint URL (https://\u2026), official registry name (io.github.acme/weather), or npm package name"
2080
+ ),
2081
+ client: external_exports.enum(CLIENT_IDS).optional().describe(
2082
+ "One client to check, e.g. claude-code, cursor, chatgpt; omit for every client"
2083
+ )
2084
+ }
2085
+ },
2086
+ async (args) => reply(
2087
+ await run("connect_check", async () => {
2088
+ const [{ handleConnectCheck }, { sharedSafeFetch }] = await Promise.all([
2089
+ import("./check-2JTQDQA6.js"),
2090
+ import("./safeFetch-COERXGFN.js")
2091
+ ]);
2092
+ return handleConnectCheck(
2093
+ db,
2094
+ { server: args.server, client: args.client ?? null },
2095
+ { liveProbe: { fetch: sharedSafeFetch() } }
2096
+ );
2097
+ })
2098
+ )
2099
+ );
2100
+ if (ctx.local) {
2101
+ server.registerTool(
2102
+ "upkeep",
2103
+ {
2104
+ title: "What needs fixing in this project",
2105
+ description: "The upkeep plan for the project you are editing, read from its own files. Returns findings across domains: environment variables the code reads that no .env file declares, model identifiers the provider has retired or put an end date on, and \u2014 when you pass `upgrade` \u2014 the call sites an upgrade breaks, the replacement the package itself proves, and the manifest ranges left stale. Each finding carries either exact edits (a rename the package proves, byte ranges you can apply) or a brief with the facts you cannot look up: the exports the target version actually ships, with their kinds and arities. A domain that could not run says so; a skipped domain is never the same as a clean one. Needs no API key. Use it before editing a project you have just opened, or after an upgrade to see what it broke.",
2106
+ annotations: READ_LIVE,
2107
+ inputSchema: {
2108
+ dir: external_exports.string().max(4096).optional().describe(
2109
+ "Project root. Defaults to the working directory this server was started in."
2110
+ ),
2111
+ upgrade: external_exports.array(
2112
+ external_exports.object({
2113
+ package: npmName,
2114
+ fromVersion: external_exports.string().min(1).max(100),
2115
+ toVersion: external_exports.string().min(1).max(100)
2116
+ })
2117
+ ).max(50).optional().describe(
2118
+ "Upgrades to assess. Without this the package domain is skipped, because working out what moved needs the index and this tool runs without a key."
2119
+ ),
2120
+ domains: external_exports.array(external_exports.enum(["package", "mcp-config", "env", "api", "model"])).max(5).optional().describe("Limit to these domains. Default: every domain with a detector.")
2121
+ }
2122
+ },
2123
+ async (args) => reply(
2124
+ await run("upkeep", async () => {
2125
+ const { handleUpkeep } = await import("./upkeepHandler-VFGYXJKB.js");
2126
+ return handleUpkeep(args);
2127
+ })
2128
+ )
2129
+ );
2130
+ }
2131
+ server.registerTool(
2132
+ "audit",
2133
+ {
2134
+ title: "Audit a whole project",
2135
+ description: "Assess an entire project's dependencies in ONE call: which packages are outdated, deprecated or carry advisories for the exact installed version, and which configured MCP servers have drifted, need credentials, or cannot be observed at all. Send the inventory you read locally (names and versions only \u2014 never source). Returns a per-item verdict plus an explicit coverage count: how many were answered, how many are queued because the index has not seen them, and how many were skipped and why. An item lurq could not assess is reported as unassessed, never as clean.",
2136
+ annotations: READ_LIVE,
2137
+ inputSchema: {
2138
+ packages: external_exports.array(
2139
+ external_exports.object({
2140
+ name: npmName,
2141
+ range: external_exports.string().optional().describe("Declared range, e.g. ^6.4.0"),
2142
+ installed: external_exports.string().nullable().optional().describe(
2143
+ "Resolved version from the lockfile or node_modules \u2014 what actually runs"
2144
+ )
2145
+ })
2146
+ ).max(600).optional().describe("npm dependencies read from package.json + lockfile"),
2147
+ mcpServers: external_exports.array(
2148
+ external_exports.object({
2149
+ alias: external_exports.string().max(200).optional(),
2150
+ kind: external_exports.enum(["npm-stdio", "remote", "local", "other-registry"]).optional().describe("How it launches; decides whether lurq can read its contract"),
2151
+ packageName: external_exports.string().max(300).nullable().optional(),
2152
+ version: external_exports.string().max(100).nullable().optional(),
2153
+ endpoint: external_exports.string().max(300).nullable().optional()
2154
+ })
2155
+ ).max(200).optional().describe("MCP servers read from .mcp.json / agent configs")
2156
+ }
2157
+ },
2158
+ async (args) => reply(await run("audit", () => handleAudit(db, args, ctx.ownerId ?? null)))
2159
+ );
2160
+ server.registerTool(
2161
+ "capabilities",
2162
+ {
2163
+ title: "What lurq can do",
2164
+ description: "Look up which lurq tool answers a situation, and what to run next. Call when you're unsure whether lurq covers something (an upgrade, a licence rule, a version's exact exports, publishing a package) instead of guessing or skipping it. Returns matching capabilities with the tool or command to use.",
2165
+ annotations: READ_INDEX,
2166
+ inputSchema: {
2167
+ query: external_exports.string().max(300).optional().describe("What you are trying to do, in plain words. Omit for the full menu.")
2168
+ }
2169
+ },
2170
+ async (args) => reply({ capabilities: searchCapabilities(args.query ?? "", 6) })
2171
+ );
2172
+ server.registerTool(
2173
+ "report_outcome",
2174
+ {
2175
+ title: "Report how a package worked out",
2176
+ description: "Opt-in feedback after you act on lurq's evidence about a package (verify, evaluate, compare, compat): whether you went with it and whether it built. No source code, only the coarse decision + a build signal. Helps lurq learn which packages agents actually succeed with; safe to skip.",
2177
+ // The one tool that writes: each call appends a row, so a repeat is a
2178
+ // second report, not a no-op.
2179
+ annotations: {
2180
+ readOnlyHint: false,
2181
+ destructiveHint: false,
2182
+ idempotentHint: false,
2183
+ openWorldHint: false
2184
+ },
2185
+ inputSchema: {
2186
+ package: npmName.describe("The package you decided on"),
2187
+ accepted: external_exports.boolean().describe("Did you go with this package?"),
2188
+ buildSignal: external_exports.enum(["installed", "compiled", "tests_passed", "failed"]).optional().describe("Coarse post-install result, if known"),
2189
+ need: external_exports.string().max(500).optional().describe("What you needed the package for, in plain words (no source code)")
2190
+ }
2191
+ },
2192
+ // ownerId comes from the authenticated key (ctx), NOT the tool arguments —
2193
+ // a caller must never be able to attribute an outcome to another org.
2194
+ async (args) => reply(await run("report_outcome", () => handleReportOutcome(db, args, ctx.ownerId ?? null)))
2195
+ );
2196
+ server.server.registerCapabilities({ resources: {}, prompts: {} });
2197
+ server.server.setRequestHandler(ListResourcesRequestSchema, () => ({ resources: [] }));
2198
+ server.server.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({
2199
+ resourceTemplates: []
2200
+ }));
2201
+ server.server.setRequestHandler(ListPromptsRequestSchema, () => ({ prompts: [] }));
2202
+ return server;
2203
+ }
2204
+ var SERVE_NEEDS_DATABASE = "`lurq serve` answers from a local lurq index and needs DATABASE_URL, which is not set. To use lurq from an agent without running your own index, connect it to the hosted service instead: run `npx lurqrun` and it writes the MCP entry for your assistants. To self-host, set DATABASE_URL to a migrated lurq index.";
2205
+ async function startMcpServer() {
2206
+ if (!getConfig().DATABASE_URL) throw new Error(SERVE_NEEDS_DATABASE);
2207
+ const { db, close } = createDb();
2208
+ const server = buildMcpServer(db, { local: true });
2209
+ const shutdown = async () => {
2210
+ try {
2211
+ await close();
2212
+ } finally {
2213
+ process.exit(0);
2214
+ }
2215
+ };
2216
+ process.on("SIGINT", shutdown);
2217
+ process.on("SIGTERM", shutdown);
2218
+ const transport = new StdioServerTransport();
2219
+ await server.connect(transport);
2220
+ logger.info(`${SERVER_NAME} MCP server v${VERSION} running on stdio.`);
2221
+ }
2222
+
2223
+ export {
2224
+ renderPrometheus,
2225
+ recordUsage,
2226
+ getUsageSummary,
2227
+ getUsageByTool,
2228
+ capture,
2229
+ flush,
2230
+ npmName,
2231
+ exactVersion,
2232
+ buildMcpServer,
2233
+ SERVE_NEEDS_DATABASE,
2234
+ startMcpServer
2235
+ };