@slashfi/agents-sdk 0.39.0 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/adk.ts CHANGED
@@ -2,31 +2,23 @@
2
2
  /**
3
3
  * ADK CLI — Agent Development Kit
4
4
  *
5
- * Unified CLI for building, testing, and publishing agent definitions.
6
- *
7
5
  * Commands:
8
- * codegen Generate agent definitions from an MCP server (full codegen)
9
- * introspect Introspect an MCP server → agent.json (lightweight)
10
- * pack Generate publishable @agentdef/* package from agent.json
11
- * publish Pack + npm publish to @agentdef/*
12
- * use Execute a tool on a generated agent
13
- * list List all generated agents
6
+ * codegen Generate agent definitions from an MCP server
7
+ * introspect Introspect an MCP server → agent.json
8
+ * pack Generate publishable @agentdef/* package
9
+ * publish Pack + npm publish to @agentdef/*
10
+ * use Execute a tool on a generated agent
11
+ * list List all generated agents
12
+ * registry <op> Manage registry connections (add, remove, list, browse, inspect, test)
13
+ * ref <op> Manage agent refs (add, remove, list, get, inspect, call, resources, read)
14
14
  *
15
15
  * @example
16
16
  * ```bash
17
- * # Full codegen from MCP server
18
- * adk codegen --server 'npx @mcp/notion' --name notion --out ./agents/@notion
19
- *
20
- * # Lightweight introspect → agent.json
21
- * adk introspect --server 'npx @notionhq/notion-mcp-server' --name notion
22
- *
23
- * # Build + publish
24
- * adk pack
25
- * adk publish
26
- *
27
- * # Use a tool
28
- * adk use notion search_pages '{"query": "hello"}'
29
- * adk use notion --list
17
+ * adk registry add https://registry.slash.com --name slash
18
+ * adk registry browse slash
19
+ * adk ref add notion --registry slash
20
+ * adk ref inspect notion
21
+ * adk ref call notion notion-search '{"query":"hello"}'
30
22
  * ```
31
23
  */
32
24
 
@@ -35,6 +27,9 @@ import { join, resolve } from "node:path";
35
27
  import { codegen, listAgentTools, useAgent } from "./codegen.js";
36
28
  import type { CodegenManifest } from "./codegen.js";
37
29
  import { pack, publish } from "./pack.js";
30
+ import { createAdk } from "./config-store.js";
31
+ import { createLocalFsStore, getLocalEncryptionKey } from "./local-fs.js";
32
+ import type { Adk } from "./config-store.js";
38
33
 
39
34
  const args = process.argv.slice(2);
40
35
  const command = args[0];
@@ -72,51 +67,57 @@ function findAgentDir(name: string): string | null {
72
67
  return null;
73
68
  }
74
69
 
