@slashfi/agents-sdk 0.21.0 → 0.23.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agents SDK
2
2
 
3
- SDK for building AI agents with tool definitions and JSON-RPC servers.
3
+ SDK for building, testing, and publishing AI agent definitions. Includes the `adk` CLI (Agent Development Kit) for working with MCP servers and the `@agentdef` npm package ecosystem.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,265 +10,421 @@ bun add @slashfi/agents-sdk
10
10
  npm install @slashfi/agents-sdk
11
11
  ```
12
12
 
13
- ## Quick Start
13
+ ## Overview
14
14
 
15
- ```typescript
16
- import {
17
- defineAgent,
18
- defineTool,
19
- createAgentRegistry,
20
- createAgentServer
21
- } from '@slashfi/agents-sdk';
22
-
23
- // Define a tool
24
- const greet = defineTool({
25
- name: 'greet',
26
- description: 'Greet a user',
27
- inputSchema: {
28
- type: 'object',
29
- properties: {
30
- name: { type: 'string', description: 'Name to greet' }
31
- },
32
- required: ['name']
33
- },
34
- execute: async (input: { name: string }) => {
35
- return { message: `Hello, ${input.name}!` };
36
- }
37
- });
15
+ The SDK has two main parts:
38
16
 
39
- // Define an agent
40
- const agent = defineAgent({
41
- path: '@my-agent',
42
- entrypoint: 'You are a helpful assistant.',
43
- config: {
44
- name: 'My Agent',
45
- description: 'A helpful agent that can greet users'
46
- },
47
- tools: [greet]
48
- });
17
+ 1. **Runtime** define agents, tools, registries, and servers programmatically
18
+ 2. **ADK CLI** — introspect MCP servers, pack agent definitions, publish to npm
49
19
 
50
- // Create registry and register agent
51
- const registry = createAgentRegistry();
52
- registry.register(agent);
20
+ ---
53
21
 
54
- // Start HTTP server
55
- const server = createAgentServer(registry, { port: 3000 });
56
- await server.start();
22
+ ## ADK CLI
23
+
24
+ The Agent Development Kit CLI. One tool for the full agent definition lifecycle.
25
+
26
+ ```bash
27
+ adk --help
57
28
  ```
58
29
 
59
- ## API
30
+ ### Commands
60
31
 
61
- ### `defineTool(options)`
32
+ | Command | Description |
33
+ |---------|-------------|
34
+ | `adk introspect` | Connect to an MCP server → produce `agent.json` |
35
+ | `adk pack` | Generate a publishable `@agentdef/*` npm package from `agent.json` |
36
+ | `adk publish` | Pack + `npm publish` in one step |
37
+ | `adk codegen` | Full codegen from MCP server (TypeScript types, CLI, manifest) |
38
+ | `adk use` | Execute a tool on a generated agent |
39
+ | `adk list` | List all generated agents |
62
40
 
63
- Create a tool definition.
41
+ ### Workflow
64
42
 
65
- ```typescript
66
- const tool = defineTool({
67
- name: 'tool-name',
68
- description: 'What the tool does',
69
- inputSchema: {
70
- type: 'object',
71
- properties: {
72
- param: { type: 'string', description: 'Parameter description' }
73
- },
74
- required: ['param']
75
- },
76
- execute: async (input, ctx) => {
77
- // Tool implementation
78
- return result;
79
- }
80
- });
43
+ ```bash
44
+ # 1. Introspect any MCP server → agent.json
45
+ adk introspect --server 'npx @notionhq/notion-mcp-server' --name notion
46
+
47
+ # 2. Review the generated agent.json (supports JSONC — comments allowed)
48
+ cat agent.json
49
+
50
+ # 3. Pack into a publishable npm package
51
+ adk pack
52
+ # ✅ Packed @agentdef/notion@1.0.0
53
+ # Hash: ba845dfb
54
+ # Tools: 22
55
+ # Size: 28.7KB
56
+
57
+ # 4. Publish to npm
58
+ adk publish
59
+ # ✅ Published @agentdef/notion@1.0.0
81
60
  ```
82
61
 
83
- ### `defineAgent(options)`
62
+ ### `adk introspect`
84
63
 
85
- Create an agent definition.
64
+ Connects to an MCP server via stdio, discovers all tools, deduplicates shared `$defs`, and writes a `SerializedAgentDefinition` as JSON.
86
65
 
87
- ```typescript
88
- const agent = defineAgent({
89
- path: '@agent-name',
90
- entrypoint: 'System prompt for the agent',
91
- config: {
92
- name: 'Agent Name',
93
- description: 'Agent description',
94
- supportedActions: ['execute_tool', 'describe_tools', 'load']
95
- },
96
- tools: [tool1, tool2]
97
- });
66
+ ```bash
67
+ adk introspect --server 'npx @notionhq/notion-mcp-server' --name notion
68
+ adk introspect --server 'npx @modelcontextprotocol/server-github' --name github --out ./definitions/github.json
98
69
  ```
