@nimrobo/mcporter-remote 0.1.0

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 (741) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.gitattributes +2 -0
  3. package/.github/workflows/ci.yml +26 -0
  4. package/AGENTS.md +109 -0
  5. package/CHANGELOG.md +361 -0
  6. package/LICENSE +21 -0
  7. package/README.md +449 -0
  8. package/bin/git +180 -0
  9. package/biome.json +43 -0
  10. package/config/mcporter.json +134 -0
  11. package/dist/cli/adhoc-server.d.ts +21 -0
  12. package/dist/cli/adhoc-server.d.ts.map +1 -0
  13. package/dist/cli/adhoc-server.js +228 -0
  14. package/dist/cli/adhoc-server.js.map +1 -0
  15. package/dist/cli/auth-command.d.ts +6 -0
  16. package/dist/cli/auth-command.d.ts.map +1 -0
  17. package/dist/cli/auth-command.js +257 -0
  18. package/dist/cli/auth-command.js.map +1 -0
  19. package/dist/cli/call-argument-expression.d.ts +5 -0
  20. package/dist/cli/call-argument-expression.d.ts.map +1 -0
  21. package/dist/cli/call-argument-expression.js +57 -0
  22. package/dist/cli/call-argument-expression.js.map +1 -0
  23. package/dist/cli/call-argument-values.d.ts +10 -0
  24. package/dist/cli/call-argument-values.d.ts.map +1 -0
  25. package/dist/cli/call-argument-values.js +83 -0
  26. package/dist/cli/call-argument-values.js.map +1 -0
  27. package/dist/cli/call-arguments.d.ts +17 -0
  28. package/dist/cli/call-arguments.d.ts.map +1 -0
  29. package/dist/cli/call-arguments.js +183 -0
  30. package/dist/cli/call-arguments.js.map +1 -0
  31. package/dist/cli/call-command.d.ts +5 -0
  32. package/dist/cli/call-command.d.ts.map +1 -0
  33. package/dist/cli/call-command.js +371 -0
  34. package/dist/cli/call-command.js.map +1 -0
  35. package/dist/cli/call-expression-parser.d.ts +9 -0
  36. package/dist/cli/call-expression-parser.d.ts.map +1 -0
  37. package/dist/cli/call-expression-parser.js +177 -0
  38. package/dist/cli/call-expression-parser.js.map +1 -0
  39. package/dist/cli/cli-factory.d.ts +16 -0
  40. package/dist/cli/cli-factory.d.ts.map +1 -0
  41. package/dist/cli/cli-factory.js +37 -0
  42. package/dist/cli/cli-factory.js.map +1 -0
  43. package/dist/cli/command-inference.d.ts +12 -0
  44. package/dist/cli/command-inference.d.ts.map +1 -0
  45. package/dist/cli/command-inference.js +75 -0
  46. package/dist/cli/command-inference.js.map +1 -0
  47. package/dist/cli/config/add.d.ts +23 -0
  48. package/dist/cli/config/add.d.ts.map +1 -0
  49. package/dist/cli/config/add.js +267 -0
  50. package/dist/cli/config/add.js.map +1 -0
  51. package/dist/cli/config/auth.d.ts +4 -0
  52. package/dist/cli/config/auth.d.ts.map +1 -0
  53. package/dist/cli/config/auth.js +21 -0
  54. package/dist/cli/config/auth.js.map +1 -0
  55. package/dist/cli/config/doctor.d.ts +3 -0
  56. package/dist/cli/config/doctor.d.ts.map +1 -0
  57. package/dist/cli/config/doctor.js +26 -0
  58. package/dist/cli/config/doctor.js.map +1 -0
  59. package/dist/cli/config/get.d.ts +3 -0
  60. package/dist/cli/config/get.d.ts.map +1 -0
  61. package/dist/cli/config/get.js +45 -0
  62. package/dist/cli/config/get.js.map +1 -0
  63. package/dist/cli/config/help.d.ts +18 -0
  64. package/dist/cli/config/help.d.ts.map +1 -0
  65. package/dist/cli/config/help.js +193 -0
  66. package/dist/cli/config/help.js.map +1 -0
  67. package/dist/cli/config/import.d.ts +9 -0
  68. package/dist/cli/config/import.d.ts.map +1 -0
  69. package/dist/cli/config/import.js +88 -0
  70. package/dist/cli/config/import.js.map +1 -0
  71. package/dist/cli/config/index.d.ts +2 -0
  72. package/dist/cli/config/index.d.ts.map +1 -0
  73. package/dist/cli/config/index.js +2 -0
  74. package/dist/cli/config/index.js.map +1 -0
  75. package/dist/cli/config/list.d.ts +7 -0
  76. package/dist/cli/config/list.d.ts.map +1 -0
  77. package/dist/cli/config/list.js +71 -0
  78. package/dist/cli/config/list.js.map +1 -0
  79. package/dist/cli/config/remove.d.ts +3 -0
  80. package/dist/cli/config/remove.d.ts.map +1 -0
  81. package/dist/cli/config/remove.js +19 -0
  82. package/dist/cli/config/remove.js.map +1 -0
  83. package/dist/cli/config/render.d.ts +26 -0
  84. package/dist/cli/config/render.d.ts.map +1 -0
  85. package/dist/cli/config/render.js +99 -0
  86. package/dist/cli/config/render.js.map +1 -0
  87. package/dist/cli/config/shared.d.ts +21 -0
  88. package/dist/cli/config/shared.d.ts.map +1 -0
  89. package/dist/cli/config/shared.js +130 -0
  90. package/dist/cli/config/shared.js.map +1 -0
  91. package/dist/cli/config/types.d.ts +7 -0
  92. package/dist/cli/config/types.d.ts.map +1 -0
  93. package/dist/cli/config/types.js +2 -0
  94. package/dist/cli/config/types.js.map +1 -0
  95. package/dist/cli/config-command.d.ts +7 -0
  96. package/dist/cli/config-command.d.ts.map +1 -0
  97. package/dist/cli/config-command.js +67 -0
  98. package/dist/cli/config-command.js.map +1 -0
  99. package/dist/cli/daemon-command.d.ts +8 -0
  100. package/dist/cli/daemon-command.d.ts.map +1 -0
  101. package/dist/cli/daemon-command.js +219 -0
  102. package/dist/cli/daemon-command.js.map +1 -0
  103. package/dist/cli/emit-ts-command.d.ts +31 -0
  104. package/dist/cli/emit-ts-command.d.ts.map +1 -0
  105. package/dist/cli/emit-ts-command.js +217 -0
  106. package/dist/cli/emit-ts-command.js.map +1 -0
  107. package/dist/cli/emit-ts-templates.d.ts +23 -0
  108. package/dist/cli/emit-ts-templates.d.ts.map +1 -0
  109. package/dist/cli/emit-ts-templates.js +130 -0
  110. package/dist/cli/emit-ts-templates.js.map +1 -0
  111. package/dist/cli/ephemeral-flags.d.ts +7 -0
  112. package/dist/cli/ephemeral-flags.d.ts.map +1 -0
  113. package/dist/cli/ephemeral-flags.js +108 -0
  114. package/dist/cli/ephemeral-flags.js.map +1 -0
  115. package/dist/cli/ephemeral-target.d.ts +16 -0
  116. package/dist/cli/ephemeral-target.d.ts.map +1 -0
  117. package/dist/cli/ephemeral-target.js +105 -0
  118. package/dist/cli/ephemeral-target.js.map +1 -0
  119. package/dist/cli/errors.d.ts +4 -0
  120. package/dist/cli/errors.d.ts.map +1 -0
  121. package/dist/cli/errors.js +7 -0
  122. package/dist/cli/errors.js.map +1 -0
  123. package/dist/cli/flag-utils.d.ts +4 -0
  124. package/dist/cli/flag-utils.d.ts.map +1 -0
  125. package/dist/cli/flag-utils.js +27 -0
  126. package/dist/cli/flag-utils.js.map +1 -0
  127. package/dist/cli/generate/artifacts.d.ts +15 -0
  128. package/dist/cli/generate/artifacts.d.ts.map +1 -0
  129. package/dist/cli/generate/artifacts.js +247 -0
  130. package/dist/cli/generate/artifacts.js.map +1 -0
  131. package/dist/cli/generate/definition.d.ts +22 -0
  132. package/dist/cli/generate/definition.d.ts.map +1 -0
  133. package/dist/cli/generate/definition.js +265 -0
  134. package/dist/cli/generate/definition.js.map +1 -0
  135. package/dist/cli/generate/flag-parser.d.ts +11 -0
  136. package/dist/cli/generate/flag-parser.d.ts.map +1 -0
  137. package/dist/cli/generate/flag-parser.js +41 -0
  138. package/dist/cli/generate/flag-parser.js.map +1 -0
  139. package/dist/cli/generate/flags.d.ts +20 -0
  140. package/dist/cli/generate/flags.d.ts.map +1 -0
  141. package/dist/cli/generate/flags.js +220 -0
  142. package/dist/cli/generate/flags.js.map +1 -0
  143. package/dist/cli/generate/fs-helpers.d.ts +3 -0
  144. package/dist/cli/generate/fs-helpers.d.ts.map +1 -0
  145. package/dist/cli/generate/fs-helpers.js +34 -0
  146. package/dist/cli/generate/fs-helpers.js.map +1 -0
  147. package/dist/cli/generate/name-utils.d.ts +5 -0
  148. package/dist/cli/generate/name-utils.d.ts.map +1 -0
  149. package/dist/cli/generate/name-utils.js +170 -0
  150. package/dist/cli/generate/name-utils.js.map +1 -0
  151. package/dist/cli/generate/output.d.ts +5 -0
  152. package/dist/cli/generate/output.d.ts.map +1 -0
  153. package/dist/cli/generate/output.js +24 -0
  154. package/dist/cli/generate/output.js.map +1 -0
  155. package/dist/cli/generate/runtime.d.ts +3 -0
  156. package/dist/cli/generate/runtime.d.ts.map +1 -0
  157. package/dist/cli/generate/runtime.js +34 -0
  158. package/dist/cli/generate/runtime.js.map +1 -0
  159. package/dist/cli/generate/server-utils.d.ts +3 -0
  160. package/dist/cli/generate/server-utils.d.ts.map +1 -0
  161. package/dist/cli/generate/server-utils.js +33 -0
  162. package/dist/cli/generate/server-utils.js.map +1 -0
  163. package/dist/cli/generate/template-data.d.ts +25 -0
  164. package/dist/cli/generate/template-data.d.ts.map +1 -0
  165. package/dist/cli/generate/template-data.js +90 -0
  166. package/dist/cli/generate/template-data.js.map +1 -0
  167. package/dist/cli/generate/template-help.d.ts +2 -0
  168. package/dist/cli/generate/template-help.d.ts.map +1 -0
  169. package/dist/cli/generate/template-help.js +113 -0
  170. package/dist/cli/generate/template-help.js.map +1 -0
  171. package/dist/cli/generate/template.d.ts +30 -0
  172. package/dist/cli/generate/template.d.ts.map +1 -0
  173. package/dist/cli/generate/template.js +366 -0
  174. package/dist/cli/generate/template.js.map +1 -0
  175. package/dist/cli/generate/tools.d.ts +46 -0
  176. package/dist/cli/generate/tools.d.ts.map +1 -0
  177. package/dist/cli/generate/tools.js +304 -0
  178. package/dist/cli/generate/tools.js.map +1 -0
  179. package/dist/cli/generate/types.d.ts +5 -0
  180. package/dist/cli/generate/types.d.ts.map +1 -0
  181. package/dist/cli/generate/types.js +2 -0
  182. package/dist/cli/generate/types.js.map +1 -0
  183. package/dist/cli/generate-cli-runner.d.ts +3 -0
  184. package/dist/cli/generate-cli-runner.d.ts.map +1 -0
  185. package/dist/cli/generate-cli-runner.js +72 -0
  186. package/dist/cli/generate-cli-runner.js.map +1 -0
  187. package/dist/cli/help-output.d.ts +6 -0
  188. package/dist/cli/help-output.d.ts.map +1 -0
  189. package/dist/cli/help-output.js +186 -0
  190. package/dist/cli/help-output.js.map +1 -0
  191. package/dist/cli/http-utils.d.ts +9 -0
  192. package/dist/cli/http-utils.d.ts.map +1 -0
  193. package/dist/cli/http-utils.js +88 -0
  194. package/dist/cli/http-utils.js.map +1 -0
  195. package/dist/cli/identifier-helpers.d.ts +20 -0
  196. package/dist/cli/identifier-helpers.d.ts.map +1 -0
  197. package/dist/cli/identifier-helpers.js +84 -0
  198. package/dist/cli/identifier-helpers.js.map +1 -0
  199. package/dist/cli/image-output.d.ts +3 -0
  200. package/dist/cli/image-output.d.ts.map +1 -0
  201. package/dist/cli/image-output.js +57 -0
  202. package/dist/cli/image-output.js.map +1 -0
  203. package/dist/cli/inspect-cli-command.d.ts +11 -0
  204. package/dist/cli/inspect-cli-command.d.ts.map +1 -0
  205. package/dist/cli/inspect-cli-command.js +78 -0
  206. package/dist/cli/inspect-cli-command.js.map +1 -0
  207. package/dist/cli/json-output.d.ts +23 -0
  208. package/dist/cli/json-output.d.ts.map +1 -0
  209. package/dist/cli/json-output.js +38 -0
  210. package/dist/cli/json-output.js.map +1 -0
  211. package/dist/cli/list-command.d.ts +15 -0
  212. package/dist/cli/list-command.d.ts.map +1 -0
  213. package/dist/cli/list-command.js +372 -0
  214. package/dist/cli/list-command.js.map +1 -0
  215. package/dist/cli/list-detail-helpers.d.ts +41 -0
  216. package/dist/cli/list-detail-helpers.d.ts.map +1 -0
  217. package/dist/cli/list-detail-helpers.js +99 -0
  218. package/dist/cli/list-detail-helpers.js.map +1 -0
  219. package/dist/cli/list-doc-comments.d.ts +6 -0
  220. package/dist/cli/list-doc-comments.d.ts.map +1 -0
  221. package/dist/cli/list-doc-comments.js +114 -0
  222. package/dist/cli/list-doc-comments.js.map +1 -0
  223. package/dist/cli/list-format.d.ts +38 -0
  224. package/dist/cli/list-format.d.ts.map +1 -0
  225. package/dist/cli/list-format.js +98 -0
  226. package/dist/cli/list-format.js.map +1 -0
  227. package/dist/cli/list-output.d.ts +39 -0
  228. package/dist/cli/list-output.d.ts.map +1 -0
  229. package/dist/cli/list-output.js +159 -0
  230. package/dist/cli/list-output.js.map +1 -0
  231. package/dist/cli/list-signature.d.ts +26 -0
  232. package/dist/cli/list-signature.d.ts.map +1 -0
  233. package/dist/cli/list-signature.js +176 -0
  234. package/dist/cli/list-signature.js.map +1 -0
  235. package/dist/cli/logger-context.d.ts +9 -0
  236. package/dist/cli/logger-context.d.ts.map +1 -0
  237. package/dist/cli/logger-context.js +29 -0
  238. package/dist/cli/logger-context.js.map +1 -0
  239. package/dist/cli/output-format.d.ts +11 -0
  240. package/dist/cli/output-format.d.ts.map +1 -0
  241. package/dist/cli/output-format.js +51 -0
  242. package/dist/cli/output-format.js.map +1 -0
  243. package/dist/cli/output-utils.d.ts +5 -0
  244. package/dist/cli/output-utils.d.ts.map +1 -0
  245. package/dist/cli/output-utils.js +143 -0
  246. package/dist/cli/output-utils.js.map +1 -0
  247. package/dist/cli/path-utils.d.ts +2 -0
  248. package/dist/cli/path-utils.d.ts.map +1 -0
  249. package/dist/cli/path-utils.js +12 -0
  250. package/dist/cli/path-utils.js.map +1 -0
  251. package/dist/cli/runtime-debug.d.ts +4 -0
  252. package/dist/cli/runtime-debug.d.ts.map +1 -0
  253. package/dist/cli/runtime-debug.js +134 -0
  254. package/dist/cli/runtime-debug.js.map +1 -0
  255. package/dist/cli/server-lookup.d.ts +3 -0
  256. package/dist/cli/server-lookup.d.ts.map +1 -0
  257. package/dist/cli/server-lookup.js +21 -0
  258. package/dist/cli/server-lookup.js.map +1 -0
  259. package/dist/cli/terminal.d.ts +10 -0
  260. package/dist/cli/terminal.d.ts.map +1 -0
  261. package/dist/cli/terminal.js +33 -0
  262. package/dist/cli/terminal.js.map +1 -0
  263. package/dist/cli/timeouts.d.ts +9 -0
  264. package/dist/cli/timeouts.d.ts.map +1 -0
  265. package/dist/cli/timeouts.js +55 -0
  266. package/dist/cli/timeouts.js.map +1 -0
  267. package/dist/cli/tool-cache.d.ts +9 -0
  268. package/dist/cli/tool-cache.d.ts.map +1 -0
  269. package/dist/cli/tool-cache.js +31 -0
  270. package/dist/cli/tool-cache.js.map +1 -0
  271. package/dist/cli/transport-utils.d.ts +3 -0
  272. package/dist/cli/transport-utils.d.ts.map +1 -0
  273. package/dist/cli/transport-utils.js +9 -0
  274. package/dist/cli/transport-utils.js.map +1 -0
  275. package/dist/cli-metadata.d.ts +57 -0
  276. package/dist/cli-metadata.d.ts.map +1 -0
  277. package/dist/cli-metadata.js +92 -0
  278. package/dist/cli-metadata.js.map +1 -0
  279. package/dist/cli.d.ts +10 -0
  280. package/dist/cli.d.ts.map +1 -0
  281. package/dist/cli.js +217 -0
  282. package/dist/cli.js.map +1 -0
  283. package/dist/config/imports/external.d.ts +8 -0
  284. package/dist/config/imports/external.d.ts.map +1 -0
  285. package/dist/config/imports/external.js +231 -0
  286. package/dist/config/imports/external.js.map +1 -0
  287. package/dist/config/imports/paths-utils.d.ts +3 -0
  288. package/dist/config/imports/paths-utils.d.ts.map +1 -0
  289. package/dist/config/imports/paths-utils.js +27 -0
  290. package/dist/config/imports/paths-utils.js.map +1 -0
  291. package/dist/config/imports/paths.d.ts +3 -0
  292. package/dist/config/imports/paths.d.ts.map +1 -0
  293. package/dist/config/imports/paths.js +135 -0
  294. package/dist/config/imports/paths.js.map +1 -0
  295. package/dist/config/imports/shared.d.ts +4 -0
  296. package/dist/config/imports/shared.d.ts.map +1 -0
  297. package/dist/config/imports/shared.js +25 -0
  298. package/dist/config/imports/shared.js.map +1 -0
  299. package/dist/config/path-discovery.d.ts +11 -0
  300. package/dist/config/path-discovery.d.ts.map +1 -0
  301. package/dist/config/path-discovery.js +65 -0
  302. package/dist/config/path-discovery.js.map +1 -0
  303. package/dist/config/read-config.d.ts +9 -0
  304. package/dist/config/read-config.d.ts.map +1 -0
  305. package/dist/config/read-config.js +74 -0
  306. package/dist/config/read-config.js.map +1 -0
  307. package/dist/config-imports.d.ts +7 -0
  308. package/dist/config-imports.d.ts.map +1 -0
  309. package/dist/config-imports.js +8 -0
  310. package/dist/config-imports.js.map +1 -0
  311. package/dist/config-normalize.d.ts +8 -0
  312. package/dist/config-normalize.d.ts.map +1 -0
  313. package/dist/config-normalize.js +184 -0
  314. package/dist/config-normalize.js.map +1 -0
  315. package/dist/config-schema.d.ts +164 -0
  316. package/dist/config-schema.d.ts.map +1 -0
  317. package/dist/config-schema.js +103 -0
  318. package/dist/config-schema.js.map +1 -0
  319. package/dist/config.d.ts +17 -0
  320. package/dist/config.d.ts.map +1 -0
  321. package/dist/config.js +91 -0
  322. package/dist/config.js.map +1 -0
  323. package/dist/daemon/client.d.ts +34 -0
  324. package/dist/daemon/client.d.ts.map +1 -0
  325. package/dist/daemon/client.js +291 -0
  326. package/dist/daemon/client.js.map +1 -0
  327. package/dist/daemon/config-layers.d.ts +7 -0
  328. package/dist/daemon/config-layers.d.ts.map +1 -0
  329. package/dist/daemon/config-layers.js +20 -0
  330. package/dist/daemon/config-layers.js.map +1 -0
  331. package/dist/daemon/host.d.ts +32 -0
  332. package/dist/daemon/host.d.ts.map +1 -0
  333. package/dist/daemon/host.js +345 -0
  334. package/dist/daemon/host.js.map +1 -0
  335. package/dist/daemon/launch.d.ts +10 -0
  336. package/dist/daemon/launch.d.ts.map +1 -0
  337. package/dist/daemon/launch.js +35 -0
  338. package/dist/daemon/launch.js.map +1 -0
  339. package/dist/daemon/log-context.d.ts +18 -0
  340. package/dist/daemon/log-context.d.ts.map +1 -0
  341. package/dist/daemon/log-context.js +64 -0
  342. package/dist/daemon/log-context.js.map +1 -0
  343. package/dist/daemon/paths.d.ts +5 -0
  344. package/dist/daemon/paths.d.ts.map +1 -0
  345. package/dist/daemon/paths.js +30 -0
  346. package/dist/daemon/paths.js.map +1 -0
  347. package/dist/daemon/protocol.d.ts +51 -0
  348. package/dist/daemon/protocol.d.ts.map +1 -0
  349. package/dist/daemon/protocol.js +2 -0
  350. package/dist/daemon/protocol.js.map +1 -0
  351. package/dist/daemon/request-utils.d.ts +12 -0
  352. package/dist/daemon/request-utils.d.ts.map +1 -0
  353. package/dist/daemon/request-utils.js +52 -0
  354. package/dist/daemon/request-utils.js.map +1 -0
  355. package/dist/daemon/runtime-wrapper.d.ts +9 -0
  356. package/dist/daemon/runtime-wrapper.d.ts.map +1 -0
  357. package/dist/daemon/runtime-wrapper.js +110 -0
  358. package/dist/daemon/runtime-wrapper.js.map +1 -0
  359. package/dist/env.d.ts +5 -0
  360. package/dist/env.d.ts.map +1 -0
  361. package/dist/env.js +93 -0
  362. package/dist/env.js.map +1 -0
  363. package/dist/error-classifier.d.ts +11 -0
  364. package/dist/error-classifier.d.ts.map +1 -0
  365. package/dist/error-classifier.js +141 -0
  366. package/dist/error-classifier.js.map +1 -0
  367. package/dist/fs-json.d.ts +3 -0
  368. package/dist/fs-json.d.ts.map +1 -0
  369. package/dist/fs-json.js +21 -0
  370. package/dist/fs-json.js.map +1 -0
  371. package/dist/generate-cli.d.ts +32 -0
  372. package/dist/generate-cli.d.ts.map +1 -0
  373. package/dist/generate-cli.js +155 -0
  374. package/dist/generate-cli.js.map +1 -0
  375. package/dist/index.d.ts +9 -0
  376. package/dist/index.d.ts.map +1 -0
  377. package/dist/index.js +5 -0
  378. package/dist/index.js.map +1 -0
  379. package/dist/lifecycle.d.ts +8 -0
  380. package/dist/lifecycle.d.ts.map +1 -0
  381. package/dist/lifecycle.js +106 -0
  382. package/dist/lifecycle.js.map +1 -0
  383. package/dist/logging.d.ts +19 -0
  384. package/dist/logging.d.ts.map +1 -0
  385. package/dist/logging.js +76 -0
  386. package/dist/logging.js.map +1 -0
  387. package/dist/oauth-manual.d.ts +9 -0
  388. package/dist/oauth-manual.d.ts.map +1 -0
  389. package/dist/oauth-manual.js +84 -0
  390. package/dist/oauth-manual.js.map +1 -0
  391. package/dist/oauth-persistence.d.ts +20 -0
  392. package/dist/oauth-persistence.d.ts.map +1 -0
  393. package/dist/oauth-persistence.js +254 -0
  394. package/dist/oauth-persistence.js.map +1 -0
  395. package/dist/oauth-vault.d.ts +19 -0
  396. package/dist/oauth-vault.d.ts.map +1 -0
  397. package/dist/oauth-vault.js +100 -0
  398. package/dist/oauth-vault.js.map +1 -0
  399. package/dist/oauth.d.ts +31 -0
  400. package/dist/oauth.d.ts.map +1 -0
  401. package/dist/oauth.js +414 -0
  402. package/dist/oauth.js.map +1 -0
  403. package/dist/result-utils.d.ts +22 -0
  404. package/dist/result-utils.d.ts.map +1 -0
  405. package/dist/result-utils.js +229 -0
  406. package/dist/result-utils.js.map +1 -0
  407. package/dist/runtime/errors.d.ts +2 -0
  408. package/dist/runtime/errors.d.ts.map +1 -0
  409. package/dist/runtime/errors.js +16 -0
  410. package/dist/runtime/errors.js.map +1 -0
  411. package/dist/runtime/http-transport.d.ts +15 -0
  412. package/dist/runtime/http-transport.d.ts.map +1 -0
  413. package/dist/runtime/http-transport.js +91 -0
  414. package/dist/runtime/http-transport.js.map +1 -0
  415. package/dist/runtime/manual-oauth.d.ts +8 -0
  416. package/dist/runtime/manual-oauth.d.ts.map +1 -0
  417. package/dist/runtime/manual-oauth.js +81 -0
  418. package/dist/runtime/manual-oauth.js.map +1 -0
  419. package/dist/runtime/oauth.d.ts +22 -0
  420. package/dist/runtime/oauth.d.ts.map +1 -0
  421. package/dist/runtime/oauth.js +83 -0
  422. package/dist/runtime/oauth.js.map +1 -0
  423. package/dist/runtime/transport.d.ts +24 -0
  424. package/dist/runtime/transport.d.ts.map +1 -0
  425. package/dist/runtime/transport.js +165 -0
  426. package/dist/runtime/transport.js.map +1 -0
  427. package/dist/runtime/utils.d.ts +5 -0
  428. package/dist/runtime/utils.d.ts.map +1 -0
  429. package/dist/runtime/utils.js +47 -0
  430. package/dist/runtime/utils.js.map +1 -0
  431. package/dist/runtime-header-utils.d.ts +2 -0
  432. package/dist/runtime-header-utils.d.ts.map +1 -0
  433. package/dist/runtime-header-utils.js +19 -0
  434. package/dist/runtime-header-utils.js.map +1 -0
  435. package/dist/runtime-oauth-support.d.ts +5 -0
  436. package/dist/runtime-oauth-support.d.ts.map +1 -0
  437. package/dist/runtime-oauth-support.js +21 -0
  438. package/dist/runtime-oauth-support.js.map +1 -0
  439. package/dist/runtime-process-utils.d.ts +11 -0
  440. package/dist/runtime-process-utils.d.ts.map +1 -0
  441. package/dist/runtime-process-utils.js +299 -0
  442. package/dist/runtime-process-utils.js.map +1 -0
  443. package/dist/runtime.d.ts +55 -0
  444. package/dist/runtime.d.ts.map +1 -0
  445. package/dist/runtime.js +245 -0
  446. package/dist/runtime.js.map +1 -0
  447. package/dist/schema-cache.d.ts +10 -0
  448. package/dist/schema-cache.d.ts.map +1 -0
  449. package/dist/schema-cache.js +40 -0
  450. package/dist/schema-cache.js.map +1 -0
  451. package/dist/sdk-patches.d.ts +5 -0
  452. package/dist/sdk-patches.d.ts.map +1 -0
  453. package/dist/sdk-patches.js +399 -0
  454. package/dist/sdk-patches.js.map +1 -0
  455. package/dist/server-proxy.d.ts +17 -0
  456. package/dist/server-proxy.d.ts.map +1 -0
  457. package/dist/server-proxy.js +342 -0
  458. package/dist/server-proxy.js.map +1 -0
  459. package/docs/RELEASE.md +96 -0
  460. package/docs/adhoc.md +76 -0
  461. package/docs/call-heuristic.md +31 -0
  462. package/docs/call-syntax.md +75 -0
  463. package/docs/cli-generator.md +116 -0
  464. package/docs/cli-reference.md +76 -0
  465. package/docs/config.md +208 -0
  466. package/docs/daemon.md +95 -0
  467. package/docs/emit-ts.md +98 -0
  468. package/docs/hang-debug.md +88 -0
  469. package/docs/import.md +59 -0
  470. package/docs/known-issues.md +33 -0
  471. package/docs/livetests.md +31 -0
  472. package/docs/local.md +73 -0
  473. package/docs/logging.md +67 -0
  474. package/docs/manual-testing.md +78 -0
  475. package/docs/mcp.md +44 -0
  476. package/docs/migration.md +77 -0
  477. package/docs/pnpm-mcp-migration.md +15 -0
  478. package/docs/refactor.md +76 -0
  479. package/docs/shortcuts.md +31 -0
  480. package/docs/spec.md +86 -0
  481. package/docs/subagent.md +39 -0
  482. package/docs/supabase-auth-issue.md +53 -0
  483. package/docs/tmux.md +30 -0
  484. package/docs/tool-calling.md +73 -0
  485. package/docs/windows.md +25 -0
  486. package/examples/context7-headlines.ts +72 -0
  487. package/git +3 -0
  488. package/mcporter.png +0 -0
  489. package/mcporter.schema.json +263 -0
  490. package/package.json +105 -0
  491. package/pnpm-workspace.yaml +2 -0
  492. package/runner +13 -0
  493. package/scripts/agent-send.ts +179 -0
  494. package/scripts/build-bun.ts +125 -0
  495. package/scripts/committer +53 -0
  496. package/scripts/docs-list.ts +132 -0
  497. package/scripts/generate-json-schema.ts +50 -0
  498. package/scripts/git-policy.ts +165 -0
  499. package/scripts/mcp_signoz_retry_patch.cjs +9 -0
  500. package/scripts/release.sh +86 -0
  501. package/scripts/runner.ts +1556 -0
  502. package/scripts/test-runner.js +39 -0
  503. package/src/cli/adhoc-server.ts +263 -0
  504. package/src/cli/auth-command.ts +290 -0
  505. package/src/cli/call-argument-expression.ts +61 -0
  506. package/src/cli/call-argument-values.ts +95 -0
  507. package/src/cli/call-arguments.ts +246 -0
  508. package/src/cli/call-command.ts +478 -0
  509. package/src/cli/call-expression-parser.ts +210 -0
  510. package/src/cli/cli-factory.ts +51 -0
  511. package/src/cli/command-inference.ts +99 -0
  512. package/src/cli/config/add.ts +308 -0
  513. package/src/cli/config/auth.ts +23 -0
  514. package/src/cli/config/doctor.ts +27 -0
  515. package/src/cli/config/get.ts +47 -0
  516. package/src/cli/config/help.ts +213 -0
  517. package/src/cli/config/import.ts +97 -0
  518. package/src/cli/config/index.ts +1 -0
  519. package/src/cli/config/list.ts +81 -0
  520. package/src/cli/config/remove.ts +20 -0
  521. package/src/cli/config/render.ts +119 -0
  522. package/src/cli/config/shared.ts +159 -0
  523. package/src/cli/config/types.ts +8 -0
  524. package/src/cli/config-command.ts +72 -0
  525. package/src/cli/daemon-command.ts +260 -0
  526. package/src/cli/emit-ts-command.ts +260 -0
  527. package/src/cli/emit-ts-templates.ts +161 -0
  528. package/src/cli/ephemeral-flags.ts +128 -0
  529. package/src/cli/ephemeral-target.ts +134 -0
  530. package/src/cli/errors.ts +6 -0
  531. package/src/cli/flag-utils.ts +29 -0
  532. package/src/cli/generate/artifacts.ts +308 -0
  533. package/src/cli/generate/definition.ts +325 -0
  534. package/src/cli/generate/flag-parser.ts +50 -0
  535. package/src/cli/generate/flags.ts +248 -0
  536. package/src/cli/generate/fs-helpers.ts +34 -0
  537. package/src/cli/generate/name-utils.ts +176 -0
  538. package/src/cli/generate/output.ts +27 -0
  539. package/src/cli/generate/runtime.ts +38 -0
  540. package/src/cli/generate/server-utils.ts +38 -0
  541. package/src/cli/generate/template-data.ts +126 -0
  542. package/src/cli/generate/template-help.ts +112 -0
  543. package/src/cli/generate/template.ts +407 -0
  544. package/src/cli/generate/tools.ts +354 -0
  545. package/src/cli/generate/types.ts +1 -0
  546. package/src/cli/generate-cli-runner.ts +82 -0
  547. package/src/cli/help-output.ts +207 -0
  548. package/src/cli/http-utils.ts +89 -0
  549. package/src/cli/identifier-helpers.ts +107 -0
  550. package/src/cli/image-output.ts +62 -0
  551. package/src/cli/inspect-cli-command.ts +89 -0
  552. package/src/cli/json-output.ts +60 -0
  553. package/src/cli/list-command.ts +432 -0
  554. package/src/cli/list-detail-helpers.ts +179 -0
  555. package/src/cli/list-doc-comments.ts +129 -0
  556. package/src/cli/list-format.ts +150 -0
  557. package/src/cli/list-output.ts +224 -0
  558. package/src/cli/list-signature.ts +217 -0
  559. package/src/cli/logger-context.ts +36 -0
  560. package/src/cli/output-format.ts +63 -0
  561. package/src/cli/output-utils.ts +161 -0
  562. package/src/cli/path-utils.ts +13 -0
  563. package/src/cli/runtime-debug.ts +141 -0
  564. package/src/cli/server-lookup.ts +22 -0
  565. package/src/cli/terminal.ts +41 -0
  566. package/src/cli/timeouts.ts +67 -0
  567. package/src/cli/tool-cache.ts +43 -0
  568. package/src/cli/transport-utils.ts +10 -0
  569. package/src/cli-metadata.ts +164 -0
  570. package/src/cli.ts +234 -0
  571. package/src/config/imports/external.ts +284 -0
  572. package/src/config/imports/paths-utils.ts +29 -0
  573. package/src/config/imports/paths.ts +145 -0
  574. package/src/config/imports/shared.ts +27 -0
  575. package/src/config/path-discovery.ts +79 -0
  576. package/src/config/read-config.ts +91 -0
  577. package/src/config-imports.ts +12 -0
  578. package/src/config-normalize.ts +220 -0
  579. package/src/config-schema.ts +175 -0
  580. package/src/config.ts +136 -0
  581. package/src/daemon/client.ts +350 -0
  582. package/src/daemon/config-layers.ts +23 -0
  583. package/src/daemon/host.ts +455 -0
  584. package/src/daemon/launch.ts +45 -0
  585. package/src/daemon/log-context.ts +78 -0
  586. package/src/daemon/paths.ts +35 -0
  587. package/src/daemon/protocol.ts +57 -0
  588. package/src/daemon/request-utils.ts +67 -0
  589. package/src/daemon/runtime-wrapper.ts +135 -0
  590. package/src/env.ts +107 -0
  591. package/src/error-classifier.ts +158 -0
  592. package/src/fs-json.ts +21 -0
  593. package/src/generate-cli.ts +211 -0
  594. package/src/index.ts +14 -0
  595. package/src/lifecycle.ts +138 -0
  596. package/src/logging.ts +93 -0
  597. package/src/oauth-manual.ts +103 -0
  598. package/src/oauth-persistence.ts +316 -0
  599. package/src/oauth-vault.ts +128 -0
  600. package/src/oauth.ts +494 -0
  601. package/src/result-utils.ts +278 -0
  602. package/src/runtime/errors.ts +17 -0
  603. package/src/runtime/oauth.ts +112 -0
  604. package/src/runtime/transport.ts +198 -0
  605. package/src/runtime/utils.ts +54 -0
  606. package/src/runtime-header-utils.ts +23 -0
  607. package/src/runtime-oauth-support.ts +24 -0
  608. package/src/runtime-process-utils.ts +324 -0
  609. package/src/runtime.ts +321 -0
  610. package/src/schema-cache.ts +49 -0
  611. package/src/sdk-patches.ts +498 -0
  612. package/src/server-proxy.ts +407 -0
  613. package/tests/adhoc-server.test.ts +49 -0
  614. package/tests/call-arguments.test.ts +111 -0
  615. package/tests/cli-auth-help.test.ts +43 -0
  616. package/tests/cli-auth-retry.test.ts +41 -0
  617. package/tests/cli-auth.test.ts +96 -0
  618. package/tests/cli-call-args.test.ts +69 -0
  619. package/tests/cli-call-errors.test.ts +27 -0
  620. package/tests/cli-call-execution.test.ts +279 -0
  621. package/tests/cli-call-help.test.ts +43 -0
  622. package/tests/cli-command-inference.test.ts +73 -0
  623. package/tests/cli-config-command.test.ts +371 -0
  624. package/tests/cli-config-fallback.test.ts +259 -0
  625. package/tests/cli-config-routing.test.ts +20 -0
  626. package/tests/cli-ephemeral-flags.test.ts +54 -0
  627. package/tests/cli-flag-utils.test.ts +17 -0
  628. package/tests/cli-generate-artifacts.test.ts +52 -0
  629. package/tests/cli-generate-cli.integration.test.ts +675 -0
  630. package/tests/cli-generate-runner.test.ts +156 -0
  631. package/tests/cli-global-flags.test.ts +61 -0
  632. package/tests/cli-help-shortcuts.test.ts +42 -0
  633. package/tests/cli-image-output.test.ts +65 -0
  634. package/tests/cli-inspect-command.test.ts +15 -0
  635. package/tests/cli-list-classification.test.ts +291 -0
  636. package/tests/cli-list-flags.test.ts +83 -0
  637. package/tests/cli-list-formatting.test.ts +358 -0
  638. package/tests/cli-list-help.test.ts +43 -0
  639. package/tests/cli-list-json.test.ts +55 -0
  640. package/tests/cli-list-stdio-logs.test.ts +108 -0
  641. package/tests/cli-list-verbose-e2e.test.ts +83 -0
  642. package/tests/cli-oauth-timeout-flag.test.ts +94 -0
  643. package/tests/cli-output-utils.test.ts +129 -0
  644. package/tests/cli-regenerate.test.ts +261 -0
  645. package/tests/cli-version.test.ts +24 -0
  646. package/tests/config-add-dry-run.test.ts +45 -0
  647. package/tests/config-add-flags.test.ts +61 -0
  648. package/tests/config-add-imports.test.ts +28 -0
  649. package/tests/config-add-persist.test.ts +27 -0
  650. package/tests/config-add-scope-behavior.test.ts +46 -0
  651. package/tests/config-add-scope.test.ts +101 -0
  652. package/tests/config-add-sse.test.ts +23 -0
  653. package/tests/config-command-string.test.ts +96 -0
  654. package/tests/config-doctor.test.ts +45 -0
  655. package/tests/config-get-json.test.ts +24 -0
  656. package/tests/config-import-dedupe.test.ts +27 -0
  657. package/tests/config-import-paths.test.ts +49 -0
  658. package/tests/config-import.test.ts +64 -0
  659. package/tests/config-imports-unit.test.ts +337 -0
  660. package/tests/config-imports.test.ts +417 -0
  661. package/tests/config-layered.test.ts +178 -0
  662. package/tests/config-list-text-footer.test.ts +33 -0
  663. package/tests/config-list.test.ts +62 -0
  664. package/tests/config-missing.test.ts +140 -0
  665. package/tests/config-normalize.test.ts +71 -0
  666. package/tests/config-remove.test.ts +44 -0
  667. package/tests/config-render.test.ts +61 -0
  668. package/tests/config-resolution.test.ts +94 -0
  669. package/tests/config-schema-file.test.ts +29 -0
  670. package/tests/config-shared.test.ts +41 -0
  671. package/tests/config-sources.test.ts +58 -0
  672. package/tests/daemon-cli-command.test.ts +112 -0
  673. package/tests/daemon-client-config-stale.test.ts +222 -0
  674. package/tests/daemon-client-timeout.test.ts +114 -0
  675. package/tests/daemon-client.test.ts +61 -0
  676. package/tests/daemon-host.test.ts +33 -0
  677. package/tests/daemon.integration.test.ts +175 -0
  678. package/tests/emit-ts.test.ts +125 -0
  679. package/tests/ephemeral-target.test.ts +26 -0
  680. package/tests/error-classifier.test.ts +46 -0
  681. package/tests/fixtures/ansi.ts +18 -0
  682. package/tests/fixtures/cli-list-fixtures.ts +43 -0
  683. package/tests/fixtures/config-fixture.ts +29 -0
  684. package/tests/fixtures/imports/.claude/mcp.json +8 -0
  685. package/tests/fixtures/imports/.claude/settings.json +10 -0
  686. package/tests/fixtures/imports/.claude/settings.local.json +10 -0
  687. package/tests/fixtures/imports/.codeium/windsurf/mcp_config.json +14 -0
  688. package/tests/fixtures/imports/.codex/config.toml +7 -0
  689. package/tests/fixtures/imports/.config/opencode/opencode.jsonc +10 -0
  690. package/tests/fixtures/imports/.cursor/mcp.json +14 -0
  691. package/tests/fixtures/imports/Library/Application Support/Code/User/mcp.json +11 -0
  692. package/tests/fixtures/imports/config/mcporter.json +11 -0
  693. package/tests/fixtures/imports/home/.claude/settings.json +7 -0
  694. package/tests/fixtures/imports/home/.codeium/windsurf/mcp_config.json +14 -0
  695. package/tests/fixtures/imports/home/.codex/config.toml +7 -0
  696. package/tests/fixtures/imports/home/Library/Application Support/Code/User/mcp.json +11 -0
  697. package/tests/fixtures/imports/opencode.jsonc +11 -0
  698. package/tests/fixtures/mcporter.json +64 -0
  699. package/tests/fixtures/stdio-filesystem-server.mjs +63 -0
  700. package/tests/fixtures/stdio-memory-server.mjs +58 -0
  701. package/tests/fixtures/test-helpers.ts +24 -0
  702. package/tests/fixtures/tool-fixtures.ts +35 -0
  703. package/tests/fs-json.test.ts +35 -0
  704. package/tests/generate-cli-helpers.test.ts +162 -0
  705. package/tests/generate-cli.test.ts +595 -0
  706. package/tests/generate-definition.test.ts +25 -0
  707. package/tests/generator-flag-parser.test.ts +19 -0
  708. package/tests/index-api.test.ts +136 -0
  709. package/tests/keep-alive-runtime.test.ts +152 -0
  710. package/tests/lifecycle.test.ts +29 -0
  711. package/tests/list-detail-helpers.test.ts +204 -0
  712. package/tests/list-format.test.ts +40 -0
  713. package/tests/list-inline-stdio.test.ts +71 -0
  714. package/tests/list-output.test.ts +138 -0
  715. package/tests/live/deepwiki-live.test.ts +53 -0
  716. package/tests/oauth-callback.test.ts +108 -0
  717. package/tests/oauth-open-external.test.ts +29 -0
  718. package/tests/oauth-persistence.test.ts +146 -0
  719. package/tests/oauth-session.test.ts +216 -0
  720. package/tests/result-utils.test.ts +254 -0
  721. package/tests/runtime-call-timeout.test.ts +75 -0
  722. package/tests/runtime-compose.test.ts +298 -0
  723. package/tests/runtime-error-reset.test.ts +65 -0
  724. package/tests/runtime-header-utils.test.ts +36 -0
  725. package/tests/runtime-integration.test.ts +113 -0
  726. package/tests/runtime-oauth-connect.test.ts +72 -0
  727. package/tests/runtime-oauth-detection.test.ts +72 -0
  728. package/tests/runtime-oauth-timeout.test.ts +60 -0
  729. package/tests/runtime-oauth-utils.test.ts +14 -0
  730. package/tests/runtime-process-utils.test.ts +53 -0
  731. package/tests/runtime-transport.test.ts +69 -0
  732. package/tests/runtime-utils.test.ts +31 -0
  733. package/tests/runtime.test.ts +94 -0
  734. package/tests/sdk-patches.test.ts +24 -0
  735. package/tests/server-proxy.test.ts +336 -0
  736. package/tests/stdio-servers.integration.test.ts +139 -0
  737. package/tests/tool-cache.test.ts +42 -0
  738. package/tests/version-consistency.test.ts +11 -0
  739. package/tsconfig.build.json +11 -0
  740. package/tsconfig.json +17 -0
  741. package/vitest.config.ts +18 -0