70
+ function getAdk(): Adk {
71
+ const token = process.env.ADK_TOKEN ?? undefined;
72
+ const encryptionKey = getLocalEncryptionKey();
73
+ return createAdk(createLocalFsStore(), { token, encryptionKey });
74
+ }
75
+
75
76
  function printUsage() {
76
77
  console.log(`
77
78
  adk — Agent Development Kit
78
79
 
79
80
  Usage:
80
- adk codegen [options] Generate agent from MCP server (full codegen)
81
+ adk registry <op> [options] Manage registry connections
82
+ adk ref <op> [options] Manage agent refs
83
+ adk codegen [options] Generate agent from MCP server
81
84
  adk introspect [options] Introspect MCP server → agent.json
82
85
  adk pack [options] Generate publishable package from agent.json
83
86
  adk publish [options] Pack + npm publish to @agentdef/*
84
87
  adk use <agent> [options] Execute a tool on a generated agent
85
88
  adk list List all generated agents
86
89
 
87
- Codegen options:
88
- --server <source> MCP server (command string or URL)
89
- --name <name> Agent name (default: derived from server)
90
- --out <dir> Output directory (default: ./agents/@<name>)
91
- --path <path> Agent path override
92
- --no-cli Skip CLI generation
93
- --no-types Skip TypeScript interface generation
94
- --visibility <level> Agent visibility (public|internal|private)
95
-
96
- Introspect options:
97
- --server <cmd> MCP server command to introspect
98
- --name <name> Agent name for output
99
- --out <path> Output path (default: ./<name>.json)
100
-
101
- Pack / Publish options:
102
- --agent <path> Path to agent.json (default: ./agent.json)
103
- --out <dir> Output directory (default: ./dist)
104
- --scope <scope> npm scope (default: @agentdef)
105
- --previous <path> Previous agent.json for diff
106
- --dry-run Don't actually publish (publish only)
107
- --tag <tag> npm dist-tag (default: latest)
108
- --access <level> npm access: public | restricted (default: public)
109
-
110
- Use options:
111
- adk use <agent> <tool> [params_json]
112
- adk use <agent> --list List tools on the agent
90
+ Registry operations:
91
+ adk registry add <url> --name <name> [--auth-type bearer|api-key|none]
92
+ adk registry remove <name>
93
+ adk registry list
94
+ adk registry browse <name> [--query <q>]
95
+ adk registry inspect <name>
96
+ adk registry test [name]
97
+
98
+ Ref operations:
99
+ adk ref add <ref> [--registry <name>] [--as <alias>] [--url <url>] [--scheme mcp|https|registry]
100
+ adk ref remove <name>
101
+ adk ref list
102
+ adk ref get <name>
103
+ adk ref inspect <name> [--full]
104
+ adk ref call <name> <tool> [params_json]
105
+ adk ref resources <name>
106
+ adk ref read <name> <uri> [uri...]
107
+ adk ref auth <name> [--api-key <key>]
108
+ adk ref auth-status <name>
109
+
110
+ Environment:
111
+ ADK_CONFIG_DIR Config directory (default: ~/.adk)
112
+ ADK_TOKEN Bearer token for authenticated registries
113
+ ADK_ENCRYPTION_KEY Override encryption key (default: auto from ~/.adk/.encryption-key)
113
114
 
114
115
  Examples:
115
- adk codegen --server 'npx @mcp/notion' --name notion
116
- adk introspect --server 'npx @notionhq/notion-mcp-server' --name notion
117
- adk pack --agent ./agent.json
118
- adk publish --dry-run
119
- adk use notion search_pages '{"query": "hello"}'
116
+ adk registry add https://registry.slash.com --name slash
117
+ adk registry browse slash
118
+ adk ref add notion --registry slash
119
+ adk ref inspect notion --full
120
+ adk ref call notion notion-search '{"query":"hello"}'
120
121
  `);
121
122
  }
122
123
 
@@ -363,11 +364,270 @@ function runList() {
363
364
  }
364
365
  }
365
366
 
