@rotifer/mcp-server 0.8.2 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -1,9 +1,21 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
- import { CallToolRequestSchema, ListToolsRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
- import { searchGenes, getGeneDetail, arenaRankings, compareGenes, geneStats, leaderboard, developerProfile, listLocalGenes, listLocalAgents, submitToArena, installGeneFromCloud, createLocalAgent, agentRun, compileGene, runGene, initGene, scanGenes, wrapGene, testGene, publishGene, authStatus, login, logout, geneVersions, mcpStats, geneReputation, myReputation, domainSuggestion } from "./tools.js";
2
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
+ import { searchGenes, getGeneDetail, arenaRankings, compareGenes, geneStats, leaderboard, developerProfile, listLocalGenes, listLocalAgents, submitToArena, installGeneFromCloud, createLocalAgent, agentRun, compileGene, runGene, initGene, scanGenes, wrapGene, testGene, publishGene, authStatus, login, logout, geneVersions, mcpStats, geneReputation, myReputation, domainSuggestion, vgScan } from "./tools.js";
4
4
  import { getGeneStatsRpc, getReputationLeaderboard, getDeveloperProfile, getGene, logMcpCall } from "./cloud.js";
5
+ import { getPackageVersion, getVersionInfo, formatUpdateHint } from "./version.js";
6
+ const ICON_DATA_URI = "data:image/png;base64,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";
5
7
  export function createServer() {
6
- const server = new Server({ name: "rotifer", version: "0.8.1" }, { capabilities: { tools: {}, resources: {} } });
8
+ const version = getPackageVersion();
9
+ const server = new Server({
10
+ name: "rotifer",
11
+ version,
12
+ icons: [{ src: ICON_DATA_URI, mimeType: "image/png" }],
13
+ }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
14
+ let isVersionWarningShown = false;
15
+ let cachedVersionInfo = null;
16
+ getVersionInfo()
17
+ .then((info) => { cachedVersionInfo = info; })
18
+ .catch(() => { });
7
19
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
8
20
  tools: [
9
21
  {
@@ -11,25 +23,27 @@ export function createServer() {
11
23
  description: "Search the Rotifer Gene ecosystem. Returns a list of Genes matching the query, filterable by domain and fidelity.",
12
24
  inputSchema: {
13
25
  type: "object",
26
+ additionalProperties: false,
14
27
  properties: {
15
28
  query: { type: "string", description: "Free-text search by gene name or description" },
16
29
  domain: { type: "string", description: "Filter by capability domain (e.g. search.web, code.format)" },
17
30
  fidelity: { type: "string", enum: ["Wrapped", "Hybrid", "Native", "Unknown"], description: "Filter by gene fidelity type" },
18
- sort: { type: "string", enum: ["relevance", "newest", "reputation", "downloads"], description: "Sort order (default: relevance when query is given, newest otherwise)" },
31
+ sort: { type: "string", enum: ["relevance", "newest", "popular", "fitness"], description: "Sort order (default: relevance when query is given, newest otherwise)" },
19
32
  page: { type: "number", description: "Page number (default 1)" },
20
- perPage: { type: "number", description: "Results per page (default 20, max 50)" },
33
+ per_page: { type: "number", description: "Results per page (default 20, max 50)" },
21
34
  },
22
35
  },
23
36
  },
24
37
  {
25
38
  name: "get_gene_detail",
26
- description: "Get detailed information about a specific Gene by its ID, including phenotype, fitness, and metadata.",
39
+ description: "Get detailed information about a specific Gene by its ID or content_hash, including phenotype, fitness, and metadata. At least one of gene_id or content_hash must be provided.",
27
40
  inputSchema: {
28
41
  type: "object",
42
+ additionalProperties: false,
29
43
  properties: {
30
- id: { type: "string", description: "Gene UUID" },
44
+ gene_id: { type: "string", description: "Gene UUID (required if content_hash not provided)" },
45
+ content_hash: { type: "string", description: "SHA-256 content hash of the gene's phenotype (alternative to gene_id)" },
31
46
  },
32
- required: ["id"],
33
47
  },
34
48
  },
35
49
  {
@@ -37,10 +51,11 @@ export function createServer() {
37
51
  description: "Get Arena rankings for a domain with full 5-dimensional fitness metrics: fitness (F(g)), safety, success_rate, latency, and resource_efficiency. Use this to find the best Gene for a capability.",
38
52
  inputSchema: {
39
53
  type: "object",
54
+ additionalProperties: false,
40
55
  properties: {
41
56
  domain: { type: "string", description: "Capability domain (e.g. search.web)" },
42
57
  page: { type: "number", description: "Page number (default 1)" },
43
- perPage: { type: "number", description: "Results per page (default 20)" },
58
+ per_page: { type: "number", description: "Results per page (default 20)" },
44
59
  },
45
60
  },
46
61
  },
@@ -49,6 +64,7 @@ export function createServer() {
49
64
  description: "Compare two or more Genes by their F(g) fitness metrics. Returns side-by-side fitness breakdown.",
50
65
  inputSchema: {
51
66
  type: "object",
67
+ additionalProperties: false,
52
68
  properties: {
53
69
  gene_ids: {
54
70
  type: "array",
@@ -66,6 +82,7 @@ export function createServer() {
66
82
  description: "Get download statistics for a Gene, broken down by time period (total, last 7 days, 30 days, 90 days).",
67
83
  inputSchema: {
68
84
  type: "object",
85
+ additionalProperties: false,
69
86
  properties: {
70
87
  gene_id: { type: "string", description: "Gene UUID" },
71
88
  },
@@ -74,9 +91,10 @@ export function createServer() {
74
91
  },
75
92
  {
76
93
  name: "get_leaderboard",
77
- description: "Get the developer reputation leaderboard. Shows top developers ranked by reputation score, including their published gene count, total downloads, and arena wins.",
94
+ description: "Get the creator reputation leaderboard. Shows top creators ranked by reputation score, including their published gene count, total downloads, and arena wins.",
78
95
  inputSchema: {
79
96
  type: "object",
97
+ additionalProperties: false,
80
98
  properties: {
81
99
  limit: { type: "number", description: "Number of entries to return (default 20, max 100)" },
82
100
  },
@@ -84,11 +102,12 @@ export function createServer() {
84
102
  },
85
103
  {
86
104
  name: "get_developer_profile",
87
- description: "Get a developer's public profile and reputation data by username.",
105
+ description: "Get a creator's public profile and reputation data by username.",
88
106
  inputSchema: {
89
107
  type: "object",
108
+ additionalProperties: false,
90
109
  properties: {
91
- username: { type: "string", description: "Developer username" },
110
+ username: { type: "string", description: "Creator username" },
92
111
  },
93
112
  required: ["username"],
94
113
  },
@@ -98,6 +117,7 @@ export function createServer() {
98
117
  description: "List Genes installed in the local project workspace. Scans the genes/ directory for phenotype.json files and returns metadata, compile status, and cloud origin for each Gene.",
99
118
  inputSchema: {
100
119
  type: "object",
120
+ additionalProperties: false,
101
121
  properties: {
102
122
  project_root: { type: "string", description: "Project root path (defaults to current working directory)" },
103
123
  domain: { type: "string", description: "Filter by domain prefix (e.g. 'search' matches 'search.web')" },
@@ -110,6 +130,7 @@ export function createServer() {
110
130
  description: "List Agents registered in the local project workspace. Returns each Agent's name, state, genome composition, strategy, and reputation. Agents are local constructs that compose multiple Genes into pipelines.",
111
131
  inputSchema: {
112
132
  type: "object",
133
+ additionalProperties: false,
113
134
  properties: {
114
135
  project_root: { type: "string", description: "Project root path (defaults to current working directory)" },
115
136
  state: { type: "string", description: "Filter by agent state (e.g. 'Active', 'Inactive')" },
@@ -121,9 +142,11 @@ export function createServer() {
121
142
  description: "Install a Gene from the Rotifer Cloud Registry into the local project. Downloads phenotype and metadata. Requires a valid gene_id from search_genes or get_gene_detail.",
122
143
  inputSchema: {
123
144
  type: "object",
145
+ additionalProperties: false,
124
146
  properties: {
125
147
  gene_id: { type: "string", description: "Gene UUID to install" },
126
148
  project_root: { type: "string", description: "Project root path (defaults to cwd)" },
149
+ force: { type: "boolean", description: "Overwrite if gene already exists locally (default: false)" },
127
150
  },
128
151
  required: ["gene_id"],
129
152
  },
@@ -133,6 +156,7 @@ export function createServer() {
133
156
  description: "Submit a Gene to the Arena with fitness metrics. Requires authentication (rotifer login). Upserts the Gene's Arena entry with 5-dimensional fitness scores.",
134
157
  inputSchema: {
135
158
  type: "object",
159
+ additionalProperties: false,
136
160
  properties: {
137
161
  gene_id: { type: "string", description: "Gene UUID to submit" },
138
162
  fitness_value: { type: "number", description: "Overall fitness score F(g) (0-1)" },
@@ -146,29 +170,36 @@ export function createServer() {
146
170
  },
147
171
  {
148
172
  name: "create_agent",
149
- description: "Create a new Agent by composing one or more local Genes. The Agent is saved to .rotifer/agents/ in the project. Genes must exist locally (wrap them first).",
173
+ description: "Create a new Agent by composing one or more local Genes. The Agent is saved to .rotifer/agents/ in the project. Genes must exist locally (wrap them first with wrap_gene).",
150
174
  inputSchema: {
151
175
  type: "object",
176
+ additionalProperties: false,
152
177
  properties: {
153
- name: { type: "string", description: "Agent name" },
154
- genes: { type: "array", items: { type: "string" }, description: "Array of local gene names to compose" },
155
- composition: { type: "string", enum: ["Seq", "Par", "Try"], description: "Composition strategy (default: Seq for multi-gene, Single for one gene)" },
178
+ agent_name: { type: "string", description: "Agent name" },
179
+ gene_ids: { type: "array", items: { type: "string" }, minItems: 1, description: "Array of local gene names to compose (at least one required)" },
180
+ composition: { type: "string", enum: ["Seq", "Par", "Cond", "Try", "TryPool"], description: "Composition strategy (default: Seq for multi-gene, Single for one gene)" },
156
181
  project_root: { type: "string", description: "Project root path (defaults to cwd)" },
182
+ domain: { type: "string", description: "Domain tag for the agent (e.g. search.web). Metadata only, does not auto-select genes." },
183
+ strategy: { type: "string", description: "Gene selection strategy (default: greedy)" },
184
+ par_merge: { type: "string", enum: ["first", "concat", "merge"], description: "Merge strategy for Par composition (default: first)" },
157
185
  },
158
- required: ["name", "genes"],
186
+ required: ["agent_name", "gene_ids"],
159
187
  },
160
188
  },
161
189
  {
162
190
  name: "agent_run",
163
- description: "Run a local Agent by its ID. Executes via the Rotifer CLI (rotifer agent run). The Agent must exist in .rotifer/agents/. Returns stdout/stderr from the execution.",
191
+ description: "Run a local Agent by name. Executes via the Rotifer CLI (rotifer agent run <agent-name>). The Agent must exist in .rotifer/agents/. Returns stdout/stderr from the execution.",
164
192
  inputSchema: {
165
193
  type: "object",
194
+ additionalProperties: false,
166
195
  properties: {
167
- agent_id: { type: "string", description: "Agent UUID" },
196
+ agent_name: { type: "string", description: "Agent name (as given during create_agent)" },
168
197
  project_root: { type: "string", description: "Project root path" },
169
- input: { type: "string", description: "Input data to pass to the agent" },
198
+ input: { type: "string", description: "Input data to pass to the agent (JSON string)" },
199
+ verbose: { type: "boolean", description: "Show intermediate results for each gene step" },
200
+ no_sandbox: { type: "boolean", description: "Force Node.js execution, skip WASM sandbox" },
170
201
  },
171
- required: ["agent_id"],
202
+ required: ["agent_name"],
172
203
  },
173
204
  },
174
205
  {
@@ -176,9 +207,13 @@ export function createServer() {
176
207
  description: "Compile a local Gene to WASM via the Rotifer CLI (rotifer compile). The Gene must exist in the local genes/ directory. Returns compilation output.",
177
208
  inputSchema: {
178
209
  type: "object",
210
+ additionalProperties: false,
179
211
  properties: {
180
212
  gene_name: { type: "string", description: "Gene name (directory name under genes/)" },
181
213
  project_root: { type: "string", description: "Project root path" },
214
+ check: { type: "boolean", description: "Validate only, don't produce artifacts (default: false)" },
215
+ wasm_path: { type: "string", description: "Path to a pre-compiled .wasm file to wrap as IR" },
216
+ lang: { type: "string", enum: ["ts", "wasm"], description: "Force compilation mode (auto-detected by default)" },
182
217
  },
183
218
  required: ["gene_name"],
184
219
  },
@@ -188,10 +223,14 @@ export function createServer() {
188
223
  description: "Execute a local Gene via the Rotifer CLI (rotifer run). The Gene must exist in the local genes/ directory. Returns execution output.",
189
224
  inputSchema: {
190
225
  type: "object",
226
+ additionalProperties: false,
191
227
  properties: {
192
228
  gene_name: { type: "string", description: "Gene name (directory name under genes/)" },
193
229
  project_root: { type: "string", description: "Project root path" },
194
- input: { type: "string", description: "Input data to pass to the gene" },
230
+ input: { type: "string", description: "Input JSON data to pass to the gene" },
231
+ verbose: { type: "boolean", description: "Show detailed execution output (default: false)" },
232
+ no_sandbox: { type: "boolean", description: "Run without WASM sandbox, Node.js only (default: false)" },
233
+ trust_unsigned: { type: "boolean", description: "Allow Node.js execution for Cloud-installed genes (default: false)" },
195
234
  },
196
235
  required: ["gene_name"],
197
236
  },
@@ -201,12 +240,15 @@ export function createServer() {
201
240
  description: "Initialize a new Rotifer Gene project. Creates a directory with phenotype.json template and starter files. Supports Wrapped, Hybrid, and Native fidelity types.",
202
241
  inputSchema: {
203
242
  type: "object",
243
+ additionalProperties: false,
204
244
  properties: {
205
- name: { type: "string", description: "Gene name (will create genes/<name>/ directory)" },
245
+ gene_name: { type: "string", description: "Gene name (will create genes/<gene_name>/ directory)" },
206
246
  project_root: { type: "string", description: "Project root path" },
207
247
  fidelity: { type: "string", enum: ["Wrapped", "Hybrid", "Native"], description: "Gene fidelity type (default: Wrapped)" },
248
+ domain: { type: "string", description: "Default gene domain (default: general)" },
249
+ no_genesis: { type: "boolean", description: "Skip genesis genes installation (default: false)" },
208
250
  },
209
- required: ["name"],
251
+ required: ["gene_name"],
210
252
  },
211
253
  },
212
254
  {
@@ -214,9 +256,12 @@ export function createServer() {
214
256
  description: "Scan source files for candidate gene functions or local SKILL.md files that can be wrapped as Genes. Returns discovered candidates with metadata.",
215
257
  inputSchema: {
216
258
  type: "object",
259
+ additionalProperties: false,
217
260
  properties: {
218
261
  path: { type: "string", description: "Path to scan (defaults to current directory)" },
219
262
  project_root: { type: "string", description: "Project root path" },
263
+ skills: { type: "boolean", description: "Scan for SKILL.md files instead of source functions (default: false)" },
264
+ skills_path: { type: "string", description: "Directory to scan for skills (default: .cursor/skills)" },
220
265
  },
221
266
  },
222
267
  },
@@ -225,47 +270,61 @@ export function createServer() {
225
270
  description: "Wrap a function or SKILL.md as a Rotifer Gene. Generates phenotype.json from the source. The target must exist in the project.",
226
271
  inputSchema: {
227
272
  type: "object",
273
+ additionalProperties: false,
228
274
  properties: {
229
- name: { type: "string", description: "Name of the function or skill to wrap" },
275
+ gene_name: { type: "string", description: "Name of the function or skill to wrap" },
230
276
  project_root: { type: "string", description: "Project root path" },
277
+ domain: { type: "string", description: "Gene functional domain (e.g. search.web, code.format)" },
278
+ fidelity: { type: "string", enum: ["Wrapped", "Hybrid", "Native"], description: "Fidelity level (default: Wrapped)" },
279
+ from_skill: { type: "string", description: "Create gene from a SKILL.md file (path to SKILL.md or its directory)" },
280
+ from_clawhub: { type: "string", description: "Create gene from a ClawHub skill (slug, downloads and converts automatically)" },
231
281
  },
232
- required: ["name"],
282
+ required: ["gene_name"],
233
283
  },
234
284
  },
235
285
  {
236
286
  name: "test_gene",
237
- description: "Test a Gene in the L2 sandbox. Validates phenotype schema, runs input/output tests, and checks compilation. If no name is given, tests all local genes.",
287
+ description: "Test a Gene in the sandbox. Validates phenotype schema, runs input/output tests, and checks compilation.",
238
288
  inputSchema: {
239
289
  type: "object",
290
+ additionalProperties: false,
240
291
  properties: {
241
- name: { type: "string", description: "Gene name to test (optional, tests all if omitted)" },
292
+ gene_name: { type: "string", description: "Gene name to test" },
242
293
  project_root: { type: "string", description: "Project root path" },
294
+ verbose: { type: "boolean", description: "Show detailed output (default: false)" },
295
+ compliance: { type: "boolean", description: "Run structural compliance checks (default: false)" },
243
296
  },
297
+ required: ["gene_name"],
244
298
  },
245
299
  },
246
300
  {
247
301
  name: "publish_gene",
248
- description: "Publish a Gene to Rotifer Cloud. Requires authentication (use login tool first). Validates, uploads, and optionally submits to Arena. Use --all to publish all local genes.",
302
+ description: "Publish a Gene to Rotifer Cloud. Requires authentication (use login tool first). Validates, uploads, and optionally submits to Arena. Either gene_name or all=true must be provided.",
249
303
  inputSchema: {
250
304
  type: "object",
305
+ additionalProperties: false,
251
306
  properties: {
252
- name: { type: "string", description: "Gene name to publish (optional if --all)" },
307
+ gene_name: { type: "string", description: "Gene name to publish (required unless all=true)" },
253
308
  project_root: { type: "string", description: "Project root path" },
254
309
  all: { type: "boolean", description: "Publish all local genes (default: false)" },
255
310
  skip_arena: { type: "boolean", description: "Skip automatic Arena submission after publish (default: false)" },
311
+ description: { type: "string", description: "Gene description" },
312
+ changelog: { type: "string", description: "Changelog entry for this version (max 500 chars)" },
313
+ skip_security: { type: "boolean", description: "Skip pre-publish security checks (default: false)" },
256
314
  },
257
315
  },
258
316
  },
259
317
  {
260
318
  name: "list_gene_versions",
261
- description: "List the version history chain of a Gene by owner and name. Returns all published versions in chronological order with changelog entries and previous_version_id links.",
319
+ description: "List the version history chain of a Gene by creator and name. Returns all published versions in chronological order with changelog entries and previous_version_id links.",
262
320
  inputSchema: {
263
321
  type: "object",
322
+ additionalProperties: false,
264
323
  properties: {
265
- owner: { type: "string", description: "Gene owner's username" },
266
- name: { type: "string", description: "Gene name" },
324
+ owner: { type: "string", description: "Gene creator's username" },
325
+ gene_name: { type: "string", description: "Gene name" },
267
326
  },
268
- required: ["owner", "name"],
327
+ required: ["owner", "gene_name"],
269
328
  },
270
329
  },
271
330
  {
@@ -273,6 +332,7 @@ export function createServer() {
273
332
  description: "Get MCP Server call analytics for a given time period. Returns total calls, success rate, average latency, top tools, and top genes. Requires authentication.",
274
333
  inputSchema: {
275
334
  type: "object",
335
+ additionalProperties: false,
276
336
  properties: {
277
337
  days: { type: "number", description: "Time window in days (default 7)" },
278
338
  },
@@ -283,6 +343,7 @@ export function createServer() {
283
343
  description: "Check current authentication status. Returns whether the user is logged in, their username, provider, and how many minutes until the token expires.",
284
344
  inputSchema: {
285
345
  type: "object",
346
+ additionalProperties: false,
286
347
  properties: {},
287
348
  },
288
349
  },
@@ -291,8 +352,10 @@ export function createServer() {
291
352
  description: "Log in to Rotifer Cloud. Opens the browser for OAuth authorization (GitHub or GitLab). After the user authorizes in the browser, credentials are saved locally. This must be done before using arena_submit or publish_gene.",
292
353
  inputSchema: {
293
354
  type: "object",
355
+ additionalProperties: false,
294
356
  properties: {
295
357
  provider: { type: "string", enum: ["github", "gitlab"], description: "OAuth provider (default: github)" },
358
+ endpoint: { type: "string", description: "Cloud endpoint URL (uses default if omitted)" },
296
359
  },
297
360
  },
298
361
  },
@@ -301,6 +364,7 @@ export function createServer() {
301
364
  description: "Log out from Rotifer Cloud. Clears locally saved credentials.",
302
365
  inputSchema: {
303
366
  type: "object",
367
+ additionalProperties: false,
304
368
  properties: {},
305
369
  },
306
370
  },
@@ -309,6 +373,7 @@ export function createServer() {
309
373
  description: "Get detailed reputation breakdown for a Gene (Arena, Usage, Stability scores).",
310
374
  inputSchema: {
311
375
  type: "object",
376
+ additionalProperties: false,
312
377
  properties: {
313
378
  gene_id: { type: "string", description: "Gene ID" },
314
379
  },
@@ -317,9 +382,10 @@ export function createServer() {
317
382
  },
318
383
  {
319
384
  name: "get_my_reputation",
320
- description: "Get the current logged-in developer's reputation and stats. Requires authentication.",
385
+ description: "Get the current logged-in creator's reputation and stats. Requires authentication.",
321
386
  inputSchema: {
322
387
  type: "object",
388
+ additionalProperties: false,
323
389
  properties: {},
324
390
  },
325
391
  },
@@ -328,12 +394,27 @@ export function createServer() {
328
394
  description: "Suggest top matching domains from the domain registry based on a description.",
329
395
  inputSchema: {
330
396
  type: "object",
397
+ additionalProperties: false,
331
398
  properties: {
332
399
  description: { type: "string", description: "Description to match against domains" },
333
400
  },
334
401
  required: ["description"],
335
402
  },
336
403
  },
404
+ {
405
+ name: "vg_scan",
406
+ description: "V(g) security scan — static analysis for Gene/Skill code safety. Returns a grade (A/B/C/D/?) and per-finding details with severity, file, line, and snippet.",
407
+ inputSchema: {
408
+ type: "object",
409
+ additionalProperties: false,
410
+ properties: {
411
+ path: { type: "string", description: "Path to Gene or Skill directory to scan (default: current project root)" },
412
+ gene_id: { type: "string", description: "Gene/Skill identifier for the report" },
413
+ all: { type: "boolean", description: "Scan all code files, not just src/" },
414
+ project_root: { type: "string", description: "Project root directory (auto-detected if omitted)" },
415
+ },
416
+ },
417
+ },
337
418
  ],
338
419
  }));
339
420
  const GENE_ID_TOOLS = new Set([
@@ -344,22 +425,29 @@ export function createServer() {
344
425
  function extractGeneId(toolName, args) {
345
426
  if (!GENE_ID_TOOLS.has(toolName))
346
427
  return null;
347
- return (args.gene_id || args.id || args.gene_name || null);
428
+ return (args.gene_id || args.gene_name || null);
348
429
  }
349
430
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
350
431
  const { name, arguments: args } = request.params;
351
432
  const startMs = Date.now();
433
+ function mapPerPage(a) {
434
+ if ("per_page" in a) {
435
+ const { per_page, ...rest } = a;
436
+ return { ...rest, perPage: per_page };
437
+ }
438
+ return a;
439
+ }
352
440
  try {
353
441
  let result;
354
442
  switch (name) {
355
443
  case "search_genes":
356
- result = await searchGenes(args);
444
+ result = await searchGenes(mapPerPage(args));
357
445
  break;
358
446
  case "get_gene_detail":
359
447
  result = await getGeneDetail(args);
360
448
  break;
361
449
  case "get_arena_rankings":
362
- result = await arenaRankings(args);
450
+ result = await arenaRankings(mapPerPage(args));
363
451
  break;
364
452
  case "compare_genes":
365
453
  result = await compareGenes(args);
@@ -418,9 +506,16 @@ export function createServer() {
418
506
  case "get_mcp_stats":
419
507
  result = await mcpStats(args);
420
508
  break;
421
- case "auth_status":
422
- result = authStatus();
509
+ case "auth_status": {
510
+ const s = authStatus();
511
+ result = {
512
+ is_logged_in: s.isLoggedIn,
513
+ username: s.username,
514
+ provider: s.provider,
515
+ expires_in_minutes: s.expiresInMinutes,
516
+ };
423
517
  break;
518
+ }
424
519
  case "login":
425
520
  result = await login(args);
426
521
  break;
@@ -436,9 +531,12 @@ export function createServer() {
436
531
  case "suggest_domain":
437
532
  result = await domainSuggestion(args);
438
533
  break;
534
+ case "vg_scan":
535
+ result = vgScan(args);
536
+ break;
439
537
  default:
440
538
  logMcpCall({ tool_name: name, success: false, latency_ms: Date.now() - startMs });
441
- return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
539
+ return { content: [{ type: "text", text: `Unknown tool: ${name}. Use ListTools to see available tools.` }], isError: true };
442
540
  }
443
541
  logMcpCall({
444
542
  tool_name: name,
@@ -446,7 +544,14 @@ export function createServer() {
446
544
  success: true,
447
545
  latency_ms: Date.now() - startMs,
448
546
  });
449
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
547
+ const content = [
548
+ { type: "text", text: JSON.stringify(result, null, 2) },
549
+ ];
550
+ if (!isVersionWarningShown && cachedVersionInfo?.updateAvailable) {
551
+ isVersionWarningShown = true;
552
+ content.push({ type: "text", text: formatUpdateHint(cachedVersionInfo) });
553
+ }
554
+ return { content };
450
555
  }
451
556
  catch (error) {
452
557
  logMcpCall({
@@ -468,8 +573,8 @@ export function createServer() {
468
573
  },
469
574
  {
470
575
  uriTemplate: "rotifer://developers/{username}",
471
- name: "Developer Profile",
472
- description: "A developer's public profile and reputation data",
576
+ name: "Creator Profile",
577
+ description: "A creator's public profile and reputation data",
473
578
  mimeType: "application/json",
474
579
  },
475
580
  {
@@ -481,7 +586,7 @@ export function createServer() {
481
586
  {
482
587
  uriTemplate: "rotifer://leaderboard",
483
588
  name: "Reputation Leaderboard",
484
- description: "Top developers ranked by reputation score",
589
+ description: "Top creators ranked by reputation score",
485
590
  mimeType: "application/json",
486
591
  },
487
592
  {
@@ -496,6 +601,12 @@ export function createServer() {
496
601
  description: "All Agents registered in the current project workspace",
497
602
  mimeType: "application/json",
498
603
  },
604
+ {
605
+ uriTemplate: "rotifer://version",
606
+ name: "Version Info",
607
+ description: "Current and latest version of Rotifer MCP Server, with update availability",
608
+ mimeType: "application/json",
609
+ },
499
610
  ],
500
611
  }));
501
612
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
@@ -539,7 +650,149 @@ export function createServer() {
539
650
  contents: [{ uri, mimeType: "application/json", text: JSON.stringify(data, null, 2) }],
540
651
  };
541
652
  }
542
- throw new Error(`Unknown resource URI: ${uri}`);
653
+ if (uri === "rotifer://version") {
654
+ const info = cachedVersionInfo || await getVersionInfo();
655
+ return {
656
+ contents: [{ uri, mimeType: "application/json", text: JSON.stringify(info, null, 2) }],
657
+ };
658
+ }
659
+ throw new Error(`Unknown resource URI: ${uri}. Valid URI patterns: rotifer://genes/{gene_id}, rotifer://genes/{gene_id}/stats, rotifer://developers/{username}, rotifer://leaderboard, rotifer://local/genes, rotifer://local/agents, rotifer://version`);
660
+ });
661
+ // Prompt templates
662
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
663
+ return {
664
+ prompts: [
665
+ {
666
+ name: "rotifer-hello",
667
+ description: "Interactive agent creation — choose a template and build an agent in seconds",
668
+ arguments: [
669
+ { name: "template", description: "Template ID (quality-advisor, uiux-diagnosis, content-analysis, code-security, doc-qa, web3-toolkit)", required: false },
670
+ { name: "input", description: "JSON input for the template", required: false },
671
+ ],
672
+ },
673
+ {
674
+ name: "rotifer-guide",
675
+ description: "Understand Rotifer Protocol — core concepts, Gene model, and how agents work",
676
+ },
677
+ {
678
+ name: "rotifer-architect",
679
+ description: "Design an Agent — select genes, choose composition, define pipeline",
680
+ arguments: [
681
+ { name: "task", description: "What the agent should accomplish", required: true },
682
+ ],
683
+ },
684
+ {
685
+ name: "rotifer-challenge",
686
+ description: "Arena evaluation — submit a gene, compare with competitors, understand fitness scoring",
687
+ arguments: [
688
+ { name: "gene", description: "Gene name to evaluate", required: true },
689
+ ],
690
+ },
691
+ ],
692
+ };
693
+ });
694
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
695
+ const { name } = request.params;
696
+ switch (name) {
697
+ case "rotifer-hello":
698
+ return {
699
+ description: "Interactive agent creation with Rotifer Protocol",
700
+ messages: [
701
+ {
702
+ role: "user",
703
+ content: {
704
+ type: "text",
705
+ text: [
706
+ "I want to create an agent using Rotifer Protocol.",
707
+ request.params.arguments?.template ? `Use the ${request.params.arguments.template} template.` : "Help me choose a template.",
708
+ request.params.arguments?.input ? `Use this input: ${request.params.arguments.input}` : "",
709
+ "",
710
+ "Available templates:",
711
+ "- quality-advisor: Gene library health diagnostic",
712
+ "- uiux-diagnosis: WCAG + Nielsen heuristic analysis",
713
+ "- content-analysis: Readability and virality scoring",
714
+ "- code-security: Vulnerability and credential scanning",
715
+ "- doc-qa: RAG pipeline with cited answers",
716
+ "- web3-toolkit: Smart contract audit pipeline",
717
+ "",
718
+ "Run `rotifer hello --template <id>` to execute.",
719
+ ].filter(Boolean).join("\n"),
720
+ },
721
+ },
722
+ ],
723
+ };
724
+ case "rotifer-guide":
725
+ return {
726
+ description: "Rotifer Protocol conceptual guide",
727
+ messages: [
728
+ {
729
+ role: "user",
730
+ content: {
731
+ type: "text",
732
+ text: [
733
+ "Explain Rotifer Protocol to me. Cover:",
734
+ "",
735
+ "1. **Gene Model**: Code as Gene — modular, fitness-evaluable logic units",
736
+ "2. **Three Fidelities**: Native (WASM sandbox), Hybrid (code + network), Wrapped (prompt-only)",
737
+ "3. **Agent = Genome**: Composition algebra (Seq, Par, Cond, Try, TryPool)",
738
+ "4. **Fitness Function**: F(g) = (S_r × log(1+C_util) × (1+R_rob)) / (L × R_cost)",
739
+ "5. **Arena**: Competitive evaluation via arena submit/watch",
740
+ "",
741
+ "Keep it practical — show CLI commands for each concept.",
742
+ ].join("\n"),
743
+ },
744
+ },
745
+ ],
746
+ };
747
+ case "rotifer-architect":
748
+ return {
749
+ description: "Design a Rotifer agent",
750
+ messages: [
751
+ {
752
+ role: "user",
753
+ content: {
754
+ type: "text",
755
+ text: [
756
+ `I want to build an agent that: ${request.params.arguments?.task || "(describe the task)"}`,
757
+ "",
758
+ "Help me:",
759
+ "1. Identify which genes I need (search with `rotifer search <keyword>`)",
760
+ "2. Choose a composition type (Seq for pipelines, Par for parallel, Try for fallback, TryPool for competitive)",
761
+ "3. Create the agent (`rotifer agent create <name> --genes <g1> <g2>`)",
762
+ "4. Test it (`rotifer agent run <name> --input '{...}'`)",
763
+ "",
764
+ "If no suitable genes exist, suggest creating a new one with `rotifer wrap <name>`.",
765
+ ].join("\n"),
766
+ },
767
+ },
768
+ ],
769
+ };
770
+ case "rotifer-challenge":
771
+ return {
772
+ description: "Arena evaluation for a gene",
773
+ messages: [
774
+ {
775
+ role: "user",
776
+ content: {
777
+ type: "text",
778
+ text: [
779
+ `Evaluate gene: ${request.params.arguments?.gene || "(gene name)"}`,
780
+ "",
781
+ "Steps:",
782
+ "1. Run `rotifer arena submit <gene>` to enter the Arena",
783
+ "2. Run `rotifer arena watch` to see live rankings",
784
+ "3. Run `rotifer compare <gene-a> <gene-b>` for head-to-head comparison",
785
+ "",
786
+ "Fitness is scored by: correctness, utility, robustness, cost efficiency.",
787
+ "Low-fitness genes get naturally selected out — improve or be replaced.",
788
+ ].join("\n"),
789
+ },
790
+ },
791
+ ],
792
+ };
793
+ default:
794
+ throw new Error(`Unknown prompt: ${name}`);
795
+ }
543
796
  });
544
797
  return server;
545
798
  }