scorecard-ai-mcp 2.0.0 → 2.1.1

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 (325) hide show
  1. package/README.md +39 -0
  2. package/code-tool-paths.cjs +6 -0
  3. package/code-tool-paths.cjs.map +1 -0
  4. package/code-tool-paths.d.cts +2 -0
  5. package/code-tool-paths.d.cts.map +1 -0
  6. package/code-tool-types.d.mts +14 -0
  7. package/code-tool-types.d.mts.map +1 -0
  8. package/code-tool-types.d.ts +14 -0
  9. package/code-tool-types.d.ts.map +1 -0
  10. package/code-tool-types.js +4 -0
  11. package/code-tool-types.js.map +1 -0
  12. package/code-tool-types.mjs +3 -0
  13. package/code-tool-types.mjs.map +1 -0
  14. package/code-tool-worker.d.mts +5 -0
  15. package/code-tool-worker.d.mts.map +1 -0
  16. package/code-tool-worker.d.ts +5 -0
  17. package/code-tool-worker.d.ts.map +1 -0
  18. package/code-tool-worker.js +45 -0
  19. package/code-tool-worker.js.map +1 -0
  20. package/code-tool-worker.mjs +40 -0
  21. package/code-tool-worker.mjs.map +1 -0
  22. package/code-tool.d.mts +12 -0
  23. package/code-tool.d.mts.map +1 -0
  24. package/code-tool.d.ts +12 -0
  25. package/code-tool.d.ts.map +1 -0
  26. package/code-tool.js +157 -0
  27. package/code-tool.js.map +1 -0
  28. package/code-tool.mjs +121 -0
  29. package/code-tool.mjs.map +1 -0
  30. package/compat.d.mts +4 -2
  31. package/compat.d.mts.map +1 -1
  32. package/compat.d.ts +4 -2
  33. package/compat.d.ts.map +1 -1
  34. package/compat.js +8 -3
  35. package/compat.js.map +1 -1
  36. package/compat.mjs +7 -2
  37. package/compat.mjs.map +1 -1
  38. package/filtering.d.mts +2 -0
  39. package/filtering.d.mts.map +1 -0
  40. package/filtering.d.ts +2 -0
  41. package/filtering.d.ts.map +1 -0
  42. package/filtering.js +20 -0
  43. package/filtering.js.map +1 -0
  44. package/filtering.mjs +13 -0
  45. package/filtering.mjs.map +1 -0
  46. package/headers.d.mts +4 -0
  47. package/headers.d.mts.map +1 -0
  48. package/headers.d.ts +4 -0
  49. package/headers.d.ts.map +1 -0
  50. package/headers.js +22 -0
  51. package/headers.js.map +1 -0
  52. package/headers.mjs +18 -0
  53. package/headers.mjs.map +1 -0
  54. package/http.d.mts +9 -0
  55. package/http.d.mts.map +1 -0
  56. package/http.d.ts +9 -0
  57. package/http.d.ts.map +1 -0
  58. package/http.js +108 -0
  59. package/http.js.map +1 -0
  60. package/http.mjs +100 -0
  61. package/http.mjs.map +1 -0
  62. package/index.js +15 -10
  63. package/index.js.map +1 -1
  64. package/index.mjs +17 -12
  65. package/index.mjs.map +1 -1
  66. package/options.d.mts +11 -6
  67. package/options.d.mts.map +1 -1
  68. package/options.d.ts +11 -6
  69. package/options.d.ts.map +1 -1
  70. package/options.js +136 -15
  71. package/options.js.map +1 -1
  72. package/options.mjs +135 -15
  73. package/options.mjs.map +1 -1
  74. package/package.json +90 -4
  75. package/server.d.mts +4 -16
  76. package/server.d.mts.map +1 -1
  77. package/server.d.ts +4 -16
  78. package/server.d.ts.map +1 -1
  79. package/server.js +86 -33
  80. package/server.js.map +1 -1
  81. package/server.mjs +84 -32
  82. package/server.mjs.map +1 -1
  83. package/src/code-tool-paths.cts +3 -0
  84. package/src/code-tool-types.ts +14 -0
  85. package/src/code-tool-worker.ts +46 -0
  86. package/src/code-tool.ts +146 -0
  87. package/src/compat.ts +9 -4
  88. package/src/filtering.ts +14 -0
  89. package/src/headers.ts +23 -0
  90. package/src/http.ts +127 -0
  91. package/src/index.ts +18 -14
  92. package/src/options.ts +158 -21
  93. package/src/server.ts +103 -48
  94. package/src/stdio.ts +13 -0
  95. package/src/tools/metrics/create-metrics.ts +8 -2
  96. package/src/tools/metrics/update-metrics.ts +8 -2
  97. package/src/tools/projects/create-projects.ts +14 -5
  98. package/src/tools/projects/list-projects.ts +16 -5
  99. package/src/tools/records/create-records.ts +17 -5
  100. package/src/tools/runs/create-runs.ts +14 -5
  101. package/src/tools/scores/upsert-scores.ts +16 -5
  102. package/src/tools/systems/delete-systems.ts +16 -5
  103. package/src/tools/systems/get-systems.ts +16 -5
  104. package/src/tools/systems/list-systems.ts +17 -5
  105. package/src/tools/systems/update-systems.ts +13 -5
  106. package/src/tools/systems/upsert-systems.ts +15 -5
  107. package/src/tools/systems/versions/get-systems-versions.ts +18 -5
  108. package/src/tools/systems/versions/upsert-systems-versions.ts +16 -5
  109. package/src/tools/testcases/create-testcases.ts +15 -5
  110. package/src/tools/testcases/delete-testcases.ts +14 -5
  111. package/src/tools/testcases/get-testcases.ts +16 -5
  112. package/src/tools/testcases/list-testcases.ts +17 -5
  113. package/src/tools/testcases/update-testcases.ts +17 -5
  114. package/src/tools/testsets/create-testsets.ts +14 -5
  115. package/src/tools/testsets/delete-testsets.ts +16 -5
  116. package/src/tools/testsets/get-testsets.ts +16 -5
  117. package/src/tools/testsets/list-testsets.ts +17 -5
  118. package/src/tools/testsets/update-testsets.ts +14 -5
  119. package/src/tools/types.ts +1 -1
  120. package/stdio.d.mts +3 -0
  121. package/stdio.d.mts.map +1 -0
  122. package/stdio.d.ts +3 -0
  123. package/stdio.d.ts.map +1 -0
  124. package/stdio.js +14 -0
  125. package/stdio.js.map +1 -0
  126. package/stdio.mjs +10 -0
  127. package/stdio.mjs.map +1 -0
  128. package/tools/metrics/create-metrics.d.mts +1 -1
  129. package/tools/metrics/create-metrics.d.mts.map +1 -1
  130. package/tools/metrics/create-metrics.d.ts +1 -1
  131. package/tools/metrics/create-metrics.d.ts.map +1 -1
  132. package/tools/metrics/create-metrics.js +7 -0
  133. package/tools/metrics/create-metrics.js.map +1 -1
  134. package/tools/metrics/create-metrics.mjs +7 -0
  135. package/tools/metrics/create-metrics.mjs.map +1 -1
  136. package/tools/metrics/update-metrics.d.mts +1 -1
  137. package/tools/metrics/update-metrics.d.mts.map +1 -1
  138. package/tools/metrics/update-metrics.d.ts +1 -1
  139. package/tools/metrics/update-metrics.d.ts.map +1 -1
  140. package/tools/metrics/update-metrics.js +7 -0
  141. package/tools/metrics/update-metrics.js.map +1 -1
  142. package/tools/metrics/update-metrics.mjs +7 -0
  143. package/tools/metrics/update-metrics.mjs.map +1 -1
  144. package/tools/projects/create-projects.d.mts +1 -1
  145. package/tools/projects/create-projects.d.mts.map +1 -1
  146. package/tools/projects/create-projects.d.ts +1 -1
  147. package/tools/projects/create-projects.d.ts.map +1 -1
  148. package/tools/projects/create-projects.js +11 -3
  149. package/tools/projects/create-projects.js.map +1 -1
  150. package/tools/projects/create-projects.mjs +11 -3
  151. package/tools/projects/create-projects.mjs.map +1 -1
  152. package/tools/projects/list-projects.d.mts +1 -1
  153. package/tools/projects/list-projects.d.mts.map +1 -1
  154. package/tools/projects/list-projects.d.ts +1 -1
  155. package/tools/projects/list-projects.d.ts.map +1 -1
  156. package/tools/projects/list-projects.js +14 -3
  157. package/tools/projects/list-projects.js.map +1 -1
  158. package/tools/projects/list-projects.mjs +14 -3
  159. package/tools/projects/list-projects.mjs.map +1 -1
  160. package/tools/records/create-records.d.mts +1 -1
  161. package/tools/records/create-records.d.mts.map +1 -1
  162. package/tools/records/create-records.d.ts +1 -1
  163. package/tools/records/create-records.d.ts.map +1 -1
  164. package/tools/records/create-records.js +14 -3
  165. package/tools/records/create-records.js.map +1 -1
  166. package/tools/records/create-records.mjs +14 -3
  167. package/tools/records/create-records.mjs.map +1 -1
  168. package/tools/runs/create-runs.d.mts +1 -1
  169. package/tools/runs/create-runs.d.mts.map +1 -1
  170. package/tools/runs/create-runs.d.ts +1 -1
  171. package/tools/runs/create-runs.d.ts.map +1 -1
  172. package/tools/runs/create-runs.js +11 -3
  173. package/tools/runs/create-runs.js.map +1 -1
  174. package/tools/runs/create-runs.mjs +11 -3
  175. package/tools/runs/create-runs.mjs.map +1 -1
  176. package/tools/scores/upsert-scores.d.mts +1 -1
  177. package/tools/scores/upsert-scores.d.mts.map +1 -1
  178. package/tools/scores/upsert-scores.d.ts +1 -1
  179. package/tools/scores/upsert-scores.d.ts.map +1 -1
  180. package/tools/scores/upsert-scores.js +14 -3
  181. package/tools/scores/upsert-scores.js.map +1 -1
  182. package/tools/scores/upsert-scores.mjs +14 -3
  183. package/tools/scores/upsert-scores.mjs.map +1 -1
  184. package/tools/systems/delete-systems.d.mts +1 -1
  185. package/tools/systems/delete-systems.d.mts.map +1 -1
  186. package/tools/systems/delete-systems.d.ts +1 -1
  187. package/tools/systems/delete-systems.d.ts.map +1 -1
  188. package/tools/systems/delete-systems.js +13 -3
  189. package/tools/systems/delete-systems.js.map +1 -1
  190. package/tools/systems/delete-systems.mjs +13 -3
  191. package/tools/systems/delete-systems.mjs.map +1 -1
  192. package/tools/systems/get-systems.d.mts +1 -1
  193. package/tools/systems/get-systems.d.mts.map +1 -1
  194. package/tools/systems/get-systems.d.ts +1 -1
  195. package/tools/systems/get-systems.d.ts.map +1 -1
  196. package/tools/systems/get-systems.js +13 -3
  197. package/tools/systems/get-systems.js.map +1 -1
  198. package/tools/systems/get-systems.mjs +13 -3
  199. package/tools/systems/get-systems.mjs.map +1 -1
  200. package/tools/systems/list-systems.d.mts +1 -1
  201. package/tools/systems/list-systems.d.mts.map +1 -1
  202. package/tools/systems/list-systems.d.ts +1 -1
  203. package/tools/systems/list-systems.d.ts.map +1 -1
  204. package/tools/systems/list-systems.js +14 -3
  205. package/tools/systems/list-systems.js.map +1 -1
  206. package/tools/systems/list-systems.mjs +14 -3
  207. package/tools/systems/list-systems.mjs.map +1 -1
  208. package/tools/systems/update-systems.d.mts +1 -1
  209. package/tools/systems/update-systems.d.mts.map +1 -1
  210. package/tools/systems/update-systems.d.ts +1 -1
  211. package/tools/systems/update-systems.d.ts.map +1 -1
  212. package/tools/systems/update-systems.js +11 -3
  213. package/tools/systems/update-systems.js.map +1 -1
  214. package/tools/systems/update-systems.mjs +11 -3
  215. package/tools/systems/update-systems.mjs.map +1 -1
  216. package/tools/systems/upsert-systems.d.mts +1 -1
  217. package/tools/systems/upsert-systems.d.mts.map +1 -1
  218. package/tools/systems/upsert-systems.d.ts +1 -1
  219. package/tools/systems/upsert-systems.d.ts.map +1 -1
  220. package/tools/systems/upsert-systems.js +12 -3
  221. package/tools/systems/upsert-systems.js.map +1 -1
  222. package/tools/systems/upsert-systems.mjs +12 -3
  223. package/tools/systems/upsert-systems.mjs.map +1 -1
  224. package/tools/systems/versions/get-systems-versions.d.mts +1 -1
  225. package/tools/systems/versions/get-systems-versions.d.mts.map +1 -1
  226. package/tools/systems/versions/get-systems-versions.d.ts +1 -1
  227. package/tools/systems/versions/get-systems-versions.d.ts.map +1 -1
  228. package/tools/systems/versions/get-systems-versions.js +13 -3
  229. package/tools/systems/versions/get-systems-versions.js.map +1 -1
  230. package/tools/systems/versions/get-systems-versions.mjs +13 -3
  231. package/tools/systems/versions/get-systems-versions.mjs.map +1 -1
  232. package/tools/systems/versions/upsert-systems-versions.d.mts +1 -1
  233. package/tools/systems/versions/upsert-systems-versions.d.mts.map +1 -1
  234. package/tools/systems/versions/upsert-systems-versions.d.ts +1 -1
  235. package/tools/systems/versions/upsert-systems-versions.d.ts.map +1 -1
  236. package/tools/systems/versions/upsert-systems-versions.js +12 -3
  237. package/tools/systems/versions/upsert-systems-versions.js.map +1 -1
  238. package/tools/systems/versions/upsert-systems-versions.mjs +12 -3
  239. package/tools/systems/versions/upsert-systems-versions.mjs.map +1 -1
  240. package/tools/testcases/create-testcases.d.mts +1 -1
  241. package/tools/testcases/create-testcases.d.mts.map +1 -1
  242. package/tools/testcases/create-testcases.d.ts +1 -1
  243. package/tools/testcases/create-testcases.d.ts.map +1 -1
  244. package/tools/testcases/create-testcases.js +12 -3
  245. package/tools/testcases/create-testcases.js.map +1 -1
  246. package/tools/testcases/create-testcases.mjs +12 -3
  247. package/tools/testcases/create-testcases.mjs.map +1 -1
  248. package/tools/testcases/delete-testcases.d.mts +1 -1
  249. package/tools/testcases/delete-testcases.d.mts.map +1 -1
  250. package/tools/testcases/delete-testcases.d.ts +1 -1
  251. package/tools/testcases/delete-testcases.d.ts.map +1 -1
  252. package/tools/testcases/delete-testcases.js +11 -3
  253. package/tools/testcases/delete-testcases.js.map +1 -1
  254. package/tools/testcases/delete-testcases.mjs +11 -3
  255. package/tools/testcases/delete-testcases.mjs.map +1 -1
  256. package/tools/testcases/get-testcases.d.mts +1 -1
  257. package/tools/testcases/get-testcases.d.mts.map +1 -1
  258. package/tools/testcases/get-testcases.d.ts +1 -1
  259. package/tools/testcases/get-testcases.d.ts.map +1 -1
  260. package/tools/testcases/get-testcases.js +13 -3
  261. package/tools/testcases/get-testcases.js.map +1 -1
  262. package/tools/testcases/get-testcases.mjs +13 -3
  263. package/tools/testcases/get-testcases.mjs.map +1 -1
  264. package/tools/testcases/list-testcases.d.mts +1 -1
  265. package/tools/testcases/list-testcases.d.mts.map +1 -1
  266. package/tools/testcases/list-testcases.d.ts +1 -1
  267. package/tools/testcases/list-testcases.d.ts.map +1 -1
  268. package/tools/testcases/list-testcases.js +14 -3
  269. package/tools/testcases/list-testcases.js.map +1 -1
  270. package/tools/testcases/list-testcases.mjs +14 -3
  271. package/tools/testcases/list-testcases.mjs.map +1 -1
  272. package/tools/testcases/update-testcases.d.mts +1 -1
  273. package/tools/testcases/update-testcases.d.mts.map +1 -1
  274. package/tools/testcases/update-testcases.d.ts +1 -1
  275. package/tools/testcases/update-testcases.d.ts.map +1 -1
  276. package/tools/testcases/update-testcases.js +14 -3
  277. package/tools/testcases/update-testcases.js.map +1 -1
  278. package/tools/testcases/update-testcases.mjs +14 -3
  279. package/tools/testcases/update-testcases.mjs.map +1 -1
  280. package/tools/testsets/create-testsets.d.mts +1 -1
  281. package/tools/testsets/create-testsets.d.mts.map +1 -1
  282. package/tools/testsets/create-testsets.d.ts +1 -1
  283. package/tools/testsets/create-testsets.d.ts.map +1 -1
  284. package/tools/testsets/create-testsets.js +12 -3
  285. package/tools/testsets/create-testsets.js.map +1 -1
  286. package/tools/testsets/create-testsets.mjs +12 -3
  287. package/tools/testsets/create-testsets.mjs.map +1 -1
  288. package/tools/testsets/delete-testsets.d.mts +1 -1
  289. package/tools/testsets/delete-testsets.d.mts.map +1 -1
  290. package/tools/testsets/delete-testsets.d.ts +1 -1
  291. package/tools/testsets/delete-testsets.d.ts.map +1 -1
  292. package/tools/testsets/delete-testsets.js +13 -3
  293. package/tools/testsets/delete-testsets.js.map +1 -1
  294. package/tools/testsets/delete-testsets.mjs +13 -3
  295. package/tools/testsets/delete-testsets.mjs.map +1 -1
  296. package/tools/testsets/get-testsets.d.mts +1 -1
  297. package/tools/testsets/get-testsets.d.mts.map +1 -1
  298. package/tools/testsets/get-testsets.d.ts +1 -1
  299. package/tools/testsets/get-testsets.d.ts.map +1 -1
  300. package/tools/testsets/get-testsets.js +13 -3
  301. package/tools/testsets/get-testsets.js.map +1 -1
  302. package/tools/testsets/get-testsets.mjs +13 -3
  303. package/tools/testsets/get-testsets.mjs.map +1 -1
  304. package/tools/testsets/list-testsets.d.mts +1 -1
  305. package/tools/testsets/list-testsets.d.mts.map +1 -1
  306. package/tools/testsets/list-testsets.d.ts +1 -1
  307. package/tools/testsets/list-testsets.d.ts.map +1 -1
  308. package/tools/testsets/list-testsets.js +14 -3
  309. package/tools/testsets/list-testsets.js.map +1 -1
  310. package/tools/testsets/list-testsets.mjs +14 -3
  311. package/tools/testsets/list-testsets.mjs.map +1 -1
  312. package/tools/testsets/update-testsets.d.mts +1 -1
  313. package/tools/testsets/update-testsets.d.mts.map +1 -1
  314. package/tools/testsets/update-testsets.d.ts +1 -1
  315. package/tools/testsets/update-testsets.d.ts.map +1 -1
  316. package/tools/testsets/update-testsets.js +12 -3
  317. package/tools/testsets/update-testsets.js.map +1 -1
  318. package/tools/testsets/update-testsets.mjs +12 -3
  319. package/tools/testsets/update-testsets.mjs.map +1 -1
  320. package/tools/types.d.mts +1 -1
  321. package/tools/types.d.mts.map +1 -1
  322. package/tools/types.d.ts +1 -1
  323. package/tools/types.d.ts.map +1 -1
  324. package/tools/types.js.map +1 -1
  325. package/tools/types.mjs.map +1 -1