367
+ // ============================================
368
+ // Registry CLI
369
+ // ============================================
370
+
371
+ async function runRegistry() {
372
+ const op = args[1];
373
+ const adk = getAdk();
374
+
375
+ switch (op) {
376
+ case "add": {
377
+ const url = args[2];
378
+ const name = getArg("--name");
379
+ if (!url) {
380
+ console.error("Usage: adk registry add <url> --name <name>");
381
+ process.exit(1);
382
+ }
383
+ const authType = getArg("--auth-type") as "bearer" | "api-key" | "none" | undefined;
384
+ const auth = authType && authType !== "none"
385
+ ? { type: authType as "bearer" | "api-key" }
386
+ : undefined;
387
+ await adk.registry.add({ url, name: name ?? new URL(url).hostname, ...(auth && { auth }) });
388
+ console.log(`Added registry: ${name ?? url}`);
389
+ break;
390
+ }
391
+ case "remove": {
392
+ const name = args[2];
393
+ if (!name) { console.error("Usage: adk registry remove <name>"); process.exit(1); }
394
+ const removed = await adk.registry.remove(name);
395
+ console.log(removed ? `Removed: ${name}` : `Not found: ${name}`);
396
+ break;
397
+ }
398
+ case "list": {
399
+ const registries = await adk.registry.list();
400
+ if (registries.length === 0) {
401
+ console.log("No registries configured. Run: adk registry add <url> --name <name>");
402
+ break;
403
+ }
404
+ console.log(`\n${registries.length} registry(s)\n`);
405
+ for (const r of registries) {
406
+ console.log(` ${r.name ?? r.url}`);
407
+ console.log(` ${r.url}`);
408
+ if (r.auth) console.log(` auth: ${r.auth.type}`);
409
+ console.log();
410
+ }
411
+ break;
412
+ }
413
+ case "browse": {
414
+ const name = args[2];
415
+ if (!name) { console.error("Usage: adk registry browse <name> [--query <q>]"); process.exit(1); }
416
+ const query = getArg("--query");
417
+ const agents = await adk.registry.browse(name, query);
418
+ console.log(`\n${agents.length} agent(s)${query ? ` matching "${query}"` : ""}\n`);
419
+ for (const a of agents) {
420
+ const toolCount = a.tools?.length ?? 0;
421
+ console.log(` ${a.path} (${toolCount} tools)`);
422
+ if (a.description) console.log(` ${a.description.slice(0, 120)}`);
423
+ console.log();
424
+ }
425
+ break;
426
+ }
427
+ case "inspect": {
428
+ const name = args[2];
429
+ if (!name) { console.error("Usage: adk registry inspect <name>"); process.exit(1); }
430
+ const config = await adk.registry.inspect(name);
431
+ console.log(`\nRegistry: ${name}\n`);
432
+ console.log(` issuer: ${config.issuer}`);
433
+ console.log(` jwks_uri: ${config.jwks_uri}`);
434
+ console.log(` token: ${config.token_endpoint}`);
435
+ console.log(` grant_types: ${config.supported_grant_types?.join(", ")}`);
436
+ console.log();
437
+ break;
438
+ }
439
+ case "test": {
440
+ const name = args[2];
441
+ const results = await adk.registry.test(name);
442
+ for (const r of results) {
443
+ const icon = r.status === "active" ? "\x1b[32m\u2713\x1b[0m" : "\x1b[31m\u2717\x1b[0m";
444
+ console.log(`${icon} ${r.name} (${r.url})`);
445
+ if (r.issuer) console.log(` issuer: ${r.issuer}`);
446
+ if (r.error) console.log(` error: ${r.error}`);
447
+ }
448
+ break;
449
+ }
450
+ default:
451
+ console.error(`Unknown registry operation: ${op}`);
452
+ console.error("Operations: add, remove, list, browse, inspect, test");
453
+ process.exit(1);
454
+ }
455
+ }
456
+
457
+ // ============================================
458
+ // Ref CLI
459
+ // ============================================
460
+
461
+ async function runRef() {
462
+ const op = args[1];
463
+ const adk = getAdk();
464
+
465
+ switch (op) {
466
+ case "add": {
467
+ const refArg = args[2];
468
+ if (!refArg) { console.error("Usage: adk ref add <ref> [--registry <name>] [--as <alias>]"); process.exit(1); }
469
+ const entry: Record<string, unknown> = { ref: refArg };
470
+ const alias = getArg("--as");
471
+ const url = getArg("--url");
472
+ const scheme = getArg("--scheme");
473
+ const registryName = getArg("--registry");
474
+ if (alias) entry.as = alias;
475
+ if (url) entry.url = url;
476
+ if (scheme) entry.scheme = scheme;
477
+ if (registryName) {
478
+ const reg = await adk.registry.get(registryName);
479
+ if (reg) {
480
+ entry.sourceRegistry = { url: reg.url, agentPath: refArg };
481
+ }
482
+ }
483
+ const { security } = await adk.ref.add(entry as import("./define-config.js").RefEntry);
484
+ console.log(`Added ref: ${alias ?? refArg}`);
485
+ if (security && security.type !== "none") {
486
+ console.log(`\n Auth required: ${security.type}`);
487
+ console.log(` Run: adk ref auth ${alias ?? refArg}`);
488
+ }
489
+ break;
490
+ }
491
+ case "remove": {
492
+ const name = args[2];
493
+ if (!name) { console.error("Usage: adk ref remove <name>"); process.exit(1); }
494
+ const removed = await adk.ref.remove(name);
495
+ console.log(removed ? `Removed: ${name}` : `Not found: ${name}`);
496
+ break;
497
+ }
498
+ case "list": {
499
+ const refs = await adk.ref.list();
500
+ if (refs.length === 0) {
501
+ console.log("No refs configured. Run: adk ref add <ref> --registry <name>");
502
+ break;
503
+ }
504
+ console.log(`\n${refs.length} ref(s)\n`);
505
+ for (const r of refs) {
506
+ console.log(` ${r.name}`);
507
+ if (r.url) console.log(` url: ${r.url}`);
508
+ if (r.scheme) console.log(` scheme: ${r.scheme}`);
509
+ if (r.sourceRegistry) console.log(` registry: ${r.sourceRegistry.url}`);
510
+ console.log();
511
+ }
512
+ break;
513
+ }
514
+ case "get": {
515
+ const name = args[2];
516
+ if (!name) { console.error("Usage: adk ref get <name>"); process.exit(1); }
517
+ const entry = await adk.ref.get(name);
518
+ if (!entry) { console.error(`Not found: ${name}`); process.exit(1); }
519
+ console.log(JSON.stringify(entry, null, 2));
520
+ break;
521
+ }
522
+ case "inspect": {
523
+ const name = args[2];
524
+ if (!name) { console.error("Usage: adk ref inspect <name> [--full]"); process.exit(1); }
525
+ const full = hasFlag("--full");
526
+ const info = await adk.ref.inspect(name, { full });
527
+ if (!info) { console.error(`Could not inspect: ${name}`); process.exit(1); }
528
+ console.log(JSON.stringify(info, null, 2));
529
+ break;
530
+ }
531
+ case "call": {
532
+ const name = args[2];
533
+ const tool = args[3];
534
+ const paramsStr = args[4];
535
+ if (!name || !tool) { console.error("Usage: adk ref call <name> <tool> [params_json]"); process.exit(1); }
536
+ const params = paramsStr ? JSON.parse(paramsStr) : {};
537
+ const result = await adk.ref.call(name, tool, params);
538
+ console.log(JSON.stringify(result, null, 2));
539
+ break;
540
+ }
541
+ case "resources": {
542
+ const name = args[2];
543
+ if (!name) { console.error("Usage: adk ref resources <name>"); process.exit(1); }
544
+ const result = await adk.ref.resources(name);
545
+ console.log(JSON.stringify(result, null, 2));
546
+ break;
547
+ }
548
+ case "read": {
549
+ const name = args[2];
550
+ const uris = args.slice(3);
551
+ if (!name || uris.length === 0) { console.error("Usage: adk ref read <name> <uri> [uri...]"); process.exit(1); }
552
+ const result = await adk.ref.read(name, uris);
553
+ console.log(JSON.stringify(result, null, 2));
554
+ break;
555
+ }
556
+ case "auth-status": {
557
+ const name = args[2];
558
+ if (!name) { console.error("Usage: adk ref auth-status <name>"); process.exit(1); }
559
+ const status = await adk.ref.authStatus(name);
560
+ const icon = status.complete ? "\x1b[32m\u2713\x1b[0m" : "\x1b[33m!\x1b[0m";
561
+ console.log(`\n${icon} ${status.name}`);
562
+ console.log(` auth type: ${status.security?.type ?? "none"}`);
563
+ console.log(` complete: ${status.complete}`);
564
+ if (status.present.length > 0) console.log(` stored: ${status.present.join(", ")}`);
565
+ if (status.missing.length > 0) console.log(` missing: ${status.missing.join(", ")}`);
566
+ console.log();
567
+ break;
568
+ }
569
+ case "auth": {
570
+ const name = args[2];
571
+ if (!name) { console.error("Usage: adk ref auth <name> [--api-key <key>]"); process.exit(1); }
572
+ const apiKey = getArg("--api-key");
573
+
574
+ if (apiKey) {
575
+ const result = await adk.ref.auth(name, { apiKey });
576
+ if (result.complete) {
577
+ console.log(`\x1b[32m\u2713\x1b[0m Auth complete for ${name} (${result.type})`);
578
+ }
579
+ break;
580
+ }
581
+
582
+ // Check what type of auth is needed
583
+ const status = await adk.ref.authStatus(name);
584
+ if (status.complete) {
585
+ console.log(`\x1b[32m\u2713\x1b[0m ${name} is already authenticated`);
586
+ break;
587
+ }
588
+
589
+ if (status.security?.type === "apiKey" || status.security?.type === "http") {
590
+ console.error(`Provide a key: adk ref auth ${name} --api-key <your-key>`);
591
+ process.exit(1);
592
+ }
593
+
594
+ // OAuth — run locally with browser open
595
+ try {
596
+ const result = await adk.ref.authLocal(name, {
597
+ onAuthorizeUrl: (url) => {
598
+ console.log(`\nOpen this URL to authorize:\n\n ${url}\n`);
599
+ const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
600
+ import("node:child_process").then(({ exec }) => exec(`${opener} "${url}"`)).catch(() => {});
601
+ console.log("Waiting for callback ...");
602
+ },
603
+ });
604
+ if (result.complete) {
605
+ console.log(`\x1b[32m\u2713\x1b[0m Auth complete for ${name}`);
606
+ }
607
+ } catch (err) {
608
+ console.error(`Auth failed: ${err instanceof Error ? err.message : String(err)}`);
609
+ process.exit(1);
610
+ }
611
+ break;
612
+ }
613
+ default:
614
+ console.error(`Unknown ref operation: ${op}`);
615
+ console.error("Operations: add, remove, list, get, inspect, call, resources, read, auth, auth-status");
616
+ process.exit(1);
617
+ }
618
+ }
619
+
366
620
  // ============================================