99
70
 
100
- ### `createAgentRegistry(options?)`
71
+ **Options:**
101
72
 
102
- Create an agent registry to manage agents.
73
+ | Flag | Description | Default |
74
+ |------|-------------|---------|
75
+ | `--server <cmd>` | MCP server command to run | required |
76
+ | `--name <name>` | Agent name | required |
77
+ | `--out <path>` | Output file path | `./<name>.json` |
103
78
 
104
- ```typescript
105
- const registry = createAgentRegistry({
106
- defaultVisibility: 'internal' // 'public' | 'internal' | 'private'
107
- });
79
+ ### `adk pack`
108
80
 
109
- registry.register(agent);
110
- registry.list(); // Returns all registered agents
111
- registry.get('@agent-name'); // Get agent by path
81
+ Reads `agent.json` and generates a complete, publishable npm package:
112
82
 
113
- // Call an agent
114
- const result = await registry.call({
115
- action: 'execute_tool',
116
- path: '@agent-name',
117
- tool: 'tool-name',
118
- params: { param: 'value' }
119
- });
83
+ ```
84
+ @agentdef/notion/
85
+ ├── package.json ← generated from agent.json
86
+ ├── agent.json ← full SerializedAgentDefinition
87
+ ├── meta.json ← version metadata + diff from previous
88
+ ├── index.js ← re-export for ESM import
89
+ └── index.d.ts ← typed as SerializedAgentDefinition
120
90
  ```
121
91
 
122
- ### `createAgentServer(registry, options?)`
92
+ **Options:**
123
93
 
124
- Create an HTTP server exposing the registry.
94
+ | Flag | Description | Default |
95
+ |------|-------------|---------|
96
+ | `--agent <path>` | Path to agent.json | `./agent.json` |
97
+ | `--out <dir>` | Output directory | `./dist` |
98
+ | `--scope <scope>` | npm scope | `@agentdef` |
99
+ | `--previous <path>` | Previous agent.json for version diff | — |
125
100
 
126
- ```typescript
127
- const server = createAgentServer(registry, {
128
- port: 3000,
129
- hostname: 'localhost',
130
- basePath: '/api',
131
- cors: true
132
- });
101
+ **Version diff** — pass `--previous` to generate a diff in `meta.json`:
133
102
 
134
- await server.start();
135
- // POST /api/call - Execute agent actions
136
- // GET /api/list - List agents
103
+ ```bash
104
+ adk pack --previous ./agent-v1.json
105
+ # Packed @agentdef/notion@1.1.0
106
+ # Added: new-tool
107
+ # Removed: deprecated-tool
108
+ # Modified: search (inputSchema changed)
109
+ ```
110
+
111
+ ### `adk publish`
137
112
 
138
- await server.stop();
113
+ Packs + publishes to npm. Includes safety checks:
114
+
115
+ - **Duplicate version** — refuses with clear error + hint
116
+ - **Out-of-order version** — refuses to clobber `latest` tag
117
+ - **Auth failures** — hints to `npm login` or set `NPM_TOKEN`
118
+
119
+ ```bash
120
+ adk publish
121
+ adk publish --dry-run
122
+ adk publish --tag beta
123
+ adk publish --registry http://localhost:4873
139
124
  ```
140
125
 
141
- ## HTTP Endpoints
126
+ **Options:**
142
127
 
143
- ### POST /call
128
+ | Flag | Description | Default |
129
+ |------|-------------|---------|
130
+ | `--dry-run` | Pack without publishing | — |
131
+ | `--tag <tag>` | npm dist-tag | `latest` |
132
+ | `--access <level>` | `public` or `restricted` | `public` |
133
+ | `--registry <url>` | npm registry URL | default npm |
134
+ | + all `pack` options | | |
144
135
 
145
- Execute an agent action.
136
+ **Error examples:**
146
137
 
