hugging-bay-mcp 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 (5) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/index.mjs +1976 -0
  4. package/package.json +40 -0
  5. package/server.json +42 -0
package/index.mjs ADDED
@@ -0,0 +1,1976 @@
1
+ #!/usr/bin/env node
2
+
3
+ const apiBase = process.env.HUGGING_BAY_API || "https://huggingbay.xyz";
4
+ const token =
5
+ process.env.HUGGING_BAY_TOKEN ||
6
+ process.env.HUGGING_BAY_ADMIN_TOKEN ||
7
+ process.env.HUGGING_BAY_PUBLISHER_TOKEN ||
8
+ process.env.HUGGING_BAY_READER_TOKEN ||
9
+ "";
10
+ const serverInfo = { name: "hugging-bay-mcp", version: "0.1.0" };
11
+ const localToolEnum = ["ollama", "lm-studio", "comfyui", "transformers", "llama.cpp"];
12
+
13
+ const tools = [
14
+ {
15
+ name: "get_health",
16
+ description: "Return Hugging Bay public health and persistence state.",
17
+ inputSchema: {
18
+ type: "object",
19
+ properties: {},
20
+ additionalProperties: false,
21
+ },
22
+ },
23
+ {
24
+ name: "get_catalog_coverage",
25
+ description: "Return public catalog scale, source coverage, and readiness facts.",
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {},
29
+ additionalProperties: false,
30
+ },
31
+ },
32
+ {
33
+ name: "get_open_source_radar",
34
+ description: "Return popular, newest, and non-Hugging Face open-source AI records in one bounded response.",
35
+ inputSchema: {
36
+ type: "object",
37
+ properties: {},
38
+ additionalProperties: false,
39
+ },
40
+ },
41
+ {
42
+ name: "get_trending",
43
+ description: "Return public trending artifacts from aggregate pageview, hosted-download, mirror-request, and product-action signals.",
44
+ inputSchema: {
45
+ type: "object",
46
+ properties: {
47
+ window: { type: "string", enum: ["24h", "7d", "30d", "all"] },
48
+ limit: { type: "number", minimum: 1, maximum: 50 },
49
+ },
50
+ additionalProperties: false,
51
+ },
52
+ },
53
+ {
54
+ name: "get_traffic",
55
+ description: "Return privacy-safe aggregate Hugging Bay usage, hosted-download, mirror-request, product-action, and agent/crawler discovery signals.",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {},
59
+ additionalProperties: false,
60
+ },
61
+ },
62
+ {
63
+ name: "get_agent_discovery",
64
+ description: "Return the single-call agent discovery contract for answer engines, OpenClaw/Hermes-style agents, MCP clients, OpenAPI users, crawlers, citation targets, and bounded API entrypoints.",
65
+ inputSchema: {
66
+ type: "object",
67
+ properties: {},
68
+ additionalProperties: false,
69
+ },
70
+ },
71
+ {
72
+ name: "get_ai_bot_allowlist",
73
+ description: "Return the machine-readable AI crawler/user-agent allowlist, official verification links, and WAF guidance.",
74
+ inputSchema: {
75
+ type: "object",
76
+ properties: {},
77
+ additionalProperties: false,
78
+ },
79
+ },
80
+ {
81
+ name: "get_ai_search_guidance",
82
+ description: "Return citation-ready AI-search guidance for ChatGPT, Perplexity, Gemini, Claude, Grok, OpenClaw, Hermes, and local agents.",
83
+ inputSchema: {
84
+ type: "object",
85
+ properties: {},
86
+ additionalProperties: false,
87
+ },
88
+ },
89
+ {
90
+ name: "get_ai_mention_monitor",
91
+ description: "Return prompt-level answer-engine monitoring targets, expected citations, crawler signals, and claim boundaries.",
92
+ inputSchema: {
93
+ type: "object",
94
+ properties: {},
95
+ additionalProperties: false,
96
+ },
97
+ },
98
+ {
99
+ name: "get_ai_mention_results",
100
+ description: "Return observed answer-engine mention and citation results, including provider, prompt, status, citation rank, wrong-claim flags, and bounded excerpts.",
101
+ inputSchema: {
102
+ type: "object",
103
+ properties: {
104
+ provider: { type: "string" },
105
+ promptId: { type: "string" },
106
+ limit: { type: "number", minimum: 1, maximum: 200 },
107
+ },
108
+ additionalProperties: false,
109
+ },
110
+ },
111
+ {
112
+ name: "get_source_coverage",
113
+ description: "Return one provider's source coverage, policy, rollups, and top imported records.",
114
+ inputSchema: {
115
+ type: "object",
116
+ properties: {
117
+ id: { type: "string", enum: ["huggingface", "github", "arxiv", "openml", "zenodo", "dataverse", "datacite", "paperswithcode", "opendatalab", "opencompass", "modelscope"] },
118
+ },
119
+ required: ["id"],
120
+ additionalProperties: false,
121
+ },
122
+ },
123
+ {
124
+ name: "get_recommendations",
125
+ description: "Return Hugging Bay catalog expansion facts, mirror candidates, scale totals, and pack summaries.",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {},
129
+ additionalProperties: false,
130
+ },
131
+ },
132
+ {
133
+ name: "recommend_artifacts",
134
+ description: "Return ranked artifacts for a concrete use case, with fit reasons, tool commands, hosted download links, and mirror actions.",
135
+ inputSchema: {
136
+ type: "object",
137
+ properties: {
138
+ useCase: { type: "string" },
139
+ q: { type: "string" },
140
+ tool: { type: "string", enum: localToolEnum },
141
+ commercial: { type: "boolean" },
142
+ hosted: { type: "boolean" },
143
+ limit: { type: "number", minimum: 1, maximum: 25 },
144
+ },
145
+ additionalProperties: false,
146
+ },
147
+ },
148
+ {
149
+ name: "get_agent_tasks",
150
+ description: "Return intent-specific agent action plans for RAG embeddings, hosted downloads, commercial-safe search, and mirror prioritization.",
151
+ inputSchema: {
152
+ type: "object",
153
+ properties: {},
154
+ additionalProperties: false,
155
+ },
156
+ },
157
+ {
158
+ name: "get_publisher_workflow",
159
+ description: "Return publisher application, large-upload, release-check, and publishing workflow for agents.",
160
+ inputSchema: {
161
+ type: "object",
162
+ properties: {},
163
+ additionalProperties: false,
164
+ },
165
+ },
166
+ {
167
+ name: "get_publisher_release_template",
168
+ description: "Return a copyable Hugging Bay release manifest template for labs, including source URLs, hashes, runtime notes, upload-session body, and reviewed fallback fields.",
169
+ inputSchema: {
170
+ type: "object",
171
+ properties: {
172
+ kind: { type: "string", enum: ["llm", "dataset", "vision", "audio", "agent", "app", "eval"] },
173
+ },
174
+ additionalProperties: false,
175
+ },
176
+ },
177
+ {
178
+ name: "list_publishers",
179
+ description: "List public publisher namespaces with artifact counts, hosted-file counts, claim state, and trust stats.",
180
+ inputSchema: {
181
+ type: "object",
182
+ properties: {
183
+ q: { type: "string" },
184
+ limit: { type: "number", minimum: 1, maximum: 100 },
185
+ },
186
+ additionalProperties: false,
187
+ },
188
+ },
189
+ {
190
+ name: "get_publisher_profile",
191
+ description: "Fetch one public publisher namespace profile with releases, hosted files, claim state, and trust stats.",
192
+ inputSchema: {
193
+ type: "object",
194
+ required: ["namespace"],
195
+ properties: {
196
+ namespace: { type: "string" },
197
+ limit: { type: "number", minimum: 1, maximum: 100 },
198
+ },
199
+ additionalProperties: false,
200
+ },
201
+ },
202
+ {
203
+ name: "get_publisher_dashboard",
204
+ description: "Return publisher-owned releases, release blockers, and upload sessions. Requires HUGGING_BAY_TOKEN with publisher/admin role.",
205
+ inputSchema: {
206
+ type: "object",
207
+ properties: {},
208
+ additionalProperties: false,
209
+ },
210
+ },
211
+ {
212
+ name: "list_saved_searches",
213
+ description: "List saved catalog searches/watchlists for HUGGING_BAY_TOKEN.",
214
+ inputSchema: {
215
+ type: "object",
216
+ properties: {
217
+ alerts: { type: "string", enum: ["1"], description: "Include bounded alert state." },
218
+ alertLimit: { type: "number", minimum: 1, maximum: 50 },
219
+ previewLimit: { type: "number", minimum: 1, maximum: 50 },
220
+ },
221
+ additionalProperties: false,
222
+ },
223
+ },
224
+ {
225
+ name: "list_saved_search_alerts",
226
+ description: "List enabled saved-search alerts for HUGGING_BAY_TOKEN, including new matching artifacts since the last seen window.",
227
+ inputSchema: {
228
+ type: "object",
229
+ properties: {
230
+ limit: { type: "number", minimum: 1, maximum: 50 },
231
+ previewLimit: { type: "number", minimum: 1, maximum: 50 },
232
+ },
233
+ additionalProperties: false,
234
+ },
235
+ },
236
+ {
237
+ name: "get_saved_search_digest",
238
+ description: "Return a bounded live digest for one saved catalog watchlist, including artifact/card/file URLs and mirror-request actions. Requires HUGGING_BAY_TOKEN.",
239
+ inputSchema: {
240
+ type: "object",
241
+ required: ["searchId"],
242
+ properties: {
243
+ searchId: { type: "string" },
244
+ id: { type: "string", description: "Deprecated alias for searchId." },
245
+ limit: { type: "number", minimum: 1, maximum: 50 },
246
+ },
247
+ additionalProperties: false,
248
+ },
249
+ },
250
+ {
251
+ name: "save_saved_search",
252
+ description: "Save a durable catalog watchlist with filters, sort, browser path, and agent-ready API path for HUGGING_BAY_TOKEN.",
253
+ inputSchema: {
254
+ type: "object",
255
+ properties: {
256
+ searchId: { type: "string", description: "Stable saved-search id. Alias of id for clients that use searchId consistently." },
257
+ id: { type: "string" },
258
+ label: { type: "string" },
259
+ filters: { type: "object", additionalProperties: true },
260
+ sortKey: { type: "string", enum: ["best", "ready", "mirrorable", "trust", "updated", "downloads", "stars", "mirrors", "name", "size", "license"] },
261
+ route: { type: "string" },
262
+ resultCount: { type: "number" },
263
+ notificationsEnabled: { type: "boolean" },
264
+ alert: { type: "object", additionalProperties: true },
265
+ delivery: {
266
+ type: "object",
267
+ properties: {
268
+ browser: { type: "object", additionalProperties: true },
269
+ apiDigest: { type: "object", additionalProperties: true },
270
+ webhook: { type: "object", additionalProperties: true },
271
+ email: { type: "object", additionalProperties: true },
272
+ },
273
+ additionalProperties: true,
274
+ },
275
+ },
276
+ additionalProperties: true,
277
+ },
278
+ },
279
+ {
280
+ name: "delete_saved_search",
281
+ description: "Delete one saved catalog watchlist for HUGGING_BAY_TOKEN.",
282
+ inputSchema: {
283
+ type: "object",
284
+ required: ["searchId"],
285
+ properties: {
286
+ searchId: { type: "string" },
287
+ id: { type: "string", description: "Deprecated alias for searchId." },
288
+ },
289
+ additionalProperties: false,
290
+ },
291
+ },
292
+ {
293
+ name: "apply_publisher_application",
294
+ description: "Submit a public publisher namespace application for manual review. Does not create accounts or tokens automatically.",
295
+ inputSchema: {
296
+ type: "object",
297
+ required: ["namespace", "displayName", "contact", "sourceUrl", "artifactTypes", "intendedUse", "provenancePlan", "acceptedTerms"],
298
+ properties: {
299
+ namespace: { type: "string" },
300
+ displayName: { type: "string" },
301
+ contact: { type: "string" },
302
+ website: { type: "string" },
303
+ sourceUrl: { type: "string" },
304
+ artifactTypes: { type: "array", items: { type: "string", enum: ["llm", "embedding", "audio", "vision", "agent", "dataset", "app", "tool", "eval"] } },
305
+ intendedUse: { type: "string" },
306
+ provenancePlan: { type: "string" },
307
+ expectedUploads: { type: "string" },
308
+ acceptedTerms: { type: "boolean" },
309
+ },
310
+ additionalProperties: false,
311
+ },
312
+ },
313
+ {
314
+ name: "get_publisher_application_status",
315
+ description: "Fetch sanitized public status for one publisher namespace application.",
316
+ inputSchema: {
317
+ type: "object",
318
+ required: ["caseId"],
319
+ properties: {
320
+ caseId: { type: "string" },
321
+ id: { type: "string", description: "Deprecated alias for caseId." },
322
+ },
323
+ additionalProperties: false,
324
+ },
325
+ },
326
+ {
327
+ name: "request_source_indexing",
328
+ description: "Queue a missing supported upstream source URL or repo for Hugging Bay indexing and mirror review.",
329
+ inputSchema: {
330
+ type: "object",
331
+ required: ["repo"],
332
+ properties: {
333
+ repo: { type: "string" },
334
+ source: { type: "string", enum: ["huggingface", "modelscope", "github", "zenodo", "arxiv"] },
335
+ useCase: { type: "string" },
336
+ targetTool: { type: "string" },
337
+ desiredFiles: { type: "array", items: { type: "string" } },
338
+ contact: { type: "string" },
339
+ },
340
+ additionalProperties: false,
341
+ },
342
+ },
343
+ {
344
+ name: "get_source_request_status",
345
+ description: "Fetch sanitized public status for one source indexing request.",
346
+ inputSchema: {
347
+ type: "object",
348
+ required: ["caseId"],
349
+ properties: {
350
+ caseId: { type: "string" },
351
+ id: { type: "string", description: "Deprecated alias for caseId." },
352
+ },
353
+ additionalProperties: false,
354
+ },
355
+ },
356
+ {
357
+ name: "list_publisher_api_keys",
358
+ description: "List scoped publisher automation tokens visible to HUGGING_BAY_TOKEN.",
359
+ inputSchema: {
360
+ type: "object",
361
+ properties: { limit: { type: "number", minimum: 1, maximum: 100 } },
362
+ additionalProperties: false,
363
+ },
364
+ },
365
+ {
366
+ name: "create_publisher_api_key",
367
+ description: "Create an additional scoped publisher automation token. Plaintext token is returned once.",
368
+ inputSchema: {
369
+ type: "object",
370
+ properties: {
371
+ allowedOwners: { type: "array", items: { type: "string" } },
372
+ displayName: { type: "string" },
373
+ purpose: { type: "string" },
374
+ },
375
+ additionalProperties: false,
376
+ },
377
+ },
378
+ {
379
+ name: "revoke_publisher_api_key",
380
+ description: "Revoke a scoped publisher automation token visible to HUGGING_BAY_TOKEN.",
381
+ inputSchema: {
382
+ type: "object",
383
+ required: ["keyId"],
384
+ properties: {
385
+ keyId: { type: "string" },
386
+ id: { type: "string", description: "Deprecated alias for keyId." },
387
+ },
388
+ additionalProperties: false,
389
+ },
390
+ },
391
+ {
392
+ name: "get_mirror_readiness",
393
+ description: "Return mirror candidates with readiness scores, blockers, compatible tools, and selected safe files.",
394
+ inputSchema: {
395
+ type: "object",
396
+ properties: {
397
+ limit: { type: "number", minimum: 1, maximum: 200 },
398
+ requestedOnly: { type: "boolean" },
399
+ },
400
+ additionalProperties: false,
401
+ },
402
+ },
403
+ {
404
+ name: "get_mirror_scale_plan",
405
+ description: "Return a reviewed-mirror batch plan with selected files, byte totals, storage readiness, commands, and blockers. Does not execute mirroring.",
406
+ inputSchema: {
407
+ type: "object",
408
+ properties: {
409
+ limit: { type: "number", minimum: 1, maximum: 100 },
410
+ candidateLimit: { type: "number", minimum: 1, maximum: 200 },
411
+ targetHostedFiles: { type: "number", minimum: 1 },
412
+ maxPlannedBytes: { type: "number", minimum: 1 },
413
+ requestedOnly: { type: "boolean" },
414
+ },
415
+ additionalProperties: false,
416
+ },
417
+ },
418
+ {
419
+ name: "list_stacks",
420
+ description: "List practical Hugging Bay AI stack packs for RAG, local LLMs, agent tools, commercial-safe AI, verified downloads, and research/code discovery.",
421
+ inputSchema: {
422
+ type: "object",
423
+ properties: {},
424
+ additionalProperties: false,
425
+ },
426
+ },
427
+ {
428
+ name: "get_stack",
429
+ description: "Fetch one Hugging Bay stack pack with bounded ranked artifact rows.",
430
+ inputSchema: {
431
+ type: "object",
432
+ properties: { slug: { type: "string", enum: ["rag-starter", "local-llm-starter", "global-model-labs", "agent-toolchain", "commercial-safe-ai", "verified-downloads", "research-code-bench"] } },
433
+ required: ["slug"],
434
+ additionalProperties: false,
435
+ },
436
+ },
437
+ {
438
+ name: "list_answer_packs",
439
+ description: "List citation-ready Hugging Bay answer packs for AI search engines, agents, and common open AI artifact questions.",
440
+ inputSchema: {
441
+ type: "object",
442
+ properties: {},
443
+ additionalProperties: false,
444
+ },
445
+ },
446
+ {
447
+ name: "get_answer_pack",
448
+ description: "Fetch one citation-ready answer pack with short answer, canonical citation targets, extraction APIs, and ranked rows.",
449
+ inputSchema: {
450
+ type: "object",
451
+ properties: {
452
+ slug: {
453
+ type: "string",
454
+ enum: [
455
+ "best-open-models",
456
+ "hosted-downloads",
457
+ "commercial-safe",
458
+ "rag-embeddings",
459
+ "local-llm",
460
+ "global-model-labs",
461
+ "agent-tooling",
462
+ "datasets-evals",
463
+ "beyond-hugging-face",
464
+ "hugging-face-alternative",
465
+ "verified-ai-registry",
466
+ "ai-model-mirrors",
467
+ "agent-friendly-ai-catalog",
468
+ ],
469
+ },
470
+ },
471
+ required: ["slug"],
472
+ additionalProperties: false,
473
+ },
474
+ },
475
+ {
476
+ name: "get_citation_pack",
477
+ description: "Fetch a one-call AI citation pack with safe claims, avoid claims, citation order, proof URLs, and extraction rows.",
478
+ inputSchema: {
479
+ type: "object",
480
+ properties: {
481
+ q: { type: "string" },
482
+ query: { type: "string" },
483
+ slug: { type: "string" },
484
+ },
485
+ additionalProperties: false,
486
+ },
487
+ },
488
+ {
489
+ name: "get_ranking",
490
+ description: "Fetch one Hugging Bay ranking as JSON so agents do not scrape ranking HTML.",
491
+ inputSchema: {
492
+ type: "object",
493
+ properties: {
494
+ slug: {
495
+ type: "string",
496
+ enum: [
497
+ "multi-source-open-ai",
498
+ "new-open-source",
499
+ "top-open-models",
500
+ "global-model-labs",
501
+ "embeddings",
502
+ "rag-embeddings",
503
+ "commercial-use-safe",
504
+ "commercial-datasets",
505
+ "local-llm-tools",
506
+ "small-local-model-files",
507
+ "eastern-open-models",
508
+ "eastern-small-local-models",
509
+ "mcp-agent-tools",
510
+ "paper-code-benchmarks",
511
+ "recently-mirrored",
512
+ "most-requested",
513
+ ],
514
+ },
515
+ },
516
+ required: ["slug"],
517
+ additionalProperties: false,
518
+ },
519
+ },
520
+ {
521
+ name: "search_artifacts",
522
+ description: "Search the bounded public catalog summary API with optional semantic reranking.",
523
+ inputSchema: {
524
+ type: "object",
525
+ properties: {
526
+ q: { type: "string" },
527
+ limit: { type: "number", minimum: 1, maximum: 200 },
528
+ cursor: { type: "string" },
529
+ sort: { type: "string", enum: ["best", "ready", "mirrorable", "trust", "updated", "downloads", "stars", "demand", "mirrors", "name", "size", "license"] },
530
+ type: { type: "string" },
531
+ license: { type: "string" },
532
+ task: { type: "string" },
533
+ framework: { type: "string" },
534
+ format: { type: "string" },
535
+ hosting: { type: "string" },
536
+ reviewStatus: { type: "string", enum: ["first-review", "needs-evidence", "reviewed", "verified-run", "benchmark"] },
537
+ source: { type: "string" },
538
+ commercial: { type: "string", enum: ["1", "true"] },
539
+ semantic: { type: "string", enum: ["1", "true"] },
540
+ explain: { type: "string", enum: ["1", "true"] },
541
+ },
542
+ additionalProperties: false,
543
+ },
544
+ },
545
+ {
546
+ name: "resolve_artifact",
547
+ description: "Resolve an upstream repo URL, owner/name, or artifact id to a Hugging Bay artifact plus hosted download and mirror actions.",
548
+ inputSchema: {
549
+ type: "object",
550
+ properties: {
551
+ repo: { type: "string" },
552
+ url: { type: "string" },
553
+ q: { type: "string" },
554
+ source: { type: "string", enum: ["huggingface", "modelscope", "github", "zenodo", "arxiv", "openml", "dataverse", "datacite", "paperswithcode", "opendatalab", "opencompass"] },
555
+ },
556
+ additionalProperties: false,
557
+ },
558
+ },
559
+ {
560
+ name: "get_artifact",
561
+ description: "Fetch a full artifact record by Hugging Bay artifact id.",
562
+ inputSchema: {
563
+ type: "object",
564
+ properties: { id: { type: "string" } },
565
+ required: ["id"],
566
+ additionalProperties: false,
567
+ },
568
+ },
569
+ {
570
+ name: "get_artifact_metadata",
571
+ description: "Fetch agent-oriented artifact metadata with provenance, hosting, and safe next steps.",
572
+ inputSchema: {
573
+ type: "object",
574
+ properties: { id: { type: "string" } },
575
+ required: ["id"],
576
+ additionalProperties: false,
577
+ },
578
+ },
579
+ {
580
+ name: "get_artifact_bundle",
581
+ description: "Fetch one artifact's metadata, card, trust bundle, hosted files, and mirror readiness in one response.",
582
+ inputSchema: {
583
+ type: "object",
584
+ properties: { id: { type: "string" } },
585
+ required: ["id"],
586
+ additionalProperties: false,
587
+ },
588
+ },
589
+ {
590
+ name: "get_release_bundle",
591
+ description: "Fetch a launch-ready release bundle for labs and agents: publisher claim, same-as-upstream evidence, trust bundle, hosted files, local-run commands, and reviewed fallback readiness.",
592
+ inputSchema: {
593
+ type: "object",
594
+ properties: { id: { type: "string" } },
595
+ required: ["id"],
596
+ additionalProperties: false,
597
+ },
598
+ },
599
+ {
600
+ name: "get_release_readiness",
601
+ description: "Fetch a compact release readiness score/checklist for a lab release: namespace, provenance, license, scans, signed manifests, hosted files, runtime guidance, community proof, and reviewed fallback status.",
602
+ inputSchema: {
603
+ type: "object",
604
+ properties: { id: { type: "string" } },
605
+ required: ["id"],
606
+ additionalProperties: false,
607
+ },
608
+ },
609
+ {
610
+ name: "get_artifact_distribution",
611
+ description: "Fetch one artifact's hosted download state, upstream source, and reviewed peer-assisted fallback metadata.",
612
+ inputSchema: {
613
+ type: "object",
614
+ properties: { id: { type: "string" } },
615
+ required: ["id"],
616
+ additionalProperties: false,
617
+ },
618
+ },
619
+ {
620
+ name: "get_peer_fallbacks",
621
+ description: "Fetch one artifact's reviewed torrent/magnet fallback bundle, scoped to hosted-file hashes and reviewer evidence.",
622
+ inputSchema: {
623
+ type: "object",
624
+ properties: { id: { type: "string" } },
625
+ required: ["id"],
626
+ additionalProperties: false,
627
+ },
628
+ },
629
+ {
630
+ name: "list_admin_peer_fallbacks",
631
+ description: "List pending peer fallback requests for admin review. Requires HUGGING_BAY_TOKEN with admin role.",
632
+ inputSchema: {
633
+ type: "object",
634
+ properties: {
635
+ status: { type: "string", enum: ["needs-review", "verified", "rejected", "blocked", "all"] },
636
+ limit: { type: "number", minimum: 1, maximum: 200 },
637
+ },
638
+ additionalProperties: false,
639
+ },
640
+ },
641
+ {
642
+ name: "get_artifact_insights",
643
+ description: "Fetch decision-ready artifact insights with best-fit labels, trust gaps, runner commands, benchmark evidence, hardware estimate, hosted files, and mirror readiness.",
644
+ inputSchema: {
645
+ type: "object",
646
+ properties: { id: { type: "string" } },
647
+ required: ["id"],
648
+ additionalProperties: false,
649
+ },
650
+ },
651
+ {
652
+ name: "get_local_kit",
653
+ description: "Fetch copyable local-use commands, required files, warnings, and next actions for one artifact, optionally filtered by runtime tool.",
654
+ inputSchema: {
655
+ type: "object",
656
+ properties: {
657
+ id: { type: "string" },
658
+ tool: { type: "string", enum: localToolEnum },
659
+ },
660
+ required: ["id"],
661
+ additionalProperties: false,
662
+ },
663
+ },
664
+ {
665
+ name: "get_download_plan",
666
+ description: "Fetch hosted-only download instructions, signed manifest URL, SHA-256 hashes, and CLI commands for one artifact.",
667
+ inputSchema: {
668
+ type: "object",
669
+ properties: {
670
+ id: { type: "string" },
671
+ tool: { type: "string", enum: localToolEnum },
672
+ },
673
+ required: ["id"],
674
+ additionalProperties: false,
675
+ },
676
+ },
677
+ {
678
+ name: "get_artifact_card",
679
+ description: "Fetch a repo-grade artifact card as JSON or Markdown.",
680
+ inputSchema: {
681
+ type: "object",
682
+ properties: {
683
+ id: { type: "string" },
684
+ markdown: { type: "boolean" },
685
+ },
686
+ required: ["id"],
687
+ additionalProperties: false,
688
+ },
689
+ },
690
+ {
691
+ name: "get_artifact_reviews",
692
+ description: "Fetch public community ratings, reviews, and verified-run attestations for an artifact.",
693
+ inputSchema: {
694
+ type: "object",
695
+ properties: {
696
+ id: { type: "string" },
697
+ limit: { type: "number", minimum: 1, maximum: 200 },
698
+ },
699
+ required: ["id"],
700
+ additionalProperties: false,
701
+ },
702
+ },
703
+ {
704
+ name: "get_evidence_rollups",
705
+ description: "Fetch global public evidence rollups by benchmark, tool, hardware, and artifact type.",
706
+ inputSchema: {
707
+ type: "object",
708
+ properties: {
709
+ limit: { type: "number", minimum: 1, maximum: 100 },
710
+ },
711
+ additionalProperties: false,
712
+ },
713
+ },
714
+ {
715
+ name: "get_review_queue",
716
+ description: "Fetch prioritized artifacts that need community reviews, verified-run evidence, or benchmark reports.",
717
+ inputSchema: {
718
+ type: "object",
719
+ properties: {
720
+ mode: { type: "string", enum: ["first-review", "needs-evidence", "verified-run", "benchmark"] },
721
+ hosting: { type: "string", enum: ["actionable", "hosted", "reviewable", "all"] },
722
+ maxReviews: { type: "number", minimum: 0, maximum: 25 },
723
+ limit: { type: "number", minimum: 1, maximum: 100 },
724
+ },
725
+ additionalProperties: false,
726
+ },
727
+ },
728
+ {
729
+ name: "submit_artifact_review",
730
+ description: "Submit a bounded public review or verified-run attestation after using an artifact.",
731
+ inputSchema: {
732
+ type: "object",
733
+ properties: {
734
+ id: { type: "string" },
735
+ rating: { type: "number", minimum: 1, maximum: 5 },
736
+ title: { type: "string" },
737
+ body: { type: "string" },
738
+ reviewer: { type: "string" },
739
+ tool: { type: "string" },
740
+ version: { type: "string" },
741
+ verifiedRun: { type: "boolean" },
742
+ verifiedFiles: { type: "array", items: { type: "string" } },
743
+ evidence: { type: "object", additionalProperties: true },
744
+ },
745
+ required: ["id", "rating", "body"],
746
+ additionalProperties: true,
747
+ },
748
+ },
749
+ {
750
+ name: "mark_review_helpful",
751
+ description: "Mark a public artifact review as helpful with duplicate protection.",
752
+ inputSchema: {
753
+ type: "object",
754
+ properties: {
755
+ id: { type: "string" },
756
+ reviewId: { type: "string" },
757
+ },
758
+ required: ["id", "reviewId"],
759
+ additionalProperties: false,
760
+ },
761
+ },
762
+ {
763
+ name: "report_review",
764
+ description: "Report a public artifact review for moderation.",
765
+ inputSchema: {
766
+ type: "object",
767
+ properties: {
768
+ id: { type: "string" },
769
+ reviewId: { type: "string" },
770
+ reason: { type: "string" },
771
+ summary: { type: "string" },
772
+ evidence: { type: "string" },
773
+ },
774
+ required: ["id", "reviewId"],
775
+ additionalProperties: true,
776
+ },
777
+ },
778
+ {
779
+ name: "get_community_signals",
780
+ description: "Fetch aggregate public community trust signals, recent reviews, and top helpful reviews.",
781
+ inputSchema: {
782
+ type: "object",
783
+ properties: {
784
+ limit: { type: "number", minimum: 1, maximum: 100 },
785
+ },
786
+ additionalProperties: false,
787
+ },
788
+ },
789
+ {
790
+ name: "compare_artifacts",
791
+ description: "Compare up to six Hugging Bay artifact ids or owner/name repos side by side.",
792
+ inputSchema: {
793
+ type: "object",
794
+ properties: {
795
+ ids: {
796
+ type: "array",
797
+ items: { type: "string" },
798
+ minItems: 1,
799
+ maxItems: 6,
800
+ },
801
+ },
802
+ required: ["ids"],
803
+ additionalProperties: false,
804
+ },
805
+ },
806
+ {
807
+ name: "preview_file",
808
+ description: "Preview one Hugging Bay-hosted text-like file with bounded text and optional row samples.",
809
+ inputSchema: {
810
+ type: "object",
811
+ properties: {
812
+ id: { type: "string" },
813
+ path: { type: "string" },
814
+ },
815
+ required: ["id", "path"],
816
+ additionalProperties: false,
817
+ },
818
+ },
819
+ {
820
+ name: "list_files",
821
+ description: "List an artifact's files with bounded pagination.",
822
+ inputSchema: {
823
+ type: "object",
824
+ properties: {
825
+ id: { type: "string" },
826
+ q: { type: "string" },
827
+ tool: { type: "string", enum: localToolEnum },
828
+ limit: { type: "number", minimum: 1, maximum: 500 },
829
+ cursor: { type: "string" },
830
+ },
831
+ required: ["id"],
832
+ additionalProperties: false,
833
+ },
834
+ },
835
+ {
836
+ name: "list_downloadable_files",
837
+ description: "List files actually hosted by Hugging Bay. External metadata rows are excluded.",
838
+ inputSchema: {
839
+ type: "object",
840
+ properties: {
841
+ q: { type: "string" },
842
+ pack: { type: "string" },
843
+ artifactId: { type: "string" },
844
+ path: { type: "string" },
845
+ sourceKind: { type: "string", enum: ["mirrored-hf", "uploaded", "seeded-upload"] },
846
+ tool: { type: "string", enum: localToolEnum },
847
+ limit: { type: "number", minimum: 1, maximum: 1000 },
848
+ },
849
+ additionalProperties: false,
850
+ },
851
+ },
852
+ {
853
+ name: "list_mirror_packs",
854
+ description: "List curated Hugging Bay packs such as Downloadable Now, RAG embeddings, and commercial-use safe artifacts.",
855
+ inputSchema: {
856
+ type: "object",
857
+ properties: {},
858
+ additionalProperties: false,
859
+ },
860
+ },
861
+ {
862
+ name: "get_mirror_pack",
863
+ description: "Fetch one curated pack with artifact rows by slug.",
864
+ inputSchema: {
865
+ type: "object",
866
+ properties: { slug: { type: "string" } },
867
+ required: ["slug"],
868
+ additionalProperties: false,
869
+ },
870
+ },
871
+ {
872
+ name: "list_mirror_demand",
873
+ description: "List requested and high-download mirror candidates for prioritizing what Hugging Bay should host next.",
874
+ inputSchema: {
875
+ type: "object",
876
+ properties: {
877
+ limit: { type: "number", minimum: 1, maximum: 200 },
878
+ requestedOnly: { type: "boolean" },
879
+ },
880
+ additionalProperties: false,
881
+ },
882
+ },
883
+ {
884
+ name: "list_mirrors",
885
+ description: "List registered Hugging Bay mirror nodes and health state.",
886
+ inputSchema: {
887
+ type: "object",
888
+ properties: {},
889
+ additionalProperties: false,
890
+ },
891
+ },
892
+ {
893
+ name: "register_mirror",
894
+ description: "Register a reviewed public mirror node. Requires HUGGING_BAY_TOKEN with admin role.",
895
+ inputSchema: {
896
+ type: "object",
897
+ required: ["name", "region", "endpoint"],
898
+ properties: {
899
+ name: { type: "string" },
900
+ region: { type: "string" },
901
+ endpoint: { type: "string" },
902
+ },
903
+ additionalProperties: false,
904
+ },
905
+ },
906
+ {
907
+ name: "update_mirror",
908
+ description: "Update a mirror node health state. Requires HUGGING_BAY_TOKEN with admin role.",
909
+ inputSchema: {
910
+ type: "object",
911
+ required: ["id"],
912
+ properties: {
913
+ id: { type: "string" },
914
+ health: { type: "string", enum: ["healthy", "stale", "degraded", "quarantined"] },
915
+ },
916
+ additionalProperties: false,
917
+ },
918
+ },
919
+ {
920
+ name: "list_topics",
921
+ description: "List generated catalog topics by task, type, license, framework, and source.",
922
+ inputSchema: {
923
+ type: "object",
924
+ properties: {},
925
+ additionalProperties: false,
926
+ },
927
+ },
928
+ {
929
+ name: "get_topic",
930
+ description: "Fetch one catalog topic and its ranked artifact rows.",
931
+ inputSchema: {
932
+ type: "object",
933
+ properties: { slug: { type: "string" } },
934
+ required: ["slug"],
935
+ additionalProperties: false,
936
+ },
937
+ },
938
+ {
939
+ name: "request_mirror",
940
+ description: "Record mirror demand for an external Hugging Face artifact by artifact id.",
941
+ inputSchema: {
942
+ type: "object",
943
+ properties: {
944
+ id: { type: "string" },
945
+ sourceRoute: { type: "string" },
946
+ query: { type: "string" },
947
+ topic: { type: "string" },
948
+ ranking: { type: "string" },
949
+ useCase: { type: "string" },
950
+ targetTool: { type: "string" },
951
+ desiredFiles: { type: "array", items: { type: "string" } },
952
+ contact: { type: "string" },
953
+ },
954
+ required: ["id"],
955
+ additionalProperties: false,
956
+ },
957
+ },
958
+ {
959
+ name: "get_trust_bundle",
960
+ description: "Fetch artifact trust evidence: license decision, scan status, hosting state, manifest key URL, and file evidence.",
961
+ inputSchema: {
962
+ type: "object",
963
+ properties: { id: { type: "string" } },
964
+ required: ["id"],
965
+ additionalProperties: false,
966
+ },
967
+ },
968
+ {
969
+ name: "get_manifest_signing_key",
970
+ description: "Fetch public manifest signing key metadata used to verify signed manifests.",
971
+ inputSchema: {
972
+ type: "object",
973
+ properties: {},
974
+ additionalProperties: false,
975
+ },
976
+ },
977
+ {
978
+ name: "get_indexing_status",
979
+ description: "Fetch sitemap, URL batch, and crawl-readiness status for search engines and agents.",
980
+ inputSchema: {
981
+ type: "object",
982
+ properties: {},
983
+ additionalProperties: false,
984
+ },
985
+ },
986
+ {
987
+ name: "list_indexing_urls",
988
+ description: "Fetch bounded canonical URL batches by kind for indexing/submission workflows.",
989
+ inputSchema: {
990
+ type: "object",
991
+ properties: {
992
+ kind: { type: "string", enum: ["static", "publisher", "ranking", "stack", "intent", "answer", "source", "topic", "artifact", "artifact-section", "artifact-evidence", "downloadable", "agent-doc"] },
993
+ limit: { type: "number", minimum: 1, maximum: 1000 },
994
+ cursor: { type: "string" },
995
+ q: { type: "string" },
996
+ source: { type: "string" },
997
+ type: { type: "string" },
998
+ license: { type: "string" },
999
+ format: { type: "string" },
1000
+ hosting: { type: "string" },
1001
+ reviewStatus: { type: "string", enum: ["first-review", "needs-evidence", "reviewed", "verified-run", "benchmark"] },
1002
+ tool: { type: "string", enum: localToolEnum },
1003
+ worksWith: { type: "string", enum: localToolEnum },
1004
+ commercial: { type: "boolean" },
1005
+ verified: { type: "boolean" },
1006
+ sort: { type: "string", enum: ["best", "ready", "mirrorable", "trust", "downloads", "stars", "mirrors", "demand", "name", "size", "license", "updated"] },
1007
+ },
1008
+ additionalProperties: false,
1009
+ },
1010
+ },
1011
+ {
1012
+ name: "get_import_status",
1013
+ description: "Fetch admin import/mirror job status. Requires HUGGING_BAY_TOKEN with admin role.",
1014
+ inputSchema: {
1015
+ type: "object",
1016
+ properties: {},
1017
+ additionalProperties: false,
1018
+ },
1019
+ },
1020
+ {
1021
+ name: "list_import_runs",
1022
+ description: "List compact import runs for agent operators. Requires HUGGING_BAY_TOKEN with admin role.",
1023
+ inputSchema: {
1024
+ type: "object",
1025
+ properties: {
1026
+ limit: { type: "number", minimum: 1, maximum: 200 },
1027
+ cursor: { type: "string" },
1028
+ },
1029
+ additionalProperties: false,
1030
+ },
1031
+ },
1032
+ {
1033
+ name: "get_import_run",
1034
+ description: "Fetch one import run with its cursors. Requires HUGGING_BAY_TOKEN with admin role.",
1035
+ inputSchema: {
1036
+ type: "object",
1037
+ properties: { runId: { type: "string" } },
1038
+ required: ["runId"],
1039
+ additionalProperties: false,
1040
+ },
1041
+ },
1042
+ {
1043
+ name: "extend_hf_import",
1044
+ description: "Plan a metadata-only continuation from a completed Hugging Face import run. Requires HUGGING_BAY_TOKEN with admin role.",
1045
+ inputSchema: {
1046
+ type: "object",
1047
+ properties: {
1048
+ previousRunId: { type: "string" },
1049
+ targetRecords: { type: "number", minimum: 1, maximum: 100000 },
1050
+ pageSize: { type: "number", minimum: 1, maximum: 500 },
1051
+ preset: { type: "string" },
1052
+ },
1053
+ required: ["previousRunId"],
1054
+ additionalProperties: false,
1055
+ },
1056
+ },
1057
+ {
1058
+ name: "run_hf_worker_batch",
1059
+ description: "Run a small metadata-only HF worker batch, optionally scoped to a run id. Requires HUGGING_BAY_TOKEN with admin role and enabled worker.",
1060
+ inputSchema: {
1061
+ type: "object",
1062
+ properties: {
1063
+ runId: { type: "string" },
1064
+ maxPages: { type: "number", minimum: 1, maximum: 5 },
1065
+ },
1066
+ additionalProperties: false,
1067
+ },
1068
+ },
1069
+ {
1070
+ name: "run_source_import",
1071
+ description: "Run metadata-only source import from ModelScope, GitHub, arXiv, OpenML, Zenodo, Dataverse, DataCite, Papers with Code, OpenDataLab, and/or OpenCompass. Requires HUGGING_BAY_TOKEN with admin role.",
1072
+ inputSchema: {
1073
+ type: "object",
1074
+ properties: {
1075
+ source: { type: "string", enum: ["all", "public-growth", "east-west-data", "github", "arxiv", "openml", "zenodo", "dataverse", "datacite", "paperswithcode", "opendatalab", "opencompass", "modelscope"] },
1076
+ pack: { type: "string", enum: ["public-growth", "east-west-data"] },
1077
+ limit: { type: "number", minimum: 1, maximum: 10000 },
1078
+ github: { type: "number", minimum: 1, maximum: 5000 },
1079
+ arxiv: { type: "number", minimum: 1, maximum: 5000 },
1080
+ openml: { type: "number", minimum: 1, maximum: 5000 },
1081
+ zenodo: { type: "number", minimum: 1, maximum: 5000 },
1082
+ dataverse: { type: "number", minimum: 1, maximum: 5000 },
1083
+ datacite: { type: "number", minimum: 1, maximum: 5000 },
1084
+ paperswithcode: { type: "number", minimum: 1, maximum: 5000 },
1085
+ opendatalab: { type: "number", minimum: 1, maximum: 5000 },
1086
+ opencompass: { type: "number", minimum: 1, maximum: 5000 },
1087
+ modelscope: { type: "number", minimum: 1, maximum: 5000 },
1088
+ query: { type: "string" },
1089
+ strict: { type: "boolean" },
1090
+ dryRun: { type: "boolean" },
1091
+ },
1092
+ additionalProperties: false,
1093
+ },
1094
+ },
1095
+ {
1096
+ name: "plan_source_import",
1097
+ description: "Plan a resumable metadata-only source import using provider cursors. Requires HUGGING_BAY_TOKEN with admin role.",
1098
+ inputSchema: {
1099
+ type: "object",
1100
+ properties: {
1101
+ source: { type: "string", enum: ["all", "public-growth", "east-west-data", "github", "arxiv", "openml", "zenodo", "dataverse", "datacite", "paperswithcode", "opendatalab", "opencompass", "modelscope"] },
1102
+ pack: { type: "string", enum: ["public-growth", "east-west-data"] },
1103
+ targetRecords: { type: "number", minimum: 1, maximum: 10000 },
1104
+ pageSize: { type: "number", minimum: 1, maximum: 500 },
1105
+ github: { type: "number", minimum: 1, maximum: 5000 },
1106
+ arxiv: { type: "number", minimum: 1, maximum: 5000 },
1107
+ openml: { type: "number", minimum: 1, maximum: 5000 },
1108
+ zenodo: { type: "number", minimum: 1, maximum: 5000 },
1109
+ dataverse: { type: "number", minimum: 1, maximum: 5000 },
1110
+ datacite: { type: "number", minimum: 1, maximum: 5000 },
1111
+ paperswithcode: { type: "number", minimum: 1, maximum: 5000 },
1112
+ opendatalab: { type: "number", minimum: 1, maximum: 5000 },
1113
+ opencompass: { type: "number", minimum: 1, maximum: 5000 },
1114
+ modelscope: { type: "number", minimum: 1, maximum: 5000 },
1115
+ query: { type: "string" },
1116
+ },
1117
+ additionalProperties: false,
1118
+ },
1119
+ },
1120
+ {
1121
+ name: "run_source_worker_batch",
1122
+ description: "Run a scoped metadata-only source worker batch. Requires HUGGING_BAY_TOKEN with admin role.",
1123
+ inputSchema: {
1124
+ type: "object",
1125
+ properties: {
1126
+ runId: { type: "string" },
1127
+ maxPages: { type: "number", minimum: 1, maximum: 10 },
1128
+ maxErrors: { type: "number", minimum: 1, maximum: 25 },
1129
+ },
1130
+ additionalProperties: false,
1131
+ },
1132
+ },
1133
+ {
1134
+ name: "get_traffic_summary",
1135
+ description: "Fetch first-party traffic, hosted download, and mirror-demand telemetry. Requires HUGGING_BAY_TOKEN with admin role.",
1136
+ inputSchema: {
1137
+ type: "object",
1138
+ properties: {},
1139
+ additionalProperties: false,
1140
+ },
1141
+ },
1142
+ {
1143
+ name: "expand_hf_detail_metadata",
1144
+ description: "Expand selected Hugging Face metadata rows with file-list details. Requires HUGGING_BAY_TOKEN with admin role. Production web services may disable this unless a monitored maintenance env flag is enabled; use direct workers for bulk expansion.",
1145
+ inputSchema: {
1146
+ type: "object",
1147
+ properties: {
1148
+ limit: { type: "number", minimum: 1, maximum: 200 },
1149
+ q: { type: "string" },
1150
+ requestedOnly: { type: "boolean" },
1151
+ force: { type: "boolean" },
1152
+ missingSizes: { type: "boolean" },
1153
+ preferRuntime: { type: "boolean" },
1154
+ dryRun: { type: "boolean" },
1155
+ maxRuntimeMs: { type: "number", minimum: 1000, maximum: 120000 },
1156
+ timeoutMs: { type: "number", minimum: 1000, maximum: 30000 },
1157
+ retries: { type: "number", minimum: 0, maximum: 2 },
1158
+ backoffMs: { type: "number", minimum: 0, maximum: 5000 },
1159
+ },
1160
+ additionalProperties: false,
1161
+ },
1162
+ },
1163
+ {
1164
+ name: "create_upload_session",
1165
+ description: "Create signed large-upload URLs for a publisher release. Requires HUGGING_BAY_TOKEN with publisher/admin role.",
1166
+ inputSchema: {
1167
+ type: "object",
1168
+ required: ["owner", "name", "files"],
1169
+ properties: {
1170
+ owner: { type: "string" },
1171
+ name: { type: "string" },
1172
+ files: {
1173
+ type: "array",
1174
+ items: {
1175
+ type: "object",
1176
+ required: ["path", "sizeBytes", "sha256"],
1177
+ properties: {
1178
+ path: { type: "string" },
1179
+ sizeBytes: { type: "number" },
1180
+ sha256: { type: "string" },
1181
+ contentType: { type: "string" },
1182
+ },
1183
+ additionalProperties: false,
1184
+ },
1185
+ },
1186
+ },
1187
+ additionalProperties: false,
1188
+ },
1189
+ },
1190
+ {
1191
+ name: "get_upload_session",
1192
+ description: "Fetch upload-session status and optional live object-storage progress. Requires HUGGING_BAY_TOKEN with session owner/admin role.",
1193
+ inputSchema: {
1194
+ type: "object",
1195
+ required: ["id"],
1196
+ properties: { id: { type: "string" }, refresh: { type: "boolean" } },
1197
+ additionalProperties: false,
1198
+ },
1199
+ },
1200
+ {
1201
+ name: "resume_upload_session",
1202
+ description: "Refresh signed PUT URLs for incomplete upload-session files. Requires HUGGING_BAY_TOKEN with session owner/admin role.",
1203
+ inputSchema: {
1204
+ type: "object",
1205
+ required: ["id"],
1206
+ properties: { id: { type: "string" } },
1207
+ additionalProperties: false,
1208
+ },
1209
+ },
1210
+ {
1211
+ name: "complete_upload_session",
1212
+ description: "Verify uploaded objects and complete a large-upload session. Requires HUGGING_BAY_TOKEN with session owner/admin role.",
1213
+ inputSchema: {
1214
+ type: "object",
1215
+ required: ["id"],
1216
+ properties: { id: { type: "string" } },
1217
+ additionalProperties: false,
1218
+ },
1219
+ },
1220
+ {
1221
+ name: "cancel_upload_session",
1222
+ description: "Cancel a pending upload session. Requires HUGGING_BAY_TOKEN with session owner/admin role.",
1223
+ inputSchema: {
1224
+ type: "object",
1225
+ required: ["id"],
1226
+ properties: { id: { type: "string" } },
1227
+ additionalProperties: false,
1228
+ },
1229
+ },
1230
+ {
1231
+ name: "get_admin_mirror_queue",
1232
+ description: "List admin mirror queue rows with exact useful runtime/support file candidates. Requires HUGGING_BAY_TOKEN with admin role.",
1233
+ inputSchema: {
1234
+ type: "object",
1235
+ properties: {
1236
+ limit: { type: "number", minimum: 1, maximum: 200 },
1237
+ requestedOnly: { type: "boolean" },
1238
+ },
1239
+ additionalProperties: false,
1240
+ },
1241
+ },
1242
+ {
1243
+ name: "get_user_request_automation",
1244
+ description: "List recent user mirror/source requests plus large-mirror direct and reviewed-weight candidates. Requires HUGGING_BAY_TOKEN with admin role.",
1245
+ inputSchema: {
1246
+ type: "object",
1247
+ properties: {},
1248
+ additionalProperties: false,
1249
+ },
1250
+ },
1251
+ {
1252
+ name: "run_mirror_queue_batch",
1253
+ description: "Run a bounded reviewed mirror queue batch using exact selected useful files. Requires HUGGING_BAY_TOKEN with admin role.",
1254
+ inputSchema: {
1255
+ type: "object",
1256
+ properties: {
1257
+ limit: { type: "number", minimum: 1, maximum: 25 },
1258
+ dryRun: { type: "boolean" },
1259
+ targetHostedFiles: { type: "number", minimum: 1 },
1260
+ maxPlannedBytes: { type: "number", minimum: 1 },
1261
+ },
1262
+ additionalProperties: false,
1263
+ },
1264
+ },
1265
+ {
1266
+ name: "create_mirror_batch",
1267
+ description: "Create a durable reviewed mirror batch from current readiness rows. Requires HUGGING_BAY_TOKEN with admin role.",
1268
+ inputSchema: {
1269
+ type: "object",
1270
+ properties: {
1271
+ limit: { type: "number", minimum: 1, maximum: 100 },
1272
+ candidateLimit: { type: "number", minimum: 1, maximum: 200 },
1273
+ requestedOnly: { type: "boolean" },
1274
+ includeSupportOnly: { type: "boolean" },
1275
+ includeReviewedRiskyWeights: { type: "boolean" },
1276
+ targetHostedFiles: { type: "number", minimum: 1 },
1277
+ maxPlannedBytes: { type: "number", minimum: 1 },
1278
+ note: { type: "string" },
1279
+ },
1280
+ additionalProperties: false,
1281
+ },
1282
+ },
1283
+ {
1284
+ name: "list_mirror_batches",
1285
+ description: "List durable reviewed mirror batches. Requires HUGGING_BAY_TOKEN with admin role.",
1286
+ inputSchema: {
1287
+ type: "object",
1288
+ properties: {
1289
+ limit: { type: "number", minimum: 1, maximum: 100 },
1290
+ status: { type: "string" },
1291
+ },
1292
+ additionalProperties: false,
1293
+ },
1294
+ },
1295
+ {
1296
+ name: "get_mirror_batch",
1297
+ description: "Fetch one durable mirror batch with selected files and review/run state. Requires HUGGING_BAY_TOKEN with admin role.",
1298
+ inputSchema: {
1299
+ type: "object",
1300
+ required: ["id"],
1301
+ properties: { id: { type: "string" } },
1302
+ additionalProperties: false,
1303
+ },
1304
+ },
1305
+ {
1306
+ name: "approve_mirror_batch",
1307
+ description: "Revalidate selected paths and approve a durable mirror batch. Requires HUGGING_BAY_TOKEN with admin role.",
1308
+ inputSchema: {
1309
+ type: "object",
1310
+ required: ["id"],
1311
+ properties: {
1312
+ id: { type: "string" },
1313
+ note: { type: "string" },
1314
+ riskOverride: {
1315
+ type: "object",
1316
+ required: ["note", "evidence"],
1317
+ properties: {
1318
+ note: { type: "string", minLength: 20 },
1319
+ evidence: { type: "array", minItems: 1, items: { oneOf: [{ type: "string" }, { type: "object", additionalProperties: true }] } },
1320
+ paths: { type: "array", items: { type: "string" } },
1321
+ },
1322
+ additionalProperties: true,
1323
+ },
1324
+ },
1325
+ additionalProperties: true,
1326
+ },
1327
+ },
1328
+ {
1329
+ name: "run_mirror_batch",
1330
+ description: "Dry-run or execute an approved durable mirror batch. Requires HUGGING_BAY_TOKEN with admin role.",
1331
+ inputSchema: {
1332
+ type: "object",
1333
+ required: ["id"],
1334
+ properties: {
1335
+ id: { type: "string" },
1336
+ dryRun: { type: "boolean" },
1337
+ stopOnFailure: { type: "boolean" },
1338
+ },
1339
+ additionalProperties: false,
1340
+ },
1341
+ },
1342
+ {
1343
+ name: "recover_mirror_batch",
1344
+ description: "Recover failed rows in a durable mirror batch by retrying, reopening for review, or marking reviewed failures as skipped. Requires HUGGING_BAY_TOKEN with admin role.",
1345
+ inputSchema: {
1346
+ type: "object",
1347
+ required: ["id"],
1348
+ properties: {
1349
+ id: { type: "string" },
1350
+ action: { type: "string", enum: ["retry_failed", "reopen_failed", "skip_failed"] },
1351
+ note: { type: "string" },
1352
+ },
1353
+ additionalProperties: false,
1354
+ },
1355
+ },
1356
+ {
1357
+ name: "check_storage",
1358
+ description: "Run an admin storage round-trip diagnostic. Writes, heads, reads, range-reads, and deletes a disposable object. Requires HUGGING_BAY_TOKEN with admin role.",
1359
+ inputSchema: {
1360
+ type: "object",
1361
+ properties: {},
1362
+ additionalProperties: false,
1363
+ },
1364
+ },
1365
+ ];
1366
+
1367
+ function apiUrl(path) {
1368
+ return new URL(path, apiBase).toString();
1369
+ }
1370
+
1371
+ function paramsFrom(input, allowed) {
1372
+ const params = new URLSearchParams();
1373
+ for (const key of allowed) {
1374
+ if (input[key] !== undefined && input[key] !== null && String(input[key]).trim() !== "") {
1375
+ params.set(key, String(input[key]));
1376
+ }
1377
+ }
1378
+ return params;
1379
+ }
1380
+
1381
+ async function apiRequest(path, options = {}) {
1382
+ const headers = new Headers(options.headers || {});
1383
+ if (options.body) headers.set("Content-Type", "application/json");
1384
+ if (token) headers.set("Authorization", `Bearer ${token}`);
1385
+ const response = await fetch(apiUrl(path), { ...options, headers });
1386
+ const text = await response.text();
1387
+ let body;
1388
+ try {
1389
+ body = text ? JSON.parse(text) : null;
1390
+ } catch {
1391
+ body = text;
1392
+ }
1393
+ if (!response.ok) {
1394
+ const message = typeof body === "object" && body?.error ? body.error : `${response.status} ${response.statusText}`;
1395
+ const error = new Error(message);
1396
+ error.payload = body;
1397
+ throw error;
1398
+ }
1399
+ return body;
1400
+ }
1401
+
1402
+ async function apiText(path, options = {}) {
1403
+ const headers = new Headers(options.headers || {});
1404
+ if (token) headers.set("Authorization", `Bearer ${token}`);
1405
+ const response = await fetch(apiUrl(path), { ...options, headers });
1406
+ const text = await response.text();
1407
+ if (!response.ok) {
1408
+ const error = new Error(`${response.status} ${response.statusText}`);
1409
+ error.payload = text;
1410
+ throw error;
1411
+ }
1412
+ return text;
1413
+ }
1414
+
1415
+ async function callTool(name, input = {}) {
1416
+ if (name === "get_health") return apiRequest("/api/health");
1417
+ if (name === "get_catalog_coverage") return apiRequest("/api/catalog/coverage");
1418
+ if (name === "get_open_source_radar") return apiRequest("/api/radar");
1419
+ if (name === "get_trending") {
1420
+ const params = paramsFrom(input, ["window", "limit"]);
1421
+ if (!params.has("window")) params.set("window", "7d");
1422
+ if (!params.has("limit")) params.set("limit", "25");
1423
+ return apiRequest(`/api/trending?${params}`);
1424
+ }
1425
+ if (name === "get_traffic") return apiRequest("/api/traffic");
1426
+ if (name === "get_agent_discovery") return apiRequest("/api/agent-discovery");
1427
+ if (name === "get_ai_bot_allowlist") return apiRequest("/.well-known/ai-bot-allowlist.json");
1428
+ if (name === "get_ai_search_guidance") return apiRequest("/api/ai-search");
1429
+ if (name === "get_ai_mention_monitor") return apiRequest("/api/ai-mention-monitor");
1430
+ if (name === "get_ai_mention_results") {
1431
+ const params = paramsFrom(input, ["provider", "promptId", "limit"]);
1432
+ if (!params.has("limit")) params.set("limit", "100");
1433
+ return apiRequest(`/api/ai-mention-results?${params}`);
1434
+ }
1435
+ if (name === "get_source_coverage") return apiRequest(`/api/sources/${encodeURIComponent(input.id)}/coverage`);
1436
+ if (name === "get_recommendations") return apiRequest("/api/recommendations");
1437
+ if (name === "recommend_artifacts") {
1438
+ const params = paramsFrom(input, ["useCase", "q", "tool", "commercial", "hosted", "limit"]);
1439
+ if (!params.has("limit")) params.set("limit", "12");
1440
+ return apiRequest(`/api/recommender?${params}`);
1441
+ }
1442
+ if (name === "get_agent_tasks") return apiRequest("/api/agents/tasks");
1443
+ if (name === "get_publisher_workflow") return apiRequest("/api/agents/publisher-workflow");
1444
+ if (name === "get_publisher_release_template") {
1445
+ const params = paramsFrom(input, ["kind"]);
1446
+ return apiRequest(`/api/publishers/release-template${params.toString() ? `?${params}` : ""}`);
1447
+ }
1448
+ if (name === "list_publishers") {
1449
+ const params = paramsFrom(input, ["q", "limit"]);
1450
+ if (!params.has("limit")) params.set("limit", "50");
1451
+ return apiRequest(`/api/publishers?${params}`);
1452
+ }
1453
+ if (name === "get_publisher_profile") {
1454
+ const params = paramsFrom(input, ["limit"]);
1455
+ if (!params.has("limit")) params.set("limit", "50");
1456
+ return apiRequest(`/api/publishers/${encodeURIComponent(input.namespace)}?${params}`);
1457
+ }
1458
+ if (name === "get_publisher_dashboard") return apiRequest("/api/publisher/dashboard");
1459
+ if (name === "list_saved_searches") {
1460
+ const params = paramsFrom(input, ["alerts", "alertLimit", "previewLimit"]);
1461
+ return apiRequest(`/api/saved-searches${params.toString() ? `?${params}` : ""}`);
1462
+ }
1463
+ if (name === "list_saved_search_alerts") {
1464
+ const params = paramsFrom(input, ["limit", "previewLimit"]);
1465
+ return apiRequest(`/api/saved-searches/alerts${params.toString() ? `?${params}` : ""}`);
1466
+ }
1467
+ if (name === "get_saved_search_digest") {
1468
+ const searchId = input.searchId || input.id;
1469
+ const params = paramsFrom(input, ["limit"]);
1470
+ return apiRequest(`/api/saved-searches/${encodeURIComponent(searchId)}/digest${params.toString() ? `?${params}` : ""}`);
1471
+ }
1472
+ if (name === "save_saved_search") {
1473
+ const searchId = input.searchId || input.id;
1474
+ return apiRequest(searchId ? `/api/saved-searches/${encodeURIComponent(searchId)}` : "/api/saved-searches", {
1475
+ method: searchId ? "PUT" : "POST",
1476
+ body: JSON.stringify(input),
1477
+ });
1478
+ }
1479
+ if (name === "delete_saved_search") {
1480
+ return apiRequest(`/api/saved-searches/${encodeURIComponent(input.searchId || input.id)}`, {
1481
+ method: "DELETE",
1482
+ });
1483
+ }
1484
+ if (name === "apply_publisher_application") {
1485
+ return apiRequest("/api/publisher-applications", {
1486
+ method: "POST",
1487
+ body: JSON.stringify(input),
1488
+ });
1489
+ }
1490
+ if (name === "get_publisher_application_status") return apiRequest(`/api/publisher-applications/${encodeURIComponent(input.caseId || input.id)}`);
1491
+ if (name === "request_source_indexing") {
1492
+ return apiRequest("/api/source-requests", {
1493
+ method: "POST",
1494
+ body: JSON.stringify({
1495
+ repo: input.repo,
1496
+ source: input.source || "",
1497
+ sourceRoute: "mcp:request_source_indexing",
1498
+ useCase: input.useCase || "agent-requested-indexing",
1499
+ targetTool: input.targetTool || "",
1500
+ desiredFiles: Array.isArray(input.desiredFiles) ? input.desiredFiles : [],
1501
+ contact: input.contact || "",
1502
+ }),
1503
+ });
1504
+ }
1505
+ if (name === "get_source_request_status") return apiRequest(`/api/source-requests/${encodeURIComponent(input.caseId || input.id)}`);
1506
+ if (name === "list_publisher_api_keys") {
1507
+ const params = paramsFrom(input, ["limit"]);
1508
+ if (!params.has("limit")) params.set("limit", "50");
1509
+ return apiRequest(`/api/publisher/api-keys?${params}`);
1510
+ }
1511
+ if (name === "create_publisher_api_key") {
1512
+ return apiRequest("/api/publisher/api-keys", {
1513
+ method: "POST",
1514
+ body: JSON.stringify(input),
1515
+ });
1516
+ }
1517
+ if (name === "revoke_publisher_api_key") {
1518
+ return apiRequest(`/api/publisher/api-keys/${encodeURIComponent(input.keyId || input.id)}`, {
1519
+ method: "DELETE",
1520
+ });
1521
+ }
1522
+ if (name === "get_mirror_readiness") {
1523
+ const params = paramsFrom(input, ["limit", "requestedOnly"]);
1524
+ if (!params.has("limit")) params.set("limit", "50");
1525
+ return apiRequest(`/api/mirror-readiness?${params}`);
1526
+ }
1527
+ if (name === "get_mirror_scale_plan") {
1528
+ const params = paramsFrom(input, ["limit", "candidateLimit", "targetHostedFiles", "maxPlannedBytes", "requestedOnly"]);
1529
+ if (!params.has("limit")) params.set("limit", "25");
1530
+ return apiRequest(`/api/mirror-scale-plan?${params}`);
1531
+ }
1532
+ if (name === "list_stacks") return apiRequest("/api/stacks");
1533
+ if (name === "get_stack") return apiRequest(`/api/stacks/${encodeURIComponent(input.slug)}`);
1534
+ if (name === "list_answer_packs") return apiRequest("/api/answers");
1535
+ if (name === "get_answer_pack") return apiRequest(`/api/answers/${encodeURIComponent(input.slug)}`);
1536
+ if (name === "get_citation_pack") {
1537
+ const slug = String(input.slug || "").trim();
1538
+ if (slug) return apiRequest(`/api/answers/${encodeURIComponent(slug)}/citations`);
1539
+ const params = paramsFrom(input, ["q", "query"]);
1540
+ return apiRequest(`/api/citations${params.toString() ? `?${params}` : ""}`);
1541
+ }
1542
+ if (name === "get_ranking") return apiRequest(`/api/rankings/${encodeURIComponent(input.slug)}`);
1543
+ if (name === "search_artifacts") {
1544
+ const params = paramsFrom(input, ["q", "limit", "cursor", "sort", "type", "license", "task", "framework", "format", "hosting", "reviewStatus", "source", "commercial", "semantic", "explain"]);
1545
+ params.set("summary", "1");
1546
+ if (!params.has("limit")) params.set("limit", "50");
1547
+ return apiRequest(`/api/artifacts?${params}`);
1548
+ }
1549
+ if (name === "resolve_artifact") {
1550
+ const params = paramsFrom(input, ["repo", "url", "q", "source"]);
1551
+ return apiRequest(`/api/resolve?${params}`);
1552
+ }
1553
+ if (name === "get_artifact") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}`);
1554
+ if (name === "get_artifact_metadata") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/metadata.json`);
1555
+ if (name === "get_artifact_bundle") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/agent-bundle`);
1556
+ if (name === "get_release_bundle") return apiRequest(`/api/releases/${encodeURIComponent(input.id)}`);
1557
+ if (name === "get_release_readiness") return apiRequest(`/api/releases/${encodeURIComponent(input.id)}/readiness`);
1558
+ if (name === "get_artifact_distribution") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/distribution`);
1559
+ if (name === "get_peer_fallbacks") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/peer-fallbacks`);
1560
+ if (name === "list_admin_peer_fallbacks") {
1561
+ const params = paramsFrom(input, ["status", "limit"]);
1562
+ return apiRequest(`/api/admin/peer-fallbacks${params.toString() ? `?${params}` : ""}`);
1563
+ }
1564
+ if (name === "get_artifact_insights") return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/insights`);
1565
+ if (name === "get_local_kit") {
1566
+ const params = paramsFrom(input, ["tool"]);
1567
+ return apiRequest(`/api/local-kits/${encodeURIComponent(input.id)}${params.toString() ? `?${params}` : ""}`);
1568
+ }
1569
+ if (name === "get_download_plan") {
1570
+ const params = paramsFrom(input, ["tool"]);
1571
+ return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/download-plan${params.toString() ? `?${params}` : ""}`);
1572
+ }
1573
+ if (name === "get_artifact_card") {
1574
+ return input.markdown
1575
+ ? { markdown: await apiText(`/api/artifacts/${encodeURIComponent(input.id)}/card.md`) }
1576
+ : apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/card`);
1577
+ }
1578
+ if (name === "get_artifact_reviews") {
1579
+ const params = paramsFrom(input, ["limit"]);
1580
+ return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/reviews?${params}`);
1581
+ }
1582
+ if (name === "get_evidence_rollups") {
1583
+ const params = paramsFrom(input, ["limit"]);
1584
+ if (!params.has("limit")) params.set("limit", "25");
1585
+ return apiRequest(`/api/evidence/rollups?${params}`);
1586
+ }
1587
+ if (name === "get_review_queue") {
1588
+ const params = paramsFrom(input, ["mode", "hosting", "maxReviews", "limit"]);
1589
+ if (!params.has("limit")) params.set("limit", "25");
1590
+ return apiRequest(`/api/community/review-queue?${params}`);
1591
+ }
1592
+ if (name === "submit_artifact_review") {
1593
+ const { id, ...body } = input;
1594
+ return apiRequest(`/api/artifacts/${encodeURIComponent(id)}/reviews`, {
1595
+ method: "POST",
1596
+ body: JSON.stringify(body),
1597
+ });
1598
+ }
1599
+ if (name === "mark_review_helpful") {
1600
+ return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/reviews/${encodeURIComponent(input.reviewId)}/helpful`, {
1601
+ method: "POST",
1602
+ body: JSON.stringify({}),
1603
+ });
1604
+ }
1605
+ if (name === "report_review") {
1606
+ const { id, reviewId, ...body } = input;
1607
+ return apiRequest(`/api/artifacts/${encodeURIComponent(id)}/reviews/${encodeURIComponent(reviewId)}/report`, {
1608
+ method: "POST",
1609
+ body: JSON.stringify(body),
1610
+ });
1611
+ }
1612
+ if (name === "get_community_signals") {
1613
+ const params = paramsFrom(input, ["limit"]);
1614
+ if (!params.has("limit")) params.set("limit", "25");
1615
+ return apiRequest(`/api/community/signals?${params}`);
1616
+ }
1617
+ if (name === "compare_artifacts") {
1618
+ const ids = Array.isArray(input.ids) ? input.ids.slice(0, 6).join(",") : "";
1619
+ return apiRequest(`/api/compare?ids=${encodeURIComponent(ids)}`);
1620
+ }
1621
+ if (name === "preview_file") return apiRequest(`/api/previews/${encodeURIComponent(input.id)}/${encodeURIComponent(input.path)}`);
1622
+ if (name === "list_files") {
1623
+ const params = paramsFrom(input, ["q", "tool", "limit", "cursor"]);
1624
+ if (!params.has("limit")) params.set("limit", "100");
1625
+ return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/files?${params}`);
1626
+ }
1627
+ if (name === "list_downloadable_files") {
1628
+ const params = paramsFrom(input, ["q", "pack", "artifactId", "path", "sourceKind", "tool", "limit"]);
1629
+ if (!params.has("limit")) params.set("limit", "100");
1630
+ return apiRequest(`/api/downloadable-files?${params}`);
1631
+ }
1632
+ if (name === "list_mirror_packs") return apiRequest("/api/mirror-packs");
1633
+ if (name === "get_mirror_pack") return apiRequest(`/api/mirror-packs/${encodeURIComponent(input.slug)}`);
1634
+ if (name === "list_mirror_demand") {
1635
+ const params = paramsFrom(input, ["limit", "requestedOnly"]);
1636
+ if (!params.has("limit")) params.set("limit", "25");
1637
+ return apiRequest(`/api/mirror-demand?${params}`);
1638
+ }
1639
+ if (name === "list_mirrors") return apiRequest("/api/mirrors");
1640
+ if (name === "register_mirror") {
1641
+ return apiRequest("/api/mirrors", {
1642
+ method: "POST",
1643
+ body: JSON.stringify({
1644
+ name: input.name,
1645
+ region: input.region,
1646
+ endpoint: input.endpoint,
1647
+ }),
1648
+ });
1649
+ }
1650
+ if (name === "update_mirror") {
1651
+ const { id, ...body } = input;
1652
+ return apiRequest(`/api/mirrors/${encodeURIComponent(id)}`, {
1653
+ method: "PATCH",
1654
+ body: JSON.stringify(body),
1655
+ });
1656
+ }
1657
+ if (name === "list_topics") return apiRequest("/api/topics");
1658
+ if (name === "get_topic") return apiRequest(`/api/topics/${encodeURIComponent(input.slug)}`);
1659
+ if (name === "request_mirror") {
1660
+ return apiRequest(`/api/artifacts/${encodeURIComponent(input.id)}/mirror-request`, {
1661
+ method: "POST",
1662
+ body: JSON.stringify({
1663
+ sourceRoute: input.sourceRoute || "mcp:request_mirror",
1664
+ query: input.query || "",
1665
+ topic: input.topic || "",
1666
+ ranking: input.ranking || "",
1667
+ useCase: input.useCase || "agent-requested-review",
1668
+ targetTool: input.targetTool || "",
1669
+ desiredFiles: Array.isArray(input.desiredFiles) ? input.desiredFiles : [],
1670
+ contact: input.contact || "",
1671
+ }),
1672
+ });
1673
+ }
1674
+ if (name === "get_trust_bundle") return apiRequest(`/api/trust-bundles/${encodeURIComponent(input.id)}`);
1675
+ if (name === "get_manifest_signing_key") return apiRequest("/api/keys/manifest-signing");
1676
+ if (name === "get_indexing_status") return apiRequest("/api/indexing/status");
1677
+ if (name === "list_indexing_urls") {
1678
+ const params = paramsFrom(input, ["kind", "limit", "cursor", "q", "source", "type", "license", "format", "hosting", "reviewStatus", "tool", "worksWith", "commercial", "verified", "sort"]);
1679
+ if (!params.has("kind")) params.set("kind", "artifact");
1680
+ if (!params.has("limit")) params.set("limit", "100");
1681
+ return apiRequest(`/api/indexing/urls?${params}`);
1682
+ }
1683
+ if (name === "get_import_status") return apiRequest("/api/admin/jobs");
1684
+ if (name === "list_import_runs") {
1685
+ const params = paramsFrom(input, ["limit", "cursor"]);
1686
+ if (!params.has("limit")) params.set("limit", "20");
1687
+ return apiRequest(`/api/admin/imports?${params}`);
1688
+ }
1689
+ if (name === "get_import_run") return apiRequest(`/api/admin/imports/${encodeURIComponent(input.runId)}`);
1690
+ if (name === "extend_hf_import") {
1691
+ return apiRequest("/api/admin/imports/huggingface/extend", {
1692
+ method: "POST",
1693
+ body: JSON.stringify({
1694
+ previousRunId: input.previousRunId,
1695
+ targetRecords: input.targetRecords || 100_000,
1696
+ pageSize: input.pageSize || 500,
1697
+ preset: input.preset || "traction-default",
1698
+ }),
1699
+ });
1700
+ }
1701
+ if (name === "run_hf_worker_batch") {
1702
+ return apiRequest("/api/admin/imports/huggingface/worker/run", {
1703
+ method: "POST",
1704
+ body: JSON.stringify({
1705
+ metadataOnly: true,
1706
+ runId: input.runId || "",
1707
+ maxPages: input.maxPages || 5,
1708
+ }),
1709
+ });
1710
+ }
1711
+ if (name === "run_source_import") {
1712
+ return apiRequest("/api/admin/imports/sources/catalog", {
1713
+ method: "POST",
1714
+ body: JSON.stringify({
1715
+ source: input.source || "all",
1716
+ pack: input.pack || "",
1717
+ limit: input.limit || 100,
1718
+ github: input.github,
1719
+ arxiv: input.arxiv,
1720
+ openml: input.openml,
1721
+ zenodo: input.zenodo,
1722
+ dataverse: input.dataverse,
1723
+ datacite: input.datacite,
1724
+ paperswithcode: input.paperswithcode,
1725
+ opendatalab: input.opendatalab,
1726
+ opencompass: input.opencompass,
1727
+ modelscope: input.modelscope,
1728
+ query: input.query || "",
1729
+ strict: Boolean(input.strict),
1730
+ dryRun: Boolean(input.dryRun),
1731
+ }),
1732
+ });
1733
+ }
1734
+ if (name === "plan_source_import") {
1735
+ return apiRequest("/api/admin/imports/sources/plan", {
1736
+ method: "POST",
1737
+ body: JSON.stringify({
1738
+ source: input.source || "all",
1739
+ pack: input.pack || "",
1740
+ targetRecords: input.targetRecords || 1000,
1741
+ pageSize: input.pageSize || 100,
1742
+ github: input.github,
1743
+ arxiv: input.arxiv,
1744
+ openml: input.openml,
1745
+ zenodo: input.zenodo,
1746
+ dataverse: input.dataverse,
1747
+ datacite: input.datacite,
1748
+ paperswithcode: input.paperswithcode,
1749
+ opendatalab: input.opendatalab,
1750
+ opencompass: input.opencompass,
1751
+ modelscope: input.modelscope,
1752
+ query: input.query || "",
1753
+ }),
1754
+ });
1755
+ }
1756
+ if (name === "run_source_worker_batch") {
1757
+ return apiRequest("/api/admin/imports/sources/worker/run", {
1758
+ method: "POST",
1759
+ body: JSON.stringify({
1760
+ metadataOnly: true,
1761
+ runId: input.runId || "",
1762
+ maxPages: input.maxPages || 10,
1763
+ maxErrors: input.maxErrors || 3,
1764
+ }),
1765
+ });
1766
+ }
1767
+ if (name === "get_traffic_summary") return apiRequest("/api/admin/traffic");
1768
+ if (name === "expand_hf_detail_metadata") {
1769
+ return apiRequest("/api/admin/imports/huggingface/detail-expand", {
1770
+ method: "POST",
1771
+ body: JSON.stringify({
1772
+ limit: input.limit || 25,
1773
+ q: input.q || "",
1774
+ requestedOnly: Boolean(input.requestedOnly),
1775
+ force: Boolean(input.force),
1776
+ missingSizes: input.missingSizes !== false,
1777
+ preferRuntime: input.preferRuntime !== false,
1778
+ dryRun: input.dryRun !== false,
1779
+ maxRuntimeMs: input.maxRuntimeMs,
1780
+ timeoutMs: input.timeoutMs,
1781
+ retries: input.retries,
1782
+ backoffMs: input.backoffMs,
1783
+ }),
1784
+ });
1785
+ }
1786
+ if (name === "create_upload_session") {
1787
+ return apiRequest("/api/upload-sessions", {
1788
+ method: "POST",
1789
+ body: JSON.stringify({
1790
+ owner: input.owner,
1791
+ name: input.name,
1792
+ files: input.files || [],
1793
+ }),
1794
+ });
1795
+ }
1796
+ if (name === "get_upload_session") return apiRequest(`/api/upload-sessions/${encodeURIComponent(input.id)}${input.refresh ? "?refresh=1" : ""}`);
1797
+ if (name === "resume_upload_session") {
1798
+ return apiRequest(`/api/upload-sessions/${encodeURIComponent(input.id)}/resume`, {
1799
+ method: "POST",
1800
+ body: JSON.stringify({}),
1801
+ });
1802
+ }
1803
+ if (name === "complete_upload_session") {
1804
+ return apiRequest(`/api/upload-sessions/${encodeURIComponent(input.id)}/complete`, {
1805
+ method: "POST",
1806
+ body: JSON.stringify({}),
1807
+ });
1808
+ }
1809
+ if (name === "cancel_upload_session") {
1810
+ return apiRequest(`/api/upload-sessions/${encodeURIComponent(input.id)}`, {
1811
+ method: "DELETE",
1812
+ });
1813
+ }
1814
+ if (name === "get_admin_mirror_queue") {
1815
+ const params = paramsFrom(input, ["limit", "requestedOnly"]);
1816
+ if (!params.has("limit")) params.set("limit", "50");
1817
+ return apiRequest(`/api/admin/mirror-queue?${params}`);
1818
+ }
1819
+ if (name === "get_user_request_automation") return apiRequest("/api/admin/user-requests");
1820
+ if (name === "run_mirror_queue_batch") {
1821
+ return apiRequest("/api/admin/mirror-queue/run", {
1822
+ method: "POST",
1823
+ body: JSON.stringify({
1824
+ limit: input.limit || 3,
1825
+ dryRun: input.dryRun !== false,
1826
+ storageCheck: true,
1827
+ targetHostedFiles: input.targetHostedFiles,
1828
+ maxPlannedBytes: input.maxPlannedBytes,
1829
+ }),
1830
+ });
1831
+ }
1832
+ if (name === "create_mirror_batch") {
1833
+ return apiRequest("/api/admin/mirror-batches/plan", {
1834
+ method: "POST",
1835
+ body: JSON.stringify({
1836
+ limit: input.limit || 25,
1837
+ candidateLimit: input.candidateLimit,
1838
+ requestedOnly: Boolean(input.requestedOnly),
1839
+ includeSupportOnly: Boolean(input.includeSupportOnly),
1840
+ includeReviewedRiskyWeights: Boolean(input.includeReviewedRiskyWeights),
1841
+ targetHostedFiles: input.targetHostedFiles,
1842
+ maxPlannedBytes: input.maxPlannedBytes,
1843
+ note: input.note || "",
1844
+ }),
1845
+ });
1846
+ }
1847
+ if (name === "list_mirror_batches") {
1848
+ const params = paramsFrom(input, ["limit", "status"]);
1849
+ if (!params.has("limit")) params.set("limit", "25");
1850
+ return apiRequest(`/api/admin/mirror-batches?${params}`);
1851
+ }
1852
+ if (name === "get_mirror_batch") {
1853
+ return apiRequest(`/api/admin/mirror-batches/${encodeURIComponent(input.id)}`);
1854
+ }
1855
+ if (name === "approve_mirror_batch") {
1856
+ return apiRequest(`/api/admin/mirror-batches/${encodeURIComponent(input.id)}/approve`, {
1857
+ method: "POST",
1858
+ body: JSON.stringify({
1859
+ note: input.note || "",
1860
+ riskOverride: input.riskOverride,
1861
+ }),
1862
+ });
1863
+ }
1864
+ if (name === "run_mirror_batch") {
1865
+ return apiRequest(`/api/admin/mirror-batches/${encodeURIComponent(input.id)}/run`, {
1866
+ method: "POST",
1867
+ body: JSON.stringify({
1868
+ dryRun: input.dryRun !== false,
1869
+ storageCheck: true,
1870
+ stopOnFailure: Boolean(input.stopOnFailure),
1871
+ }),
1872
+ });
1873
+ }
1874
+ if (name === "recover_mirror_batch") {
1875
+ return apiRequest(`/api/admin/mirror-batches/${encodeURIComponent(input.id)}/recover`, {
1876
+ method: "POST",
1877
+ body: JSON.stringify({
1878
+ action: input.action || "retry_failed",
1879
+ note: input.note || "",
1880
+ }),
1881
+ });
1882
+ }
1883
+ if (name === "check_storage") {
1884
+ return apiRequest("/api/admin/storage/check", {
1885
+ method: "POST",
1886
+ body: JSON.stringify({}),
1887
+ });
1888
+ }
1889
+ throw new Error(`Unknown tool: ${name}`);
1890
+ }
1891
+
1892
+ function writeMessage(message) {
1893
+ const payload = JSON.stringify(message);
1894
+ process.stdout.write(`Content-Length: ${Buffer.byteLength(payload, "utf8")}\r\n\r\n${payload}`);
1895
+ }
1896
+
1897
+ function result(id, payload) {
1898
+ writeMessage({ jsonrpc: "2.0", id, result: payload });
1899
+ }
1900
+
1901
+ function errorResult(id, code, message, data) {
1902
+ writeMessage({ jsonrpc: "2.0", id, error: { code, message, ...(data === undefined ? {} : { data }) } });
1903
+ }
1904
+
1905
+ async function handleMessage(message) {
1906
+ if (!message || !message.method) return;
1907
+ const id = message.id;
1908
+ try {
1909
+ if (message.method === "initialize") {
1910
+ result(id, {
1911
+ protocolVersion: message.params?.protocolVersion || "2025-06-18",
1912
+ capabilities: { tools: {} },
1913
+ serverInfo,
1914
+ });
1915
+ return;
1916
+ }
1917
+ if (message.method === "tools/list") {
1918
+ result(id, { tools });
1919
+ return;
1920
+ }
1921
+ if (message.method === "tools/call") {
1922
+ const output = await callTool(message.params?.name, message.params?.arguments || {});
1923
+ result(id, {
1924
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
1925
+ structuredContent: output,
1926
+ isError: false,
1927
+ });
1928
+ return;
1929
+ }
1930
+ if (message.method === "ping") {
1931
+ result(id, {});
1932
+ return;
1933
+ }
1934
+ if (id !== undefined) errorResult(id, -32601, `Method not found: ${message.method}`);
1935
+ } catch (error) {
1936
+ if (id !== undefined) {
1937
+ errorResult(id, -32000, error instanceof Error ? error.message : "Tool failed", error?.payload);
1938
+ }
1939
+ }
1940
+ }
1941
+
1942
+ let buffer = Buffer.alloc(0);
1943
+
1944
+ function consumeBuffer() {
1945
+ while (buffer.length) {
1946
+ const headerEnd = buffer.indexOf("\r\n\r\n");
1947
+ if (headerEnd >= 0) {
1948
+ const header = buffer.slice(0, headerEnd).toString("utf8");
1949
+ const match = header.match(/content-length:\s*(\d+)/i);
1950
+ if (!match) {
1951
+ buffer = buffer.slice(headerEnd + 4);
1952
+ continue;
1953
+ }
1954
+ const length = Number(match[1]);
1955
+ const payloadStart = headerEnd + 4;
1956
+ if (buffer.length < payloadStart + length) return;
1957
+ const raw = buffer.slice(payloadStart, payloadStart + length).toString("utf8");
1958
+ buffer = buffer.slice(payloadStart + length);
1959
+ void handleMessage(JSON.parse(raw));
1960
+ continue;
1961
+ }
1962
+
1963
+ const lineEnd = buffer.indexOf("\n");
1964
+ if (lineEnd < 0) return;
1965
+ const line = buffer.slice(0, lineEnd).toString("utf8").trim();
1966
+ buffer = buffer.slice(lineEnd + 1);
1967
+ if (line) void handleMessage(JSON.parse(line));
1968
+ }
1969
+ }
1970
+
1971
+ process.stdin.on("data", (chunk) => {
1972
+ buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
1973
+ consumeBuffer();
1974
+ });
1975
+
1976
+ process.stdin.resume();