367
621
  // Main
368
622
  // ============================================
369
623
 
370
624
  switch (command) {
625
+ case "registry":
626
+ await runRegistry();
627
+ break;
628
+ case "ref":
629
+ await runRef();
630
+ break;
371
631
  case "codegen":
372
632
  await runCodegen();
373
633
  break;
package/src/codegen.ts CHANGED
@@ -1153,7 +1153,7 @@ export interface CodegenManifest {
1153
1153
  agentPath: string;
1154
1154
  serverSource: ServerSource;
1155
1155
  serverInfo: McpServerInfo;
1156
- tools: { name: string; description?: string }[];
1156
+ tools: { name: string; description?: string; inputSchema?: Record<string, unknown> }[];
1157
1157
  /** How to connect to and authenticate with this MCP server */
1158
1158
  connection?: ConnectionSpec;
1159
1159
  /** Raw OAuth server metadata (from .well-known discovery) */
@@ -1191,7 +1191,7 @@ function generateManifest(
1191
1191
  agentPath,
1192
1192
  serverSource,
1193
1193
  serverInfo,
1194
- tools: tools.map((t) => ({ name: t.name, description: t.description })),
1194
+ tools: tools.map((t) => ({ name: t.name, description: t.description, ...(t.inputSchema ? { inputSchema: t.inputSchema } : {}) })),
1195
1195
  ...(connection ? { connection } : {}),
1196
1196
  ...(oauth ? { oauth } : {}),
1197
1197
  generatedAt: new Date().toISOString(),