@@ -0,0 +1,128 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import type { OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
6
+ import type { ServerDefinition } from './config.js';
7
+ import { readJsonFile, writeJsonFile } from './fs-json.js';
8
+
9
+ const VAULT_PATH = path.join(os.homedir(), '.mcporter', 'credentials.json');
10
+
11
+ type VaultKey = string;
12
+
13
+ export interface VaultEntry {
14
+ serverName: string;
15
+ serverUrl?: string;
16
+ tokens?: OAuthTokens;
17
+ clientInfo?: OAuthClientInformationMixed;
18
+ codeVerifier?: string;
19
+ state?: string;
20
+ updatedAt: string;
21
+ }
22
+
23
+ interface VaultFile {
24
+ version: 1;
25
+ entries: Record<VaultKey, VaultEntry>;
26
+ }
27
+
28
+ async function readVault(): Promise<VaultFile> {
29
+ let shouldRewrite = false;
30
+ try {
31
+ const existing = await readJsonFile<VaultFile>(VAULT_PATH);
32
+ if (existing && existing.version === 1 && existing.entries && typeof existing.entries === 'object') {
33
+ return existing;
34
+ }
35
+ // Unexpected shape; rewrite.
36
+ shouldRewrite = true;
37
+ } catch {
38
+ // Corrupt or unreadable vault; reset to empty.
39
+ shouldRewrite = true;
40
+ }
41
+ const empty: VaultFile = { version: 1, entries: {} };
42
+ if (shouldRewrite) {
43
+ await writeVault(empty);
44
+ }
45
+ return empty;
46
+ }
47
+
48
+ async function writeVault(contents: VaultFile): Promise<void> {
49
+ const dir = path.dirname(VAULT_PATH);
50
+ await fs.mkdir(dir, { recursive: true });
51
+ await writeJsonFile(VAULT_PATH, contents);
52
+ }
53
+
54
+ export function vaultKeyForDefinition(definition: ServerDefinition): VaultKey {
55
+ const descriptor = {
56
+ name: definition.name,
57
+ url: definition.command.kind === 'http' ? definition.command.url.toString() : null,
58
+ command:
59
+ definition.command.kind === 'stdio'
60
+ ? { command: definition.command.command, args: definition.command.args ?? [] }
61
+ : null,
62
+ };
63
+ const hash = crypto.createHash('sha256').update(JSON.stringify(descriptor)).digest('hex').slice(0, 16);
64
+ return `${definition.name}|${hash}`;
65
+ }
66
+
67
+ export async function loadVaultEntry(definition: ServerDefinition): Promise<VaultEntry | undefined> {
68
+ const vault = await readVault();
69
+ return vault.entries[vaultKeyForDefinition(definition)];
70
+ }
71
+
72
+ export async function saveVaultEntry(definition: ServerDefinition, patch: Partial<VaultEntry>): Promise<void> {
73
+ const vault = await readVault();
74
+ const key = vaultKeyForDefinition(definition);
75
+ const current = vault.entries[key] ?? {
76
+ serverName: definition.name,
77
+ serverUrl: definition.command.kind === 'http' ? definition.command.url.toString() : undefined,
78
+ updatedAt: new Date().toISOString(),
79
+ };
80
+ vault.entries[key] = {
81
+ ...current,
82
+ ...patch,
83
+ updatedAt: new Date().toISOString(),
84
+ };
85
+ await writeVault(vault);
86
+ }
87
+
88
+ export async function findServerNameByState(state: string): Promise<VaultEntry | undefined> {
89
+ const vault = await readVault();
90
+ for (const entry of Object.values(vault.entries)) {
91
+ if (entry.state === state) {
92
+ return entry;
93
+ }
94
+ }
95
+ return undefined;
96
+ }
97
+
98
+ export async function clearVaultEntry(
99
+ definition: ServerDefinition,
100
+ scope: 'all' | 'tokens' | 'client' | 'verifier' | 'state'
101
+ ): Promise<void> {
102
+ const vault = await readVault();
103
+ const key = vaultKeyForDefinition(definition);
104
+ const existing = vault.entries[key];
105
+ if (!existing) {
106
+ return;
107
+ }
108
+ if (scope === 'all') {
109
+ delete vault.entries[key];
110
+ } else {
111
+ const updated: VaultEntry = { ...existing };
112
+ if (scope === 'tokens') {
113
+ delete updated.tokens;
114
+ }
115
+ if (scope === 'client') {
116
+ delete updated.clientInfo;
117
+ }
118
+ if (scope === 'verifier') {
119
+ delete updated.codeVerifier;
120
+ }
121
+ if (scope === 'state') {
122
+ delete updated.state;
123
+ }
124
+ updated.updatedAt = new Date().toISOString();
125
+ vault.entries[key] = updated;
126
+ }
127
+ await writeVault(vault);
128
+ }
package/src/oauth.ts ADDED
@@ -0,0 +1,494 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ import http from 'node:http';
4
+ import { URL } from 'node:url';
5
+ import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
6
+ import type {
7
+ OAuthClientInformationMixed,
8
+ OAuthClientMetadata,
9
+ OAuthTokens,
10
+ } from '@modelcontextprotocol/sdk/shared/auth.js';
11
+ import type { ServerDefinition } from './config.js';
12
+ import type { OAuthPersistence } from './oauth-persistence.js';
13
+ import { buildOAuthPersistence } from './oauth-persistence.js';
14
+
15
+ const CALLBACK_HOST = '127.0.0.1';
16
+ const CALLBACK_PATH = '/callback';
17
+
18
+ interface Deferred<T> {
19
+ promise: Promise<T>;
20
+ resolve: (value: T) => void;
21
+ reject: (reason?: unknown) => void;
22
+ }
23
+
24
+ // createDeferred produces a minimal promise wrapper for async coordination.
25
+ function createDeferred<T>(): Deferred<T> {
26
+ let resolve!: (value: T) => void;
27
+ let reject!: (reason?: unknown) => void;
28
+ const promise = new Promise<T>((res, rej) => {
29
+ resolve = res;
30
+ reject = rej;
31
+ });
32
+ return { promise, resolve, reject };
33
+ }
34
+
35
+ // openExternal attempts to launch the system browser cross-platform.
36
+ function openExternal(url: string, platform: NodeJS.Platform = process.platform, launch: typeof spawn = spawn) {
37
+ const stdio = 'ignore';
38
+ try {
39
+ if (platform === 'darwin') {
40
+ const child = launch('open', [url], { stdio, detached: true });
41
+ child.unref();
42
+ } else if (platform === 'win32') {
43
+ const child = launch('cmd', ['/c', 'start', '""', url], {
44
+ stdio,
45
+ detached: true,
46
+ });
47
+ child.unref();
48
+ } else {
49
+ try {
50
+ const child = launch('xdg-open', [url], { stdio, detached: true });
51
+ child.on('error', () => {}); // swallow ENOENT on headless servers
52
+ child.unref();
53
+ } catch {
54
+ // headless server — no browser available
55
+ }
56
+ }
57
+ } catch {
58
+ // best-effort: fall back to printing URL
59
+ }
60
+ }
61
+
62
+ // PersistentOAuthClientProvider persists OAuth session artifacts to disk and captures callback redirects.
63
+ class PersistentOAuthClientProvider implements OAuthClientProvider {
64
+ private readonly metadata: OAuthClientMetadata;
65
+ private readonly logger: OAuthLogger;
66
+ private readonly persistence: OAuthPersistence;
67
+ private redirectUrlValue: URL;
68
+ private authorizationDeferred: Deferred<string> | null = null;
69
+ private server?: http.Server;
70
+ private readonly manual: boolean;
71
+
72
+ private constructor(
73
+ private readonly definition: ServerDefinition,
74
+ persistence: OAuthPersistence,
75
+ redirectUrl: URL,
76
+ logger: OAuthLogger,
77
+ manual = false
78
+ ) {
79
+ this.manual = manual;
80
+ this.redirectUrlValue = redirectUrl;
81
+ this.logger = logger;
82
+ this.persistence = persistence;
83
+ this.metadata = {
84
+ client_name: definition.clientName ?? `mcporter (${definition.name})`,
85
+ redirect_uris: [this.redirectUrlValue.toString()],
86
+ grant_types: ['authorization_code', 'refresh_token'],
87
+ response_types: ['code'],
88
+ token_endpoint_auth_method: 'none',
89
+ // Omit scope so the MCP SDK can derive it from the server's metadata
90
+ // (resource metadata scopes_supported or auth server scopes_supported).
91
+ // Hardcoding 'mcp:tools' breaks providers like Granola whose auth server
92
+ // does not recognise that scope value.
93
+ // If oauthScope is explicitly configured, prefer that exact value.
94
+ ...(definition.oauthScope !== undefined ? { scope: definition.oauthScope || undefined } : {}),
95
+ };
96
+ }
97
+
98
+ static async create(
99
+ definition: ServerDefinition,
100
+ logger: OAuthLogger
101
+ ): Promise<{
102
+ provider: PersistentOAuthClientProvider;
103
+ close: () => Promise<void>;
104
+ }> {
105
+ const persistence = await buildOAuthPersistence(definition, logger);
106
+
107
+ const server = http.createServer();
108
+ const overrideRedirect = definition.oauthRedirectUrl ? new URL(definition.oauthRedirectUrl) : null;
109
+ const listenHost = overrideRedirect?.hostname ?? CALLBACK_HOST;
110
+ const overridePort = overrideRedirect?.port ?? '';
111
+ const usesDynamicPort = !overrideRedirect || overridePort === '' || overridePort === '0';
112
+ const desiredPort = usesDynamicPort ? undefined : Number.parseInt(overridePort, 10);
113
+ const callbackPath =
114
+ overrideRedirect?.pathname && overrideRedirect.pathname !== '/' ? overrideRedirect.pathname : CALLBACK_PATH;
115
+ const port = await new Promise<number>((resolve, reject) => {
116
+ server.listen(desiredPort ?? 0, listenHost, () => {
117
+ const address = server.address();
118
+ if (typeof address === 'object' && address && 'port' in address) {
119
+ resolve(address.port);
120
+ } else {
121
+ reject(new Error('Failed to determine callback port'));
122
+ }
123
+ });
124
+ server.once('error', (error) => reject(error));
125
+ });
126
+
127
+ const redirectUrl = overrideRedirect
128
+ ? new URL(overrideRedirect.toString())
129
+ : new URL(`http://${listenHost}:${port}${callbackPath}`);
130
+ if (usesDynamicPort) {
131
+ redirectUrl.port = String(port);
132
+ }
133
+ if (!overrideRedirect || overrideRedirect.pathname === '/' || overrideRedirect.pathname === '') {
134
+ redirectUrl.pathname = callbackPath;
135
+ }
136
+
137
+ // When using a dynamic port, the redirect URI changes every run. If a
138
+ // previous client registration is cached with a different redirect URI the
139
+ // auth server will reject the request with `invalid_redirect_uri`. Clear
140
+ // the stale registration so the next flow re-registers with the new URI.
141
+ // Wrapped in try/catch so persistence errors (malformed JSON, permission
142
+ // issues) close the already-bound callback server instead of leaking it.
143
+ if (usesDynamicPort) {
144
+ try {
145
+ const cachedClient = await persistence.readClientInfo();
146
+ const cachedRedirect = firstRedirectUri(cachedClient);
147
+ if (cachedRedirect && cachedRedirect !== redirectUrl.toString()) {
148
+ logger.info(
149
+ `Redirect URI changed (${cachedRedirect} → ${redirectUrl.toString()}); clearing stale client registration.`
150
+ );
151
+ await persistence.clear('client');
152
+ }
153
+ } catch (error) {
154
+ await new Promise<void>((resolve) => {
155
+ server.close(() => resolve());
156
+ });
157
+ throw error;
158
+ }
159
+ }
160
+
161
+ const provider = new PersistentOAuthClientProvider(definition, persistence, redirectUrl, logger);
162
+ provider.attachServer(server);
163
+ return {
164
+ provider,
165
+ close: async () => {
166
+ await provider.close();
167
+ },
168
+ };
169
+ }
170
+
171
+ // createManual starts the server only to acquire a dynamic port for the redirect URI, then
172
+ // immediately closes it. redirectToAuthorization prints the URL instead of opening a browser,
173
+ // and the process exits after printing — the user completes the flow with `auth complete`.
174
+ static async createManual(
175
+ definition: ServerDefinition,
176
+ logger: OAuthLogger
177
+ ): Promise<{ provider: PersistentOAuthClientProvider; close: () => Promise<void> }> {
178
+ const persistence = await buildOAuthPersistence(definition, logger);
179
+
180
+ const server = http.createServer();
181
+ const overrideRedirect = definition.oauthRedirectUrl ? new URL(definition.oauthRedirectUrl) : null;
182
+ const listenHost = overrideRedirect?.hostname ?? CALLBACK_HOST;
183
+ const overridePort = overrideRedirect?.port ?? '';
184
+ const usesDynamicPort = !overrideRedirect || overridePort === '' || overridePort === '0';
185
+ const desiredPort = usesDynamicPort ? undefined : Number.parseInt(overridePort, 10);
186
+ const callbackPath =
187
+ overrideRedirect?.pathname && overrideRedirect.pathname !== '/' ? overrideRedirect.pathname : CALLBACK_PATH;
188
+
189
+ const port = await new Promise<number>((resolve, reject) => {
190
+ server.listen(desiredPort ?? 0, listenHost, () => {
191
+ const address = server.address();
192
+ if (typeof address === 'object' && address && 'port' in address) {
193
+ resolve(address.port);
194
+ } else {
195
+ reject(new Error('Failed to determine callback port'));
196
+ }
197
+ });
198
+ server.once('error', (error) => reject(error));
199
+ });
200
+
201
+ const redirectUrl = overrideRedirect
202
+ ? new URL(overrideRedirect.toString())
203
+ : new URL(`http://${listenHost}:${port}${callbackPath}`);
204
+ if (usesDynamicPort) {
205
+ redirectUrl.port = String(port);
206
+ }
207
+ if (!overrideRedirect || overrideRedirect.pathname === '/' || overrideRedirect.pathname === '') {
208
+ redirectUrl.pathname = callbackPath;
209
+ }
210
+
211
+ // Close the server immediately — manual flow doesn't need a running callback listener.
212
+ await new Promise<void>((resolve) => server.close(() => resolve()));
213
+
214
+ if (usesDynamicPort) {
215
+ const cachedClient = await persistence.readClientInfo();
216
+ const cachedRedirect = firstRedirectUri(cachedClient);
217
+ if (cachedRedirect && cachedRedirect !== redirectUrl.toString()) {
218
+ logger.info(
219
+ `Redirect URI changed (${cachedRedirect} → ${redirectUrl.toString()}); clearing stale client registration.`
220
+ );
221
+ await persistence.clear('client');
222
+ }
223
+ }
224
+
225
+ const provider = new PersistentOAuthClientProvider(definition, persistence, redirectUrl, logger, true);
226
+ return {
227
+ provider,
228
+ close: async () => {
229
+ // Server is already closed; nothing to do.
230
+ },
231
+ };
232
+ }
233
+
234
+ // attachServer listens for the OAuth redirect and resolves/rejects the deferred code promise.
235
+ private attachServer(server: http.Server) {
236
+ this.server = server;
237
+ server.on('request', async (req, res) => {
238
+ try {
239
+ const url = req.url ?? '';
240
+ const parsed = new URL(url, this.redirectUrlValue);
241
+ const expectedPath = this.redirectUrlValue.pathname || '/callback';
242
+ if (parsed.pathname !== expectedPath) {
243
+ res.statusCode = 404;
244
+ res.end('Not found');
245
+ return;
246
+ }
247
+ const code = parsed.searchParams.get('code');
248
+ const error = parsed.searchParams.get('error');
249
+ const receivedState = parsed.searchParams.get('state');
250
+ const expectedState = await this.persistence.readState();
251
+ if (expectedState && receivedState && receivedState !== expectedState) {
252
+ res.statusCode = 400;
253
+ res.setHeader('Content-Type', 'text/html');
254
+ res.end('<html><body><h1>Authorization failed</h1><p>Invalid OAuth state</p></body></html>');
255
+ this.authorizationDeferred?.reject(new Error('Invalid OAuth state'));
256
+ this.authorizationDeferred = null;
257
+ return;
258
+ }
259
+ if (code) {
260
+ this.logger.info(`Received OAuth authorization code for ${this.definition.name}`);
261
+ res.statusCode = 200;
262
+ res.setHeader('Content-Type', 'text/html');
263
+ res.end('<html><body><h1>Authorization successful</h1><p>You can return to the CLI.</p></body></html>');
264
+ this.authorizationDeferred?.resolve(code);
265
+ this.authorizationDeferred = null;
266
+ } else if (error) {
267
+ res.statusCode = 400;
268
+ res.setHeader('Content-Type', 'text/html');
269
+ res.end(`<html><body><h1>Authorization failed</h1><p>${error}</p></body></html>`);
270
+ this.authorizationDeferred?.reject(new Error(`OAuth error: ${error}`));
271
+ this.authorizationDeferred = null;
272
+ } else {
273
+ res.statusCode = 400;
274
+ res.end('Missing authorization code');
275
+ this.authorizationDeferred?.reject(new Error('Missing authorization code'));
276
+ this.authorizationDeferred = null;
277
+ }
278
+ } catch (error) {
279
+ this.authorizationDeferred?.reject(error);
280
+ this.authorizationDeferred = null;
281
+ }
282
+ });
283
+ }
284
+
285
+ get redirectUrl(): string | URL {
286
+ return this.redirectUrlValue;
287
+ }
288
+
289
+ get clientMetadata(): OAuthClientMetadata {
290
+ return this.metadata;
291
+ }
292
+
293
+ async state(): Promise<string> {
294
+ const existing = await this.persistence.readState();
295
+ if (existing) {
296
+ return existing;
297
+ }
298
+ const state = randomUUID();
299
+ await this.persistence.saveState(state);
300
+ return state;
301
+ }
302
+
303
+ async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {
304
+ return this.persistence.readClientInfo();
305
+ }
306
+
307
+ async saveClientInformation(clientInformation: OAuthClientInformationMixed): Promise<void> {
308
+ await this.persistence.saveClientInfo(clientInformation);
309
+ }
310
+
311
+ async tokens(): Promise<OAuthTokens | undefined> {
312
+ return this.persistence.readTokens();
313
+ }
314
+
315
+ async saveTokens(tokens: OAuthTokens): Promise<void> {
316
+ await this.persistence.saveTokens(tokens);
317
+ this.logger.info(`Saved OAuth tokens for ${this.definition.name} (${this.persistence.describe()})`);
318
+ }
319
+
320
+ async redirectToAuthorization(authorizationUrl: URL): Promise<void> {
321
+ if (this.manual) {
322
+ console.log(`\nAuthorization URL:\n ${authorizationUrl.toString()}\n`);
323
+ return;
324
+ }
325
+ this.logger.info(`Authorization required for ${this.definition.name}. Opening browser...`);
326
+ this.ensureAuthorizationDeferred();
327
+ __oauthInternals.openExternal(authorizationUrl.toString());
328
+ this.logger.info(`If the browser did not open, visit ${authorizationUrl.toString()} manually.`);
329
+ }
330
+
331
+ async saveCodeVerifier(codeVerifier: string): Promise<void> {
332
+ await this.persistence.saveCodeVerifier(codeVerifier);
333
+ }
334
+
335
+ async codeVerifier(): Promise<string> {
336
+ const value = await this.persistence.readCodeVerifier();
337
+ if (!value) {
338
+ throw new Error(`Missing PKCE code verifier for ${this.definition.name}`);
339
+ }
340
+ return value.trim();
341
+ }
342
+
343
+ // invalidateCredentials removes cached files to force the next OAuth flow.
344
+ async invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier'): Promise<void> {
345
+ await this.persistence.clear(scope);
346
+ }
347
+
348
+ // waitForAuthorizationCode resolves once the local callback server captures a redirect.
349
+ // The same deferred is shared with redirectToAuthorization so callback resolution is stable.
350
+ // In manual mode, throws ManualFlowInitiatedError to signal that the process should exit.
351
+ async waitForAuthorizationCode(): Promise<string> {
352
+ if (this.manual) {
353
+ throw new ManualFlowInitiatedError();
354
+ }
355
+ return this.ensureAuthorizationDeferred().promise;
356
+ }
357
+
358
+ // close stops the temporary callback server created for the OAuth session.
359
+ async close(): Promise<void> {
360
+ if (this.authorizationDeferred) {
361
+ // If the CLI is tearing down mid-flow, reject the pending wait promise so runtime shutdown isn't blocked.
362
+ this.authorizationDeferred.reject(new Error('OAuth session closed before receiving authorization code.'));
363
+ this.authorizationDeferred = null;
364
+ }
365
+ if (!this.server) {
366
+ return;
367
+ }
368
+ await new Promise<void>((resolve) => {
369
+ this.server?.close(() => resolve());
370
+ });
371
+ this.server = undefined;
372
+ }
373
+
374
+ private ensureAuthorizationDeferred(): Deferred<string> {
375
+ if (!this.authorizationDeferred) {
376
+ this.authorizationDeferred = createDeferred<string>();
377
+ }
378
+ return this.authorizationDeferred;
379
+ }
380
+ }
381
+
382
+ export interface OAuthSession {
383
+ provider: OAuthClientProvider & {
384
+ waitForAuthorizationCode: () => Promise<string>;
385
+ };
386
+ waitForAuthorizationCode: () => Promise<string>;
387
+ close: () => Promise<void>;
388
+ }
389
+
390
+ // createOAuthSession spins up a file-backed OAuth provider and callback server for the target definition.
391
+ export async function createOAuthSession(definition: ServerDefinition, logger: OAuthLogger): Promise<OAuthSession> {
392
+ const { provider, close } = await PersistentOAuthClientProvider.create(definition, logger);
393
+ const waitForAuthorizationCode = () => provider.waitForAuthorizationCode();
394
+ return {
395
+ provider,
396
+ waitForAuthorizationCode,
397
+ close,
398
+ };
399
+ }
400
+ export interface OAuthLogger {
401
+ info(message: string): void;
402
+ warn(message: string): void;
403
+ error(message: string, error?: unknown): void;
404
+ }
405
+
406
+ function firstRedirectUri(client: OAuthClientInformationMixed | undefined): string | undefined {
407
+ if (!client || typeof client !== 'object') {
408
+ return undefined;
409
+ }
410
+ const redirectUris = (client as Record<string, unknown>).redirect_uris;
411
+ if (!Array.isArray(redirectUris)) {
412
+ return undefined;
413
+ }
414
+ const [first] = redirectUris;
415
+ return typeof first === 'string' ? first : undefined;
416
+ }
417
+
418
+ export const __oauthInternals = {
419
+ openExternal,
420
+ };
421
+
422
+ // ManualFlowInitiatedError is thrown by waitForAuthorizationCode() in manual mode to signal
423
+ // that the process should exit cleanly after printing the authorization URL.
424
+ export class ManualFlowInitiatedError extends Error {
425
+ constructor() {
426
+ super('Manual OAuth flow initiated. Run `mcporter auth complete <pasted-redirect-url>` to finish.');
427
+ this.name = 'ManualFlowInitiatedError';
428
+ }
429
+ }
430
+
431
+ // createManualOAuthSession returns an OAuthClientProvider for --browser none flows.
432
+ // It acquires a redirect URI via a short-lived callback server, then closes the server.
433
+ // redirectToAuthorization prints the URL instead of opening a browser.
434
+ export async function createManualOAuthSession(
435
+ definition: ServerDefinition,
436
+ logger: OAuthLogger
437
+ ): Promise<{ provider: OAuthClientProvider; close: () => Promise<void> }> {
438
+ return PersistentOAuthClientProvider.createManual(definition, logger);
439
+ }
440
+
441
+ // createCodeExchangeProvider builds a minimal OAuthClientProvider for `auth complete`.
442
+ // It reads persisted PKCE and client artifacts to exchange an authorization code for tokens.
443
+ export async function createCodeExchangeProvider(
444
+ definition: ServerDefinition,
445
+ redirectUrl: URL,
446
+ logger: OAuthLogger
447
+ ): Promise<OAuthClientProvider> {
448
+ const persistence = await buildOAuthPersistence(definition, logger);
449
+ const metadata: OAuthClientMetadata = {
450
+ client_name: definition.clientName ?? `mcporter (${definition.name})`,
451
+ redirect_uris: [redirectUrl.toString()],
452
+ grant_types: ['authorization_code', 'refresh_token'],
453
+ response_types: ['code'],
454
+ token_endpoint_auth_method: 'none',
455
+ ...(definition.oauthScope !== undefined ? { scope: definition.oauthScope || undefined } : {}),
456
+ };
457
+ return {
458
+ get redirectUrl() {
459
+ return redirectUrl;
460
+ },
461
+ get clientMetadata() {
462
+ return metadata;
463
+ },
464
+ async state() {
465
+ return (await persistence.readState()) ?? randomUUID();
466
+ },
467
+ async clientInformation() {
468
+ return persistence.readClientInfo();
469
+ },
470
+ async saveClientInformation(info) {
471
+ await persistence.saveClientInfo(info);
472
+ },
473
+ async tokens() {
474
+ return persistence.readTokens();
475
+ },
476
+ async saveTokens(tokens) {
477
+ await persistence.saveTokens(tokens);
478
+ logger.info(`Saved OAuth tokens for ${definition.name} (${persistence.describe()})`);
479
+ },
480
+ async saveCodeVerifier(v) {
481
+ await persistence.saveCodeVerifier(v);
482
+ },
483
+ async codeVerifier() {
484
+ const v = await persistence.readCodeVerifier();
485
+ if (!v) {
486
+ throw new Error(`Missing PKCE code verifier for ${definition.name}`);
487
+ }
488
+ return v.trim();
489
+ },
490
+ async redirectToAuthorization() {
491
+ throw new Error('redirectToAuthorization called unexpectedly during auth complete');
492
+ },
493
+ };
494
+ }