147
- **Request:**
148
- ```json
149
- {
150
- "action": "execute_tool",
151
- "path": "@my-agent",
152
- "tool": "greet",
153
- "params": { "name": "World" }
154
- }
155
138
  ```
139
+ ✗ @agentdef/notion@1.0.0 already exists in registry
156
140
 
157
- **Response:**
158
- ```json
159
- {
160
- "success": true,
161
- "result": { "message": "Hello, World!" }
162
- }
141
+ Published versions: 1.0.0
142
+ Hint: bump the version in agent.json, or use --tag to publish a pre-release
143
+ Debug: cat /home/user/.npm/_logs/2026-03-29_debug.log | tail -40
163
144
  ```
164
145
 
165
- **Actions:**
166
- - `execute_tool` - Execute a specific tool
167
- - `describe_tools` - Get tool schemas
168
- - `load` - Get agent definition
146
+ ```
147
+ Warning: publishing 4.0.0 which is older than latest (5.0.0)
148
+ This will move the "latest" tag from 5.0.0 to 4.0.0.
149
+ Use --tag <name> to publish without affecting latest.
150
+ Refusing to clobber latest tag. Use --tag <name> to publish 4.0.0 alongside 5.0.0.
151
+ ```
169
152
 
170
- ### GET /list
153
+ ---
171
154
 
172
- List registered agents.
155
+ ## @agentdef Packages
173
156
 
174
- **Response:**
175
- ```json
157
+ Agent definitions published to npm under the `@agentdef` scope. Like `@types` for TypeScript, but for agent tool definitions.
158
+
159
+ ### Consuming
160
+
161
+ ```bash
162
+ npm install @agentdef/notion
163
+ ```
164
+
165
+ ```typescript
166
+ import definition from '@agentdef/notion';
167
+ // definition: SerializedAgentDefinition
168
+
169
+ console.log(definition.tools.length); // 22
170
+ console.log(definition.tools[0].name); // 'API-post-search'
171
+ ```
172
+
173
+ Access metadata:
174
+
175
+ ```typescript
176
+ import meta from '@agentdef/notion/meta.json';
177
+ // { hash, toolCount, sizeBytes, generatedAt, sdkVersion, changes? }
178
+ ```
179
+
180
+ ### agent.json Format
181
+
182
+ `agent.json` is the single source of truth. Supports JSONC (comments + trailing commas).
183
+
184
+ ```jsonc
176
185
  {
177
- "success": true,
178
- "agents": [
186
+ // Agent identity
187
+ "path": "notion",
188
+ "name": "Notion MCP Server",
189
+ "description": "Agent for Notion API",
190
+ "version": "1.0.0",
191
+ "visibility": "public",
192
+
193
+ // MCP server source (for re-introspection)
194
+ "serverSource": "npx @notionhq/notion-mcp-server",
195
+ "serverInfo": { "name": "Notion MCP Server", "version": "1.6.2" },
196
+
197
+ // Shared JSON Schema $defs (deduplicated across tools)
198
+ "$defs": { ... },
199
+
200
+ // Tool definitions
201
+ "tools": [
179
202
  {
180
- "path": "@my-agent",
181
- "name": "My Agent",
182
- "description": "A helpful agent",
183
- "supportedActions": ["execute_tool", "describe_tools", "load"]
203
+ "name": "API-post-search",
204
+ "description": "Search Notion pages and databases",
205
+ "inputSchema": {
206
+ "type": "object",
207
+ "properties": {
208
+ "query": { "type": "string" }
209
+ }
210
+ }
184
211
  }
185
- ]
212
+ // ...
213
+ ],
214
+
215
+ // Generation metadata
216
+ "generatedAt": "2026-03-29T08:40:04.913Z",
217
+ "sdkVersion": "0.21.0"
186
218
  }
187
219
  ```
188
220
 
189
- ## Access Control
221
+ ### meta.json Format
190
222
 
191
- Agents and tools support visibility levels:
223
+ ```json
224
+ {
225
+ "hash": "ba845dfb",
226
+ "serverVersion": "1.6.2",
227
+ "npmPackage": "npx @notionhq/notion-mcp-server",
228
+ "toolCount": 22,
229
+ "sizeBytes": 29373,
230
+ "generatedAt": "2026-03-29T08:40:04.913Z",
231
+ "sdkVersion": "0.21.0",
232
+ "changes": {
233
+ "previousHash": "a3f8c2de",
234
+ "toolsAdded": ["new-tool"],
235
+ "toolsRemoved": [],
236
+ "toolsModified": ["search"],
237
+ "schemaChanges": ["search: added property 'filter'"]
238
+ }
239
+ }
240
+ ```
241
+
242
+ ---
192
243
 
193
- - `public` - Anyone can access
194
- - `internal` - Only other agents in the same registry
195
- - `private` - Only the owning agent
244
+ ## Runtime API
245
+
246
+ ### `defineAgent(options)`
247
+
248
+ Create an agent definition.
196
249
 
197
250
  ```typescript