package/src/index.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { init, selectTools, server } from './server';
3
+ import { selectTools } from './server';
5
4
  import { Endpoint, endpoints } from './tools';
6
- import { McpOptions, parseOptions } from './options';
5
+ import { McpOptions, parseCLIOptions } from './options';
6
+ import { launchStdioServer } from './stdio';
7
+ import { launchStreamableHTTPServer } from './http';
7
8
 
8
9
  async function main() {
9
10
  const options = parseOptionsOrError();
@@ -13,18 +14,21 @@ async function main() {
13
14
  return;
14
15
  }
15
16
 
16
- const includedTools = selectToolsOrError(endpoints, options);
17
+ const selectedTools = await selectToolsOrError(endpoints, options);
17
18
 
18
19
  console.error(
19
- `MCP Server starting with ${includedTools.length} tools:`,
20
- includedTools.map((e) => e.tool.name),
20
+ `MCP Server starting with ${selectedTools.length} tools:`,
21
+ selectedTools.map((e) => e.tool.name),
21
22
  );
22
23
 
23
- init({ server, endpoints: includedTools });
24
-
25
- const transport = new StdioServerTransport();
26
- await server.connect(transport);
27
- console.error('MCP Server running on stdio');
24
+ switch (options.transport) {
25
+ case 'stdio':
26
+ await launchStdioServer(options);
27
+ break;
28
+ case 'http':
29
+ await launchStreamableHTTPServer(options, options.port ?? options.socket);
30
+ break;
31
+ }
28
32
  }
