agentkit-mesh 1.0.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 ADDED
@@ -0,0 +1,153 @@
1
+ # agentkit-mesh
2
+
3
+ Agent-to-agent discovery and delegation via [MCP](https://modelcontextprotocol.io) (Model Context Protocol).
4
+
5
+ Agents register their capabilities, discover each other by semantic search, and delegate tasks — all through standard MCP tools.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ npx agentkit-mesh
11
+ ```
12
+
13
+ This starts an MCP server over stdio, ready to connect to Claude Desktop, OpenClaw, or any MCP client.
14
+
15
+ ## MCP Configuration
16
+
17
+ ### Claude Desktop
18
+
19
+ Add to `claude_desktop_config.json`:
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "agentkit-mesh": {
25
+ "command": "npx",
26
+ "args": ["agentkit-mesh"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ### OpenClaw
33
+
34
+ Add to your OpenClaw config:
35
+
36
+ ```yaml
37
+ mcp:
38
+ agentkit-mesh:
39
+ command: npx agentkit-mesh
40
+ ```
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ ┌─────────────┐ MCP ┌──────────────────┐
46
+ │ AI Agent A │◄────────────►│ │
47
+ └─────────────┘ │ agentkit-mesh │
48
+ │ │
49
+ ┌─────────────┐ MCP │ ┌────────────┐ │
50
+ │ AI Agent B │◄────────────►│ │ Registry │ │
51
+ └─────────────┘ │ │ (SQLite) │ │
52
+ │ └────────────┘ │
53
+ ┌─────────────┐ MCP │ ┌────────────┐ │
54
+ │ AI Agent C │◄────────────►│ │ Discovery │ │
55
+ └─────────────┘ │ └────────────┘ │
56
+ │ ┌────────────┐ │
57
+ │ │ Delegation │ │
58
+ │ └────────────┘ │
59
+ └──────────────────┘
60
+ ```
61
+
62
+ ## MCP Tools
63
+
64
+ ### `mesh_register`
65
+
66
+ Register an agent with its capabilities.
67
+
68
+ | Parameter | Type | Description |
69
+ |-----------|------|-------------|
70
+ | `name` | string | Unique agent name |
71
+ | `description` | string | What this agent does |
72
+ | `capabilities` | string[] | List of capabilities |
73
+ | `endpoint` | string | Agent's MCP endpoint URL |
74
+
75
+ ### `mesh_discover`
76
+
77
+ Discover agents matching a natural language query.
78
+
79
+ | Parameter | Type | Description |
80
+ |-----------|------|-------------|
81
+ | `query` | string | Search query (e.g. "budget management") |
82
+ | `limit` | number? | Max results to return |
83
+
84
+ Returns agents ranked by relevance score with matched capability terms.
85
+
86
+ ### `mesh_unregister`
87
+
88
+ Remove an agent from the registry.
89
+
90
+ | Parameter | Type | Description |
91
+ |-----------|------|-------------|
92
+ | `name` | string | Agent name to remove |
93
+
94
+ ### `mesh_delegate`
95
+
96
+ Delegate a task to another agent by name.
97
+
98
+ | Parameter | Type | Description |
99
+ |-----------|------|-------------|
100
+ | `targetName` | string | Name of the target agent |
101
+ | `task` | string | Task description to delegate |
102
+ | `context` | string? | Optional JSON context |
103
+
104
+ Connects to the target agent's MCP endpoint and calls its `handle_task` tool.
105
+
106
+ ## Use Case: FormBridge
107
+
108
+ An HR agent filling an expense form discovers the Finance agent:
109
+
110
+ ```typescript
111
+ import { AgentRegistry, DiscoveryEngine } from 'agentkit-mesh';
112
+
113
+ const registry = new AgentRegistry();
114
+
115
+ // Agents register themselves
116
+ registry.register({
117
+ name: 'finance-agent',
118
+ description: 'Budget management and expense approval',
119
+ capabilities: ['budget', 'cost_center', 'expense_approval'],
120
+ endpoint: 'http://localhost:4002/mcp',
121
+ });
122
+
123
+ // HR agent discovers who can help with budget fields
124
+ const discovery = new DiscoveryEngine();
125
+ const results = discovery.discover('budget cost center', registry);
126
+ // → [{ agent: finance-agent, score: 0.67, matchedTerms: ['budget', 'cost', 'center'] }]
127
+ ```
128
+
129
+ See [examples/](examples/) for a runnable demo.
130
+
131
+ ## Optional: Lore Integration
132
+
133
+ For semantic search beyond keyword matching, connect to a [Lore](https://github.com/openclaw/lore) server:
134
+
135
+ ```typescript
136
+ import { LoreDiscoveryEngine } from 'agentkit-mesh';
137
+
138
+ const engine = new LoreDiscoveryEngine('http://lore:8080', registry, 'api-key');
139
+ const results = await engine.discover('financial planning');
140
+ // Falls back to text matching if Lore is unavailable
141
+ ```
142
+
143
+ ## Programmatic API
144
+
145
+ ```typescript
146
+ import { AgentRegistry, DiscoveryEngine, DelegationClient, createServer } from 'agentkit-mesh';
147
+ ```
148
+
149
+ All classes are exported for direct use without the MCP server layer.
150
+
151
+ ## License
152
+
153
+ ISC
@@ -0,0 +1,11 @@
1
+ import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
2
+ export interface DelegationResult {
3
+ success: boolean;
4
+ result?: string;
5
+ error?: string;
6
+ latencyMs: number;
7
+ }
8
+ export declare class DelegationClient {
9
+ delegateViaTransport(transport: Transport, task: string, context?: Record<string, any>, timeout?: number): Promise<DelegationResult>;
10
+ delegate(targetEndpoint: string, task: string, context?: Record<string, any>, timeout?: number): Promise<DelegationResult>;
11
+ }
@@ -0,0 +1,61 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ const MAX_DEPTH = 3;
3
+ const DEFAULT_TIMEOUT = 60_000;
4
+ function withTimeout(promise, ms) {
5
+ return new Promise((resolve, reject) => {
6
+ const timer = setTimeout(() => reject(new Error(`Delegation timed out after ${ms}ms`)), ms);
7
+ promise.then(resolve, reject).finally(() => clearTimeout(timer));
8
+ });
9
+ }
10
+ export class DelegationClient {
11
+ async delegateViaTransport(transport, task, context, timeout) {
12
+ const depth = context?.depth ?? 0;
13
+ if (depth > MAX_DEPTH) {
14
+ return { success: false, error: `Delegation depth ${depth} exceeds max ${MAX_DEPTH}`, latencyMs: 0 };
15
+ }
16
+ const start = Date.now();
17
+ const client = new Client({ name: 'delegation-client', version: '0.1.0' });
18
+ try {
19
+ await client.connect(transport);
20
+ const nextContext = { ...context, depth: depth + 1 };
21
+ const response = await withTimeout(client.callTool({ name: 'handle_task', arguments: { task, context: nextContext } }), timeout ?? DEFAULT_TIMEOUT);
22
+ const text = response.content?.[0]?.text ?? '';
23
+ return { success: true, result: text, latencyMs: Date.now() - start };
24
+ }
25
+ catch (err) {
26
+ return { success: false, error: err.message ?? String(err), latencyMs: Date.now() - start };
27
+ }
28
+ finally {
29
+ try {
30
+ await client.close();
31
+ }
32
+ catch { }
33
+ }
34
+ }
35
+ async delegate(targetEndpoint, task, context, timeout) {
36
+ const depth = context?.depth ?? 0;
37
+ if (depth > MAX_DEPTH) {
38
+ return { success: false, error: `Delegation depth ${depth} exceeds max ${MAX_DEPTH}`, latencyMs: 0 };
39
+ }
40
+ const start = Date.now();
41
+ const client = new Client({ name: 'delegation-client', version: '0.1.0' });
42
+ try {
43
+ const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js');
44
+ const transport = new SSEClientTransport(new URL(targetEndpoint));
45
+ await client.connect(transport);
46
+ const nextContext = { ...context, depth: depth + 1 };
47
+ const response = await withTimeout(client.callTool({ name: 'handle_task', arguments: { task, context: nextContext } }), timeout ?? DEFAULT_TIMEOUT);
48
+ const text = response.content?.[0]?.text ?? '';
49
+ return { success: true, result: text, latencyMs: Date.now() - start };
50
+ }
51
+ catch (err) {
52
+ return { success: false, error: err.message ?? String(err), latencyMs: Date.now() - start };
53
+ }
54
+ finally {
55
+ try {
56
+ await client.close();
57
+ }
58
+ catch { }
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,13 @@
1
+ import { AgentRecord, AgentRegistry } from './registry.js';
2
+ export interface DiscoveryResult {
3
+ agent: AgentRecord;
4
+ score: number;
5
+ matchedTerms: string[];
6
+ }
7
+ export interface DiscoveryProvider {
8
+ discover(query: string, limit?: number): Promise<DiscoveryResult[]>;
9
+ }
10
+ export declare class DiscoveryEngine {
11
+ discover(query: string, registry: AgentRegistry, limit?: number): DiscoveryResult[];
12
+ private tokenize;
13
+ }
@@ -0,0 +1,36 @@
1
+ export class DiscoveryEngine {
2
+ discover(query, registry, limit) {
3
+ const tokens = this.tokenize(query);
4
+ if (tokens.length === 0)
5
+ return [];
6
+ const agents = registry.list();
7
+ const results = [];
8
+ for (const agent of agents) {
9
+ const searchText = [
10
+ agent.description.toLowerCase(),
11
+ ...agent.capabilities.map(c => c.toLowerCase()),
12
+ ].join(' ');
13
+ const matchedTerms = [];
14
+ for (const token of tokens) {
15
+ if (searchText.includes(token)) {
16
+ matchedTerms.push(token);
17
+ }
18
+ }
19
+ if (matchedTerms.length > 0) {
20
+ results.push({
21
+ agent,
22
+ score: matchedTerms.length / tokens.length,
23
+ matchedTerms,
24
+ });
25
+ }
26
+ }
27
+ results.sort((a, b) => b.score - a.score);
28
+ return limit ? results.slice(0, limit) : results;
29
+ }
30
+ tokenize(query) {
31
+ return query
32
+ .toLowerCase()
33
+ .split(/[\s\W]+/)
34
+ .filter(t => t.length > 0);
35
+ }
36
+ }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ export { AgentRegistry } from './registry.js';
3
+ export type { AgentRecord, RegisterInput } from './registry.js';
4
+ export { DiscoveryEngine } from './discovery.js';
5
+ export type { DiscoveryResult, DiscoveryProvider } from './discovery.js';
6
+ export { DelegationClient } from './delegation.js';
7
+ export type { DelegationResult } from './delegation.js';
8
+ export { createServer } from './server.js';
9
+ export { LoreDiscoveryEngine } from './lore-discovery.js';
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ export { AgentRegistry } from './registry.js';
3
+ export { DiscoveryEngine } from './discovery.js';
4
+ export { DelegationClient } from './delegation.js';
5
+ export { createServer } from './server.js';
6
+ export { LoreDiscoveryEngine } from './lore-discovery.js';
7
+ // CLI entry point: only start server when run directly via the bin script
8
+ const scriptPath = process.argv[1] ?? '';
9
+ const isDirectRun = scriptPath.endsWith('/agentkit-mesh') ||
10
+ scriptPath.endsWith('\\agentkit-mesh') ||
11
+ (scriptPath.endsWith('/index.js') && scriptPath.includes('agentkit-mesh'));
12
+ if (isDirectRun) {
13
+ const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
14
+ const { AgentRegistry: Registry } = await import('./registry.js');
15
+ const { createServer: create } = await import('./server.js');
16
+ const dbPath = process.argv[2] || undefined;
17
+ const registry = new Registry(dbPath);
18
+ const server = create(registry);
19
+ const transport = new StdioServerTransport();
20
+ await server.connect(transport);
21
+ process.on('SIGINT', () => { registry.close(); process.exit(0); });
22
+ process.on('SIGTERM', () => { registry.close(); process.exit(0); });
23
+ }
@@ -0,0 +1,12 @@
1
+ import { AgentRecord, AgentRegistry } from './registry.js';
2
+ import { DiscoveryResult, DiscoveryProvider } from './discovery.js';
3
+ export declare class LoreDiscoveryEngine implements DiscoveryProvider {
4
+ private loreUrl;
5
+ private loreApiKey?;
6
+ private registry;
7
+ private fallback;
8
+ constructor(loreUrl: string, registry: AgentRegistry, loreApiKey?: string);
9
+ discover(query: string, limit?: number): Promise<DiscoveryResult[]>;
10
+ private discoverViaLore;
11
+ publishCapabilities(agent: AgentRecord): Promise<boolean>;
12
+ }
@@ -0,0 +1,71 @@
1
+ import { DiscoveryEngine } from './discovery.js';
2
+ export class LoreDiscoveryEngine {
3
+ loreUrl;
4
+ loreApiKey;
5
+ registry;
6
+ fallback;
7
+ constructor(loreUrl, registry, loreApiKey) {
8
+ this.loreUrl = loreUrl.replace(/\/+$/, '');
9
+ this.loreApiKey = loreApiKey;
10
+ this.registry = registry;
11
+ this.fallback = new DiscoveryEngine();
12
+ }
13
+ async discover(query, limit) {
14
+ try {
15
+ return await this.discoverViaLore(query, limit);
16
+ }
17
+ catch {
18
+ // Fall back to text matching
19
+ return this.fallback.discover(query, this.registry, limit);
20
+ }
21
+ }
22
+ async discoverViaLore(query, limit) {
23
+ const headers = { 'Content-Type': 'application/json' };
24
+ if (this.loreApiKey) {
25
+ headers['Authorization'] = `Bearer ${this.loreApiKey}`;
26
+ }
27
+ const response = await fetch(`${this.loreUrl}/v1/lessons/search`, {
28
+ method: 'POST',
29
+ headers,
30
+ body: JSON.stringify({ query, limit: limit ?? 10 }),
31
+ });
32
+ if (!response.ok) {
33
+ throw new Error(`Lore API returned ${response.status}`);
34
+ }
35
+ const data = await response.json();
36
+ return data.lessons.map((lesson) => ({
37
+ agent: {
38
+ name: lesson.title,
39
+ description: lesson.content,
40
+ capabilities: lesson.tags ?? [],
41
+ endpoint: '',
42
+ protocol: 'mcp',
43
+ registered_at: '',
44
+ last_seen: '',
45
+ },
46
+ score: lesson.score ?? 0.5,
47
+ matchedTerms: lesson.tags ?? [],
48
+ }));
49
+ }
50
+ async publishCapabilities(agent) {
51
+ try {
52
+ const headers = { 'Content-Type': 'application/json' };
53
+ if (this.loreApiKey) {
54
+ headers['Authorization'] = `Bearer ${this.loreApiKey}`;
55
+ }
56
+ const response = await fetch(`${this.loreUrl}/v1/lessons`, {
57
+ method: 'POST',
58
+ headers,
59
+ body: JSON.stringify({
60
+ title: agent.name,
61
+ content: `${agent.description}. Capabilities: ${agent.capabilities.join(', ')}`,
62
+ tags: agent.capabilities,
63
+ }),
64
+ });
65
+ return response.ok;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,28 @@
1
+ export interface AgentRecord {
2
+ name: string;
3
+ description: string;
4
+ capabilities: string[];
5
+ endpoint: string;
6
+ protocol: string;
7
+ registered_at: string;
8
+ last_seen: string;
9
+ }
10
+ export interface RegisterInput {
11
+ name: string;
12
+ description: string;
13
+ capabilities: string[];
14
+ endpoint: string;
15
+ protocol?: string;
16
+ }
17
+ export declare class AgentRegistry {
18
+ private db;
19
+ constructor(dbPath?: string);
20
+ private initSchema;
21
+ register(agent: RegisterInput): AgentRecord;
22
+ unregister(name: string): boolean;
23
+ list(): AgentRecord[];
24
+ get(name: string): AgentRecord | null;
25
+ heartbeat(name: string): boolean;
26
+ close(): void;
27
+ private rowToRecord;
28
+ }
@@ -0,0 +1,80 @@
1
+ import Database from 'better-sqlite3';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import os from 'os';
5
+ export class AgentRegistry {
6
+ db;
7
+ constructor(dbPath) {
8
+ if (!dbPath) {
9
+ const dir = path.join(os.homedir(), '.agentkit-mesh');
10
+ fs.mkdirSync(dir, { recursive: true });
11
+ dbPath = path.join(dir, 'registry.db');
12
+ }
13
+ this.db = new Database(dbPath);
14
+ this.db.pragma('journal_mode = WAL');
15
+ this.initSchema();
16
+ }
17
+ initSchema() {
18
+ this.db.exec(`
19
+ CREATE TABLE IF NOT EXISTS agents (
20
+ name TEXT PRIMARY KEY,
21
+ description TEXT NOT NULL,
22
+ capabilities TEXT NOT NULL,
23
+ endpoint TEXT NOT NULL,
24
+ protocol TEXT NOT NULL DEFAULT 'mcp',
25
+ registered_at TEXT NOT NULL,
26
+ last_seen TEXT NOT NULL
27
+ )
28
+ `);
29
+ }
30
+ register(agent) {
31
+ if (!agent.name || agent.name.trim().length === 0) {
32
+ throw new Error('Agent name is required');
33
+ }
34
+ if (!agent.endpoint || agent.endpoint.trim().length === 0) {
35
+ throw new Error('Agent endpoint is required');
36
+ }
37
+ const now = new Date().toISOString();
38
+ const capabilities = JSON.stringify(agent.capabilities);
39
+ const protocol = agent.protocol ?? 'mcp';
40
+ this.db.prepare(`
41
+ INSERT INTO agents (name, description, capabilities, endpoint, protocol, registered_at, last_seen)
42
+ VALUES (?, ?, ?, ?, ?, ?, ?)
43
+ ON CONFLICT(name) DO UPDATE SET
44
+ description = excluded.description,
45
+ capabilities = excluded.capabilities,
46
+ endpoint = excluded.endpoint,
47
+ protocol = excluded.protocol,
48
+ last_seen = excluded.last_seen
49
+ `).run(agent.name, agent.description, capabilities, agent.endpoint, protocol, now, now);
50
+ return this.get(agent.name);
51
+ }
52
+ unregister(name) {
53
+ const result = this.db.prepare('DELETE FROM agents WHERE name = ?').run(name);
54
+ return result.changes > 0;
55
+ }
56
+ list() {
57
+ const rows = this.db.prepare('SELECT * FROM agents ORDER BY name').all();
58
+ return rows.map(r => this.rowToRecord(r));
59
+ }
60
+ get(name) {
61
+ const row = this.db.prepare('SELECT * FROM agents WHERE name = ?').get(name);
62
+ if (!row)
63
+ return null;
64
+ return this.rowToRecord(row);
65
+ }
66
+ heartbeat(name) {
67
+ const now = new Date().toISOString();
68
+ const result = this.db.prepare('UPDATE agents SET last_seen = ? WHERE name = ?').run(now, name);
69
+ return result.changes > 0;
70
+ }
71
+ close() {
72
+ this.db.close();
73
+ }
74
+ rowToRecord(row) {
75
+ return {
76
+ ...row,
77
+ capabilities: JSON.parse(row.capabilities),
78
+ };
79
+ }
80
+ }
@@ -0,0 +1,3 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { AgentRegistry } from './registry.js';
3
+ export declare function createServer(registry: AgentRegistry): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,58 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import { DiscoveryEngine } from './discovery.js';
4
+ import { DelegationClient } from './delegation.js';
5
+ export function createServer(registry) {
6
+ const server = new McpServer({
7
+ name: 'agentkit-mesh',
8
+ version: '0.1.0',
9
+ });
10
+ const discovery = new DiscoveryEngine();
11
+ server.tool('mesh_register', 'Register an agent with its capabilities', {
12
+ name: z.string().describe('Unique agent name'),
13
+ description: z.string().describe('What this agent does'),
14
+ capabilities: z.array(z.string()).describe('List of capabilities'),
15
+ endpoint: z.string().describe('Agent endpoint URL'),
16
+ }, async ({ name, description, capabilities, endpoint }) => {
17
+ const agent = registry.register({ name, description, capabilities, endpoint });
18
+ return { content: [{ type: 'text', text: JSON.stringify(agent, null, 2) }] };
19
+ });
20
+ server.tool('mesh_discover', 'Discover agents matching a query', {
21
+ query: z.string().describe('Search query'),
22
+ limit: z.number().optional().describe('Max results'),
23
+ }, async ({ query, limit }) => {
24
+ const results = discovery.discover(query, registry, limit);
25
+ return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] };
26
+ });
27
+ server.tool('mesh_unregister', 'Unregister an agent', {
28
+ name: z.string().describe('Agent name to remove'),
29
+ }, async ({ name }) => {
30
+ const removed = registry.unregister(name);
31
+ return {
32
+ content: [{ type: 'text', text: removed ? `Unregistered ${name}` : `Agent ${name} not found` }],
33
+ };
34
+ });
35
+ const delegationClient = new DelegationClient();
36
+ server.tool('mesh_delegate', 'Delegate a task to another agent by name', {
37
+ targetName: z.string().describe('Name of the target agent'),
38
+ task: z.string().describe('Task to delegate'),
39
+ context: z.string().optional().describe('Optional JSON context'),
40
+ }, async ({ targetName, task, context }) => {
41
+ const agent = registry.get(targetName);
42
+ if (!agent) {
43
+ return { content: [{ type: 'text', text: `Agent "${targetName}" not found` }] };
44
+ }
45
+ let ctx = {};
46
+ if (context) {
47
+ try {
48
+ ctx = JSON.parse(context);
49
+ }
50
+ catch {
51
+ return { content: [{ type: 'text', text: `Invalid JSON in context` }] };
52
+ }
53
+ }
54
+ const result = await delegationClient.delegate(agent.endpoint, task, ctx);
55
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
56
+ });
57
+ return server;
58
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "agentkit-mesh",
3
+ "version": "1.0.0",
4
+ "description": "Agent-to-agent discovery and delegation via MCP (Model Context Protocol)",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/openclaw/agentkit-mesh"
20
+ },
21
+ "scripts": {
22
+ "test": "vitest run",
23
+ "build": "tsc"
24
+ },
25
+ "keywords": [],
26
+ "author": "",
27
+ "license": "ISC",
28
+ "type": "module",
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.26.0",
31
+ "better-sqlite3": "^12.6.2",
32
+ "zod": "^4.3.6"
33
+ },
34
+ "devDependencies": {
35
+ "@types/better-sqlite3": "^7.6.13",
36
+ "tsx": "^4.21.0",
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^4.0.18"
39
+ },
40
+ "bin": {
41
+ "agentkit-mesh": "./dist/index.js"
42
+ }
43
+ }