251
+ import { defineAgent, defineTool } from '@slashfi/agents-sdk';
252
+
253
+ const search = defineTool({
254
+ name: 'search',
255
+ description: 'Search for items',
256
+ inputSchema: {
257
+ type: 'object',
258
+ properties: {
259
+ query: { type: 'string', description: 'Search query' }
260
+ },
261
+ required: ['query']
262
+ },
263
+ execute: async (input) => {
264
+ return { results: [] };
265
+ }
266
+ });
267
+
198
268
  const agent = defineAgent({
199
- path: '@private-agent',
200
- entrypoint: '...',
201
- visibility: 'internal',
202
- allowedCallers: ['@trusted-agent'] // Explicit allowlist
269
+ path: '@my-agent',
270
+ entrypoint: 'You are a helpful search assistant.',
271
+ config: {
272
+ name: 'Search Agent',
273
+ description: 'An agent that can search'
274
+ },
275
+ tools: [search]
203
276
  });
204
277
  ```
205
278
 
206
- ## Filesystem Convention
279
+ ### `createClient(definition)`
207
280
 
208
- Organize agents using the filesystem convention:
281
+ Create a typed client from a `SerializedAgentDefinition`. Used for consuming `@agentdef` packages at runtime.
209
282
 
210
- ```
211
- src/agents/
212
- ├── @my-agent/
213
- │ ├── entrypoint.md # System prompt
214
- │ ├── agent.config.ts # Configuration
215
- │ ├── greet.tool.ts # Tool (exports greetTool)
216
- │ └── echo.tool.ts # Tool (exports echoTool)
217
- └── @another-agent/
218
- └── ...
283
+ ```typescript
284
+ import { createClient } from '@slashfi/agents-sdk';
285
+ import definition from '@agentdef/notion';
286
+
287
+ const client = createClient(definition);
288
+ const result = await client.callTool('API-post-search', { query: 'hello' });
219
289
  ```
220
290
 
221
- ### Build Script
291
+ ### `createAgentRegistry(options?)`
222
292
 
223
- Use `buildAgents` to generate the registry at build time:
293
+ Create an agent registry.
224
294
 
225
295
  ```typescript
226
- // scripts/build-agents.ts
227
- import { buildAgents } from '@slashfi/agents-sdk';
296
+ import { createAgentRegistry } from '@slashfi/agents-sdk';
228
297
 
229
- const result = await buildAgents({
230
- agentsDir: './src/agents',
231
- outFile: './src/agents/_generated-registry.ts',
232
- });
298
+ const registry = createAgentRegistry();
299
+ registry.register(agent);
300
+ registry.list();
301
+ registry.get('@my-agent');
233
302
 
234
- console.log(`Built ${result.agentCount} agents: ${result.agents.join(', ')}`);
303
+ const result = await registry.call({
304
+ action: 'execute_tool',
305
+ path: '@my-agent',
306
+ tool: 'search',
307
+ params: { query: 'hello' }
308
+ });
235
309
  ```
236
310
 
237
- Run before TypeScript compilation:
311
+ ### `createAgentServer(registry, options?)`
238
312
 
239
- ```bash
240
- bun scripts/build-agents.ts && bun run build
313
+ HTTP server exposing the registry via JSON-RPC.
314
+
315
+ ```typescript
316
+ import { createAgentServer } from '@slashfi/agents-sdk';
317
+
318
+ const server = createAgentServer(registry, { port: 3000 });
319
+ await server.start();
320
+ // POST /call — execute agent actions
321
+ // GET /list — list agents
241
322
  ```
242
323
 
243
- ### File Conventions
324
+ ### `SerializedAgentDefinition`
244
325
 
245
- **entrypoint.md** - System prompt for the agent (markdown)
326
+ The core type a portable, JSON-serializable agent definition.
246
327
 
247
- **agent.config.ts** - Agent configuration:
248
328
  ```typescript