29
33
 
30
34
  if (require.main === module) {
@@ -36,16 +40,16 @@ if (require.main === module) {
36
40
 
37
41
  function parseOptionsOrError() {
38
42
  try {
39
- return parseOptions();
43
+ return parseCLIOptions();
40
44
  } catch (error) {
41
45
  console.error('Error parsing options:', error);
42
46
  process.exit(1);
43
47
  }
44
48
  }
45
49
 
46
- function selectToolsOrError(endpoints: Endpoint[], options: McpOptions) {
50
+ async function selectToolsOrError(endpoints: Endpoint[], options: McpOptions): Promise<Endpoint[]> {
47
51
  try {
48
- const includedTools = selectTools(endpoints, options);
52
+ const includedTools = await selectTools(endpoints, options);
49
53
  if (includedTools.length === 0) {
50
54
  console.error('No tools match the provided filters.');
51
55
  process.exit(1);
package/src/options.ts CHANGED
@@ -1,18 +1,24 @@
1
+ import qs from 'qs';
1
2
  import yargs from 'yargs';
2
3
  import { hideBin } from 'yargs/helpers';
4
+ import z from 'zod';
3
5
  import { endpoints, Filter } from './tools';
4
6
  import { ClientCapabilities, knownClients, ClientType } from './compat';
5
7
 
6
8
  export type CLIOptions = McpOptions & {
7
9
  list: boolean;
10
+ transport: 'stdio' | 'http';
11
+ port: number | undefined;
12
+ socket: string | undefined;
8
13
  };
9
14
 
10
15
  export type McpOptions = {
11
- client: ClientType | undefined;
12
- includeDynamicTools: boolean | undefined;
13
- includeAllTools: boolean | undefined;
14
- filters: Filter[];
15
- capabilities?: Partial<ClientCapabilities>;
16
+ client?: ClientType | undefined;
17
+ includeDynamicTools?: boolean | undefined;
18
+ includeAllTools?: boolean | undefined;
19
+ includeCodeTools?: boolean | undefined;
20
+ filters?: Filter[] | undefined;
21
+ capabilities?: Partial<ClientCapabilities> | undefined;
16
22
  };
17
23
 
18
24
  const CAPABILITY_CHOICES = [
@@ -44,18 +50,18 @@ function parseCapabilityValue(cap: string): { name: Capability; value?: number }
44
50
  return { name: cap as Capability };
45
51
  }
46
52
 
47
- export function parseOptions(): CLIOptions {
53
+ export function parseCLIOptions(): CLIOptions {
48
54
  const opts = yargs(hideBin(process.argv))
49
55
  .option('tools', {
50
56
  type: 'string',
51
57
  array: true,
52
- choices: ['dynamic', 'all'],
58
+ choices: ['dynamic', 'all', 'code'],
53
59
  description: 'Use dynamic tools or all tools',
54
60
  })
55
61
  .option('no-tools', {
56
62
  type: 'string',
57
63
  array: true,
58
- choices: ['dynamic', 'all'],
64
+ choices: ['dynamic', 'all', 'code'],
59
65
  description: 'Do not use any dynamic or all tools',
60
66
  })
61
67
  .option('tool', {
@@ -129,6 +135,20 @@ export function parseOptions(): CLIOptions {
129
135
  type: 'boolean',
130
136
  description: 'Print detailed explanation of client capabilities and exit',
131
137
  })
138
+ .option('transport', {
139
+ type: 'string',
140
+ choices: ['stdio', 'http'],
141
+ default: 'stdio',
142
+ description: 'What transport to use; stdio for local servers or http for remote servers',
143
+ })
144
+ .option('port', {
145
+ type: 'number',
146
+ description: 'Port to serve on if using http transport',
147
+ })
148
+ .option('socket', {
149
+ type: 'string',
150
+ description: 'Unix socket to serve on if using http transport',
151
+ })
132
152
  .help();
133
153
 
134
154
  for (const [command, desc] of examples()) {
@@ -184,14 +204,7 @@ export function parseOptions(): CLIOptions {
184
204
  }
185
205
 
186
206
  // Parse client capabilities
187
- const clientCapabilities: ClientCapabilities = {
188
- topLevelUnions: true,
189
- validJson: true,
190
- refs: true,
191
- unions: true,
192
- formats: true,
193
- toolNameLength: undefined,
194
- };
207
+ const clientCapabilities: Partial<ClientCapabilities> = {};
195
208
 
196
209
  // Apply individual capability overrides
197
210
  if (Array.isArray(argv.capability)) {
@@ -232,20 +245,144 @@ export function parseOptions(): CLIOptions {
232
245
  }
233
246
  }
234
247
 
248
+ const shouldIncludeToolType = (toolType: 'dynamic' | 'all' | 'code') =>
249
+ explicitTools ? argv.tools?.includes(toolType) && !argv.noTools?.includes(toolType) : undefined;
250
+
235
251
  const explicitTools = Boolean(argv.tools || argv.noTools);
236
- const includeDynamicTools =
237
- explicitTools ? argv.tools?.includes('dynamic') && !argv.noTools?.includes('dynamic') : undefined;
238
- const includeAllTools =
239
- explicitTools ? argv.tools?.includes('all') && !argv.noTools?.includes('all') : undefined;
252
+ const includeDynamicTools = shouldIncludeToolType('dynamic');
253
+ const includeAllTools = shouldIncludeToolType('all');
254
+ const includeCodeTools = shouldIncludeToolType('code');
255
+
256
+ const transport = argv.transport as 'stdio' | 'http';
240
257
 
241
258
  const client = argv.client as ClientType;
242
259
  return {
243
- client: client && knownClients[client] ? client : undefined,
260
+ client: client && client !== 'infer' && knownClients[client] ? client : undefined,
244
261
  includeDynamicTools,
245
262
  includeAllTools,
263
+ includeCodeTools,
246
264
  filters,
247
265
  capabilities: clientCapabilities,
248
266
  list: argv.list || false,
267
+ transport,
268
+ port: argv.port,
269
+ socket: argv.socket,
270
+ };
271
+ }
272
+
273
+ const coerceArray = <T extends z.ZodTypeAny>(zodType: T) =>
274
+ z.preprocess(
275
+ (val) =>
276
+ Array.isArray(val) ? val
277
+ : val ? [val]
278
+ : val,
279
+ z.array(zodType).optional(),
280
+ );
281
+
282
+ const QueryOptions = z.object({
283
+ tools: coerceArray(z.enum(['dynamic', 'all'])).describe('Use dynamic tools or all tools'),
284
+ no_tools: coerceArray(z.enum(['dynamic', 'all'])).describe('Do not use dynamic tools or all tools'),
285
+ tool: coerceArray(z.string()).describe('Include tools matching the specified names'),
286
+ resource: coerceArray(z.string()).describe('Include tools matching the specified resources'),
287
+ operation: coerceArray(z.enum(['read', 'write'])).describe(
288
+ 'Include tools matching the specified operations',
289
+ ),
290
+ tag: coerceArray(z.string()).describe('Include tools with the specified tags'),
291
+ no_tool: coerceArray(z.string()).describe('Exclude tools matching the specified names'),
292
+ no_resource: coerceArray(z.string()).describe('Exclude tools matching the specified resources'),
293
+ no_operation: coerceArray(z.enum(['read', 'write'])).describe(
294
+ 'Exclude tools matching the specified operations',
295
+ ),
296
+ no_tag: coerceArray(z.string()).describe('Exclude tools with the specified tags'),
297
+ client: ClientType.optional().describe('Specify the MCP client being used'),
298
+ capability: coerceArray(z.string()).describe('Specify client capabilities'),
299
+ no_capability: coerceArray(z.enum(CAPABILITY_CHOICES)).describe('Unset client capabilities'),
300
+ });
301
+
302
+ export function parseQueryOptions(defaultOptions: McpOptions, query: unknown): McpOptions {
303
+ const queryObject = typeof query === 'string' ? qs.parse(query) : query;
304
+ const queryOptions = QueryOptions.parse(queryObject);
305
+
306
+ const filters: Filter[] = [...(defaultOptions.filters ?? [])];
307
+
308
+ for (const resource of queryOptions.resource || []) {
309
+ filters.push({ type: 'resource', op: 'include', value: resource });
310
+ }
311
+ for (const operation of queryOptions.operation || []) {
312
+ filters.push({ type: 'operation', op: 'include', value: operation });
313
+ }
314
+ for (const tag of queryOptions.tag || []) {
315
+ filters.push({ type: 'tag', op: 'include', value: tag });
316
+ }
317
+ for (const tool of queryOptions.tool || []) {
318
+ filters.push({ type: 'tool', op: 'include', value: tool });
319
+ }
320
+ for (const resource of queryOptions.no_resource || []) {
321
+ filters.push({ type: 'resource', op: 'exclude', value: resource });
322
+ }
323
+ for (const operation of queryOptions.no_operation || []) {
324
+ filters.push({ type: 'operation', op: 'exclude', value: operation });
325
+ }
326
+ for (const tag of queryOptions.no_tag || []) {
327
+ filters.push({ type: 'tag', op: 'exclude', value: tag });
328
+ }
329
+ for (const tool of queryOptions.no_tool || []) {
330
+ filters.push({ type: 'tool', op: 'exclude', value: tool });
331
+ }
332
+
333
+ // Parse client capabilities
334
+ const clientCapabilities: Partial<ClientCapabilities> = { ...defaultOptions.capabilities };
335
+
336
+ for (const cap of queryOptions.capability || []) {
337
+ const parsed = parseCapabilityValue(cap);
338
+ if (parsed.name === 'top-level-unions') {
339
+ clientCapabilities.topLevelUnions = true;
340
+ } else if (parsed.name === 'valid-json') {
341
+ clientCapabilities.validJson = true;
342
+ } else if (parsed.name === 'refs') {
343
+ clientCapabilities.refs = true;
344
+ } else if (parsed.name === 'unions') {
345
+ clientCapabilities.unions = true;
346
+ } else if (parsed.name === 'formats') {
347
+ clientCapabilities.formats = true;
348
+ } else if (parsed.name === 'tool-name-length') {
349
+ clientCapabilities.toolNameLength = parsed.value;
350
+ }
351
+ }
352
+
353
+ for (const cap of queryOptions.no_capability || []) {
354
+ if (cap === 'top-level-unions') {
355
+ clientCapabilities.topLevelUnions = false;
356
+ } else if (cap === 'valid-json') {
357
+ clientCapabilities.validJson = false;
358
+ } else if (cap === 'refs') {
359
+ clientCapabilities.refs = false;
360
+ } else if (cap === 'unions') {
361
+ clientCapabilities.unions = false;
362
+ } else if (cap === 'formats') {
363
+ clientCapabilities.formats = false;
364
+ } else if (cap === 'tool-name-length') {
365
+ clientCapabilities.toolNameLength = undefined;
366
+ }
367
+ }
368
+
369
+ let dynamicTools: boolean | undefined =
370
+ queryOptions.no_tools && queryOptions.no_tools?.includes('dynamic') ? false
371
+ : queryOptions.tools?.includes('dynamic') ? true
372
+ : defaultOptions.includeDynamicTools;
373
+
374
+ let allTools: boolean | undefined =
375
+ queryOptions.no_tools && queryOptions.no_tools?.includes('all') ? false
376
+ : queryOptions.tools?.includes('all') ? true
377
+ : defaultOptions.includeAllTools;
378
+
379
+ return {
380
+ client: queryOptions.client ?? defaultOptions.client,
381
+ includeDynamicTools: dynamicTools,
382
+ includeAllTools: allTools,
383
+ includeCodeTools: undefined,
384
+ filters,
385
+ capabilities: clientCapabilities,
249
386
  };
250
387
  }
251
388
 
package/src/server.ts CHANGED
@@ -3,7 +3,13 @@
3
3
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { Endpoint, endpoints, HandlerFunction, query } from './tools';
6
- import { CallToolRequestSchema, ListToolsRequestSchema, Tool } from '@modelcontextprotocol/sdk/types.js';
6
+ import {
7
+ CallToolRequestSchema,
8
+ ListToolsRequestSchema,
9
+ SetLevelRequestSchema,
10
+ Implementation,
11
+ Tool,
12
+ } from '@modelcontextprotocol/sdk/types.js';
7
13
  import { ClientOptions } from 'scorecard-ai';
8
14
  import Scorecard from 'scorecard-ai';
9
15
  import {
@@ -14,6 +20,7 @@ import {
14
20
  parseEmbeddedJSON,
15
21
  } from './compat';
16
22
  import { dynamicTools } from './dynamic-tools';
23
+ import { codeTool } from './code-tool';
17
24
  import { McpOptions } from './options';
18
25
 
19
26
  export { McpOptions } from './options';
@@ -22,18 +29,17 @@ export { Filter } from './tools';
22
29
  export { ClientOptions } from 'scorecard-ai';
23
30
  export { endpoints } from './tools';
24
31
 
25
- // Create server instance
26
- export const server = new McpServer(
27
- {
28
- name: 'scorecard_ai_api',
29
- version: '2.0.0',
30
- },
31
- {
32
- capabilities: {
33
- tools: {},
32
+ export const newMcpServer = () =>
33
+ new McpServer(
34
+ {
35
+ name: 'scorecard_ai_api',
36
+ version: '2.1.1',
34
37
  },
35
- },
36
- );
38
+ { capabilities: { tools: {}, logging: {} } },
39
+ );
40
+
41
+ // Create server instance
42
+ export const server = newMcpServer();
37
43
 
38
44
  /**
39
45
  * Initializes the provided MCP Server with the given tools and handlers.
@@ -41,77 +47,126 @@ export const server = new McpServer(
41
47
  */
42
48
  export function initMcpServer(params: {
43
49
  server: Server | McpServer;
44
- clientOptions: ClientOptions;
45
- mcpOptions: McpOptions;
46
- endpoints?: { tool: Tool; handler: HandlerFunction }[];
47
- }) {
48
- const transformedEndpoints = selectTools(endpoints, params.mcpOptions);
49
- const client = new Scorecard(params.clientOptions);
50
- const capabilities = {
51
- ...defaultClientCapabilities,
52
- ...(params.mcpOptions.client ? knownClients[params.mcpOptions.client] : params.mcpOptions.capabilities),
53
- };
54
- init({ server: params.server, client, endpoints: transformedEndpoints, capabilities });
55
- }
56
-
57
- export function init(params: {
58
- server: Server | McpServer;
59
- client?: Scorecard;
60
- endpoints?: { tool: Tool; handler: HandlerFunction }[];
61
- capabilities?: Partial<ClientCapabilities>;
50
+ clientOptions?: ClientOptions;
51
+ mcpOptions?: McpOptions;
62
52
  }) {
63
53
  const server = params.server instanceof McpServer ? params.server.server : params.server;
64
- const providedEndpoints = params.endpoints || endpoints;
54
+ const mcpOptions = params.mcpOptions ?? {};
55
+
56
+ let providedEndpoints: Endpoint[] | null = null;
57
+ let endpointMap: Record<string, Endpoint> | null = null;
58
+
59
+ const initTools = async (implementation?: Implementation) => {
60
+ if (implementation && (!mcpOptions.client || mcpOptions.client === 'infer')) {
61
+ mcpOptions.client =
62
+ implementation.name.toLowerCase().includes('claude') ? 'claude'
63
+ : implementation.name.toLowerCase().includes('cursor') ? 'cursor'
64
+ : undefined;
65
+ mcpOptions.capabilities = {
66
+ ...(mcpOptions.client && knownClients[mcpOptions.client]),
67
+ ...mcpOptions.capabilities,
68
+ };
69
+ }
70
+ providedEndpoints ??= await selectTools(endpoints, mcpOptions);
71
+ endpointMap ??= Object.fromEntries(providedEndpoints.map((endpoint) => [endpoint.tool.name, endpoint]));
72
+ };
65
73
 
66
- const endpointMap = Object.fromEntries(providedEndpoints.map((endpoint) => [endpoint.tool.name, endpoint]));
74
+ const logAtLevel =
75
+ (level: 'debug' | 'info' | 'warning' | 'error') =>
76
+ (message: string, ...rest: unknown[]) => {
77
+ void server.sendLoggingMessage({
78
+ level,
79
+ data: { message, rest },
80
+ });
81
+ };
82
+ const logger = {
83
+ debug: logAtLevel('debug'),
84
+ info: logAtLevel('info'),
85
+ warn: logAtLevel('warning'),
86
+ error: logAtLevel('error'),
87
+ };
67
88
 
68
- const client =
69
- params.client ||
70
- new Scorecard({
71
- environment: (readEnv('SCORECARD_ENVIRONMENT') || undefined) as any,
72
- defaultHeaders: { 'X-Stainless-MCP': 'true' },
73
- });
89
+ let client = new Scorecard({
90
+ ...{ environment: (readEnv('SCORECARD_ENVIRONMENT') || undefined) as any },
91
+ logger,
92
+ ...params.clientOptions,
93
+ defaultHeaders: {
94
+ ...params.clientOptions?.defaultHeaders,
95
+ 'X-Stainless-MCP': 'true',
96
+ },
97
+ });
74
98
 
75
99
  server.setRequestHandler(ListToolsRequestSchema, async () => {
100
+ if (providedEndpoints === null) {
101
+ await initTools(server.getClientVersion());
102
+ }
76
103
  return {
77
- tools: providedEndpoints.map((endpoint) => endpoint.tool),
104
+ tools: providedEndpoints!.map((endpoint) => endpoint.tool),
78
105
  };
79
106
  });
80
107
 
81
108
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
109
+ if (endpointMap === null) {
110
+ await initTools(server.getClientVersion());
111
+ }
82
112
  const { name, arguments: args } = request.params;
83
- const endpoint = endpointMap[name];
113
+ const endpoint = endpointMap![name];
84
114
  if (!endpoint) {
85
115
  throw new Error(`Unknown tool: ${name}`);
86
116
  }
87
117
 
88
- return executeHandler(endpoint.tool, endpoint.handler, client, args, params.capabilities);
118
+ return executeHandler(endpoint.tool, endpoint.handler, client, args, mcpOptions.capabilities);
119
+ });
120
+
121
+ server.setRequestHandler(SetLevelRequestSchema, async (request) => {
122
+ const { level } = request.params;
123
+ switch (level) {
124
+ case 'debug':
125
+ client = client.withOptions({ logLevel: 'debug' });
126
+ break;
127
+ case 'info':
128
+ client = client.withOptions({ logLevel: 'info' });
129
+ break;
130
+ case 'notice':
131
+ case 'warning':
132
+ client = client.withOptions({ logLevel: 'warn' });
133
+ break;
134
+ case 'error':
135
+ client = client.withOptions({ logLevel: 'error' });
136
+ break;
137
+ default:
138
+ client = client.withOptions({ logLevel: 'off' });
139
+ break;
140
+ }
141
+ return {};
89
142
  });
90
143
  }
91
144
 
92
145
  /**
93
146
  * Selects the tools to include in the MCP Server based on the provided options.
94
147
  */
95
- export function selectTools(endpoints: Endpoint[], options: McpOptions) {
96
- const filteredEndpoints = query(options.filters, endpoints);
148
+ export async function selectTools(endpoints: Endpoint[], options?: McpOptions): Promise<Endpoint[]> {
149
+ const filteredEndpoints = query(options?.filters ?? [], endpoints);
97
150
 
98
151
  let includedTools = filteredEndpoints;
99
152
 
100
153
  if (includedTools.length > 0) {
101
- if (options.includeDynamicTools) {
154
+ if (options?.includeDynamicTools) {
102
155
  includedTools = dynamicTools(includedTools);
103
156
  }
104
157
  } else {
105
- if (options.includeAllTools) {
158
+ if (options?.includeAllTools) {
106
159
  includedTools = endpoints;
107
- } else if (options.includeDynamicTools) {
160
+ } else if (options?.includeDynamicTools) {
108
161
  includedTools = dynamicTools(endpoints);
162
+ } else if (options?.includeCodeTools) {
163
+ includedTools = [await codeTool()];
109
164
  } else {
110
165
  includedTools = endpoints;
111
166
  }
112
167
  }
113
168
 
114
- const capabilities = { ...defaultClientCapabilities, ...options.capabilities };
169
+ const capabilities = { ...defaultClientCapabilities, ...options?.capabilities };
115
170
  return applyCompatibilityTransformations(includedTools, capabilities);
116
171
  }
117
172
 
@@ -126,7 +181,7 @@ export async function executeHandler(
126
181
  compatibilityOptions?: Partial<ClientCapabilities>,
127
182
  ) {
128
183
  const options = { ...defaultClientCapabilities, ...compatibilityOptions };
129
- if (options.validJson && args) {
184
+ if (!options.validJson && args) {
130
185
  args = parseEmbeddedJSON(args, tool.inputSchema);
131
186
  }
132
187
  return await handler(client, args || {});
package/src/stdio.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
2
+ import { initMcpServer, newMcpServer } from './server';
3
+ import { McpOptions } from './options';
4
+
5
+ export const launchStdioServer = async (options: McpOptions) => {
6
+ const server = newMcpServer();
7
+
8
+ initMcpServer({ server, mcpOptions: options });
9
+
10
+ const transport = new StdioServerTransport();
11
+ await server.connect(transport);
12
+ console.error('MCP Server running on stdio');
13
+ };
@@ -1,9 +1,8 @@
1
1
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
- import { asTextContentResult } from 'scorecard-ai-mcp/tools/types';
3
+ import { Metadata, asTextContentResult } from 'scorecard-ai-mcp/tools/types';
4
4
 
5
5
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
6
- import type { Metadata } from '../';
7
6
  import Scorecard from 'scorecard-ai';
8
7
 
9
8
  export const metadata: Metadata = {
@@ -68,6 +67,7 @@ export const tool: Tool = {
68
67
  description: 'The temperature for AI evaluation (0-2).',
69
68
  },
70
69
  },
70
+ required: ['projectId', 'evalType', 'name', 'outputType', 'promptTemplate'],
71
71
  },
72
72
  {
73
73
  type: 'object',
@@ -102,6 +102,7 @@ export const tool: Tool = {
102
102
  description: 'The threshold for determining pass/fail from integer scores (1-5).',
103
103
  },
104
104
  },
105
+ required: ['projectId', 'evalType', 'name', 'outputType'],
105
106
  },
106
107
  {
107
108
  type: 'object',
@@ -136,6 +137,7 @@ export const tool: Tool = {
136
137
  description: 'The threshold for determining pass/fail from integer scores (1-5).',
137
138
  },
138
139
  },
140
+ required: ['projectId', 'evalType', 'name', 'outputType'],
139
141
  },
140
142
  {
141
143
  type: 'object',
@@ -179,6 +181,7 @@ export const tool: Tool = {
179
181
  description: 'The temperature for AI evaluation (0-2).',
180
182
  },
181
183
  },
184
+ required: ['projectId', 'evalType', 'name', 'outputType', 'promptTemplate'],
182
185
  },
183
186
  {
184
187
  type: 'object',
@@ -209,6 +212,7 @@ export const tool: Tool = {
209
212
  description: 'Guidelines for human evaluators.',
210
213
  },
211
214
  },
215
+ required: ['projectId', 'evalType', 'name', 'outputType'],
212
216
  },
213
217
  {
214
218
  type: 'object',
@@ -239,9 +243,11 @@ export const tool: Tool = {
239
243
  description: 'Optional guidelines for heuristic evaluation logic.',
240
244
  },
241
245
  },
246
+ required: ['projectId', 'evalType', 'name', 'outputType'],
242
247
  },
243
248
  ],
244
249
  },
250
+ annotations: {},
245
251
  };
246
252
 
247
253
  export const handler = async (client: Scorecard, args: Record<string, unknown> | undefined) => {
@@ -1,9 +1,8 @@
1
1
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
- import { asTextContentResult } from 'scorecard-ai-mcp/tools/types';
3
+ import { Metadata, asTextContentResult } from 'scorecard-ai-mcp/tools/types';
4
4
 
5
5
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
6
- import type { Metadata } from '../';
7
6
  import Scorecard from 'scorecard-ai';
8
7
 
9
8
  export const metadata: Metadata = {
@@ -68,6 +67,7 @@ export const tool: Tool = {
68
67
  description: 'The temperature for AI evaluation (0-2).',
69
68
  },
70
69
  },
70
+ required: ['metricId', 'evalType', 'outputType'],
71
71
  },
72
72
  {
73
73
  type: 'object',
@@ -102,6 +102,7 @@ export const tool: Tool = {
102
102
  description: 'The threshold for determining pass/fail from integer scores (1-5).',
103
103
  },
104
104
  },
105
+ required: ['metricId', 'evalType', 'outputType'],
105
106
  },
106
107
  {
107
108
  type: 'object',
@@ -136,6 +137,7 @@ export const tool: Tool = {
136
137
  description: 'The threshold for determining pass/fail from integer scores (1-5).',
137
138
  },
138
139
  },
140
+ required: ['metricId', 'evalType', 'outputType'],
139
141
  },
140
142
  {
141
143
  type: 'object',
@@ -179,6 +181,7 @@ export const tool: Tool = {
179
181
  description: 'The temperature for AI evaluation (0-2).',
180
182
  },
181
183
  },
184
+ required: ['metricId', 'evalType', 'outputType'],
182
185
  },
183
186
  {
184
187
  type: 'object',
@@ -209,6 +212,7 @@ export const tool: Tool = {
209
212
  description: 'The name of the Metric.',
210
213
  },
211
214
  },
215
+ required: ['metricId', 'evalType', 'outputType'],
212
216
  },
213
217
  {
214
218
  type: 'object',
@@ -239,9 +243,11 @@ export const tool: Tool = {
239
243
  description: 'The name of the Metric.',
240
244
  },
241
245
  },
246
+ required: ['metricId', 'evalType', 'outputType'],
242
247
  },
243
248
  ],
244
249
  },
250
+ annotations: {},
245
251
  };
246
252
 
247
253
  export const handler = async (client: Scorecard, args: Record<string, unknown> | undefined) => {