249
- import type { AgentConfig } from '@slashfi/agents-sdk';
329
+ import type { SerializedAgentDefinition } from '@slashfi/agents-sdk';
330
+
331
+ interface SerializedAgentDefinition {
332
+ path: string;
333
+ name: string;
334
+ description?: string;
335
+ version?: string;
336
+ visibility?: 'public' | 'internal' | 'private';
337
+ serverSource?: string;
338
+ serverInfo?: { name?: string; version?: string };
339
+ $defs?: Record<string, unknown>;
340
+ tools: {
341
+ name: string;
342
+ description: string;
343
+ inputSchema: Record<string, unknown>;
344
+ }[];
345
+ generatedAt?: string;
346
+ sdkVersion?: string;
347
+ }
348
+ ```
349
+
350
+ ---
250
351
 
251
- const config: AgentConfig = {
252
- name: 'My Agent',
253
- description: 'Does things',
254
- supportedActions: ['execute_tool', 'describe_tools', 'load'],
255
- };
352
+ ## JSONC Support
256
353
 
257
- export default config;
354
+ All JSON files read by `adk` support JSONC (JSON with Comments):
355
+
356
+ ```jsonc
357
+ {
358
+ // This is a comment
359
+ "name": "notion",
360
+ "tools": [
361
+ /* multi-line
362
+ comment */
363
+ { "name": "search" }
364
+ ], // trailing commas are fine
365
+ }
258
366
  ```
259
367
 
260
- **{name}.tool.ts** - Tool definition (exports `{name}Tool`):
261
368
  ```typescript
262
- import { defineTool } from '@slashfi/agents-sdk';
369
+ import { parseJsonc, readJsoncFile } from '@slashfi/agents-sdk';
263
370
 
264
- export const greetTool = defineTool({
265
- name: 'greet',
266
- description: 'Greet a user',
267
- inputSchema: { ... },
268
- execute: async (input) => ({ message: `Hello!` }),
269
- });
371
+ const data = parseJsonc('{ "key": "value" /* comment */ }');
372
+ const file = readJsoncFile('./config.jsonc');
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Testing
378
+
379
+ ### Unit tests (tarball round-trip)
380
+
381
+ ```bash
382
+ bun test/e2e-adk.ts
383
+ ```
384
+
385
+ Tests: pack → npm pack → install tarball → import → verify → version diff.
386
+
387
+ ### Integration tests (verdaccio)
388
+
389
+ Full registry lifecycle with a local npm registry:
390
+
391
+ ```bash
392
+ # Start verdaccio
393
+ npx verdaccio --config test/verdaccio-config.yaml --listen 4873
394
+
395
+ # Run tests (in another terminal)
396
+ bun test/e2e-verdaccio.ts
270
397
  ```
271
398
 
399
+ Tests: publish v1 → install → publish v2 → npm update → pinned install → version listing.
400
+
401
+ ---
402
+
403
+ ## Project Structure
404
+
405
+ ```
406
+ src/
407
+ ├── adk.ts # ADK CLI entrypoint
408
+ ├── pack.ts # Pack + publish logic, version diff engine
409
+ ├── introspect.ts # MCP server introspection
410
+ ├── jsonc.ts # JSONC parser
411
+ ├── codegen.ts # Full codegen (TypeScript types, CLI, manifest)
412
+ ├── serialized.ts # SerializedAgentDefinition type
413
+ ├── client.ts # createClient()
414
+ ├── define.ts # defineAgent(), defineTool()
415
+ ├── registry.ts # Agent registry
416
+ ├── server.ts # HTTP server
417
+ ├── index.ts # Public API exports
418
+ └── ...
419
+
420
+ test/
421
+ ├── e2e-adk.ts # Tarball round-trip test
422
+ ├── e2e-verdaccio.ts # Full registry lifecycle test
423
+ └── verdaccio-config.yaml # Local registry config
424
+ ```
425
+
426
+ ---
427
+
272
428
  ## License
273
429
 
274
430
  MIT
package/dist/adk.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * ADK CLI — Agent Development Kit
4
+ *
5
+ * Unified CLI for building, testing, and publishing agent definitions.
6
+ *
7
+ * 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
14
+ *
15
+ * @example
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
30
+ * ```
31
+ */
32
+ export {};
33
+ //# sourceMappingURL=adk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adk.d.ts","sourceRoot":"","sources":["../src/adk.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}