@agentforge-ai/core 0.1.0 → 0.2.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/dist/agent.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  import { LanguageModelV1 } from 'ai';
2
+ import { MCPServer } from './mcp-server.js';
3
+ import 'zod';
2
4
 
5
+ /**
6
+ * Supported model types for AgentForge agents.
7
+ *
8
+ * - `LanguageModelV1`: Any AI SDK v4 model instance (e.g., `openai('gpt-4o')`)
9
+ * - `string`: A Mastra model router ID (e.g., `'openai/gpt-4o'`)
10
+ */
11
+ type AgentModel = LanguageModelV1 | string;
3
12
  /**
4
13
  * Configuration for creating an AgentForge Agent.
5
14
  */
@@ -11,21 +20,30 @@ interface AgentConfig {
11
20
  /** The system prompt or instructions for the agent. */
12
21
  instructions: string;
13
22
  /**
14
- * The language model to use. Pass a LanguageModelV1 instance
15
- * (e.g., from `@ai-sdk/openai`, `@ai-sdk/anthropic`, etc.).
23
+ * The language model to use. Accepts either:
24
+ * - A `LanguageModelV1` instance (e.g., from `@ai-sdk/openai`)
25
+ * - A string model ID (e.g., `'openai/gpt-4o'`)
16
26
  *
17
27
  * @example
18
28
  * ```typescript
19
29
  * import { openai } from '@ai-sdk/openai';
30
+ *
31
+ * // Using an AI SDK model instance (BYOK)
20
32
  * const agent = new Agent({
21
33
  * model: openai('gpt-4o-mini'),
22
34
  * // ...
23
35
  * });
36
+ *
37
+ * // Using a Mastra model router string
38
+ * const agent = new Agent({
39
+ * model: 'openai/gpt-4o-mini',
40
+ * // ...
41
+ * });
24
42
  * ```
25
43
  */
26
- model: LanguageModelV1;
27
- /** A dictionary of tools available to the agent. */
28
- tools?: Record<string, unknown>;
44
+ model: AgentModel;
45
+ /** An MCPServer instance providing tools for the agent. */
46
+ tools?: MCPServer;
29
47
  }
30
48
  /**
31
49
  * Represents a structured response from an agent generation call.
@@ -48,19 +66,33 @@ interface StreamChunk {
48
66
  *
49
67
  * Wraps the Mastra Agent to provide a simplified, curated API for
50
68
  * creating and interacting with AI agents. Supports any AI SDK-compatible
51
- * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key).
69
+ * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key),
70
+ * or Mastra model router string IDs.
71
+ *
72
+ * Tools can be provided at construction time via the `tools` config option,
73
+ * or added dynamically after construction using the `addTools()` method.
52
74
  *
53
75
  * @example
54
76
  * ```typescript
55
77
  * import { openai } from '@ai-sdk/openai';
78
+ * import { Agent, MCPServer } from '@agentforge-ai/core';
79
+ *
80
+ * const tools = new MCPServer();
81
+ * tools.registerTool({ ... });
56
82
  *
57
83
  * const agent = new Agent({
58
84
  * id: 'my-agent',
59
85
  * name: 'My Agent',
60
86
  * instructions: 'You are a helpful assistant.',
61
87
  * model: openai('gpt-4o-mini'),
88
+ * tools: tools,
62
89
  * });
63
90
  *
91
+ * // Or add tools dynamically:
92
+ * const moreTools = new MCPServer();
93
+ * moreTools.registerTool({ ... });
94
+ * agent.addTools(moreTools);
95
+ *
64
96
  * const response = await agent.generate('Hello!');
65
97
  * ```
66
98
  */
@@ -69,13 +101,71 @@ declare class Agent {
69
101
  readonly id: string;
70
102
  /** The agent's human-readable name. */
71
103
  readonly name: string;
104
+ /** The agent's instructions (system prompt). */
105
+ readonly instructions: string;
106
+ /** The agent's model configuration. */
107
+ readonly model: AgentModel;
72
108
  /** The underlying Mastra agent instance. */
73
109
  private mastraAgent;
110
+ /** The collection of MCP servers providing tools to this agent. */
111
+ private toolServers;
74
112
  /**
75
113
  * Creates a new AgentForge Agent.
76
114
  * @param config - The configuration for the agent.
77
115
  */
78
116
  constructor(config: AgentConfig);
117
+ /**
118
+ * Dynamically adds tools from an MCPServer to this agent.
119
+ *
120
+ * This method allows you to extend an agent's capabilities after construction.
121
+ * Multiple MCPServer instances can be added, and their tools are merged together.
122
+ * The underlying Mastra agent is rebuilt to include the new tools.
123
+ *
124
+ * @param server - An MCPServer instance containing the tools to add.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const agent = new Agent({ id: 'a', name: 'A', instructions: '...', model: 'openai/gpt-4o' });
129
+ *
130
+ * const financialTools = new MCPServer();
131
+ * financialTools.registerTool({ name: 'get_stock_price', ... });
132
+ * agent.addTools(financialTools);
133
+ *
134
+ * const adminTools = new MCPServer();
135
+ * adminTools.registerTool({ name: 'delete_user', ... });
136
+ * agent.addTools(adminTools);
137
+ *
138
+ * // Agent now has both get_stock_price and delete_user tools
139
+ * const tools = agent.getTools();
140
+ * ```
141
+ */
142
+ addTools(server: MCPServer): void;
143
+ /**
144
+ * Removes all tools from this agent.
145
+ *
146
+ * Clears all registered MCPServer instances and rebuilds the underlying
147
+ * Mastra agent without any tools.
148
+ */
149
+ clearTools(): void;
150
+ /**
151
+ * Returns a flat list of all tool schemas registered across all MCPServer instances.
152
+ *
153
+ * @returns An array of tool schema descriptors from all attached MCPServers.
154
+ */
155
+ getTools(): ReturnType<MCPServer['listTools']>;
156
+ /**
157
+ * Invokes a tool by name across all attached MCPServer instances.
158
+ *
159
+ * Searches through all registered MCPServers for the named tool and
160
+ * invokes it with the provided input. Throws if the tool is not found
161
+ * in any server.
162
+ *
163
+ * @param toolName - The name of the tool to invoke.
164
+ * @param input - The input to pass to the tool.
165
+ * @returns A promise that resolves with the tool's output.
166
+ * @throws {Error} If the tool is not found in any attached MCPServer.
167
+ */
168
+ callTool(toolName: string, input: unknown): Promise<unknown>;
79
169
  /**
80
170
  * Generates a structured response from the agent.
81
171
  * @param prompt - The user's prompt or input.
@@ -88,6 +178,16 @@ declare class Agent {
88
178
  * @returns An async iterable that yields response chunks.
89
179
  */
90
180
  stream(prompt: string): AsyncGenerator<StreamChunk>;
181
+ /**
182
+ * Builds (or rebuilds) the underlying Mastra agent from the current configuration.
183
+ * Called on construction and whenever tools are added or cleared.
184
+ */
185
+ private buildMastraAgent;
186
+ /**
187
+ * Merges tools from all attached MCPServer instances into a single record
188
+ * suitable for passing to the Mastra agent constructor.
189
+ */
190
+ private buildToolsRecord;
91
191
  }
92
192
 
93
- export { Agent, type AgentConfig, type AgentResponse, type StreamChunk };
193
+ export { Agent, type AgentConfig, type AgentModel, type AgentResponse, type StreamChunk };
package/dist/agent.js CHANGED
@@ -5,8 +5,14 @@ var Agent = class {
5
5
  id;
6
6
  /** The agent's human-readable name. */
7
7
  name;
8
+ /** The agent's instructions (system prompt). */
9
+ instructions;
10
+ /** The agent's model configuration. */
11
+ model;
8
12
  /** The underlying Mastra agent instance. */
9
13
  mastraAgent;
14
+ /** The collection of MCP servers providing tools to this agent. */
15
+ toolServers = [];
10
16
  /**
11
17
  * Creates a new AgentForge Agent.
12
18
  * @param config - The configuration for the agent.
@@ -14,12 +20,80 @@ var Agent = class {
14
20
  constructor(config) {
15
21
  this.id = config.id;
16
22
  this.name = config.name;
17
- this.mastraAgent = new MastraAgent({
18
- name: config.name,
19
- instructions: config.instructions,
20
- model: config.model,
21
- ...config.tools ? { tools: config.tools } : {}
22
- });
23
+ this.instructions = config.instructions;
24
+ this.model = config.model;
25
+ if (config.tools) {
26
+ this.toolServers.push(config.tools);
27
+ }
28
+ this.mastraAgent = this.buildMastraAgent();
29
+ }
30
+ /**
31
+ * Dynamically adds tools from an MCPServer to this agent.
32
+ *
33
+ * This method allows you to extend an agent's capabilities after construction.
34
+ * Multiple MCPServer instances can be added, and their tools are merged together.
35
+ * The underlying Mastra agent is rebuilt to include the new tools.
36
+ *
37
+ * @param server - An MCPServer instance containing the tools to add.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const agent = new Agent({ id: 'a', name: 'A', instructions: '...', model: 'openai/gpt-4o' });
42
+ *
43
+ * const financialTools = new MCPServer();
44
+ * financialTools.registerTool({ name: 'get_stock_price', ... });
45
+ * agent.addTools(financialTools);
46
+ *
47
+ * const adminTools = new MCPServer();
48
+ * adminTools.registerTool({ name: 'delete_user', ... });
49
+ * agent.addTools(adminTools);
50
+ *
51
+ * // Agent now has both get_stock_price and delete_user tools
52
+ * const tools = agent.getTools();
53
+ * ```
54
+ */
55
+ addTools(server) {
56
+ this.toolServers.push(server);
57
+ this.mastraAgent = this.buildMastraAgent();
58
+ }
59
+ /**
60
+ * Removes all tools from this agent.
61
+ *
62
+ * Clears all registered MCPServer instances and rebuilds the underlying
63
+ * Mastra agent without any tools.
64
+ */
65
+ clearTools() {
66
+ this.toolServers = [];
67
+ this.mastraAgent = this.buildMastraAgent();
68
+ }
69
+ /**
70
+ * Returns a flat list of all tool schemas registered across all MCPServer instances.
71
+ *
72
+ * @returns An array of tool schema descriptors from all attached MCPServers.
73
+ */
74
+ getTools() {
75
+ return this.toolServers.flatMap((server) => server.listTools());
76
+ }
77
+ /**
78
+ * Invokes a tool by name across all attached MCPServer instances.
79
+ *
80
+ * Searches through all registered MCPServers for the named tool and
81
+ * invokes it with the provided input. Throws if the tool is not found
82
+ * in any server.
83
+ *
84
+ * @param toolName - The name of the tool to invoke.
85
+ * @param input - The input to pass to the tool.
86
+ * @returns A promise that resolves with the tool's output.
87
+ * @throws {Error} If the tool is not found in any attached MCPServer.
88
+ */
89
+ async callTool(toolName, input) {
90
+ for (const server of this.toolServers) {
91
+ const toolList = server.listTools();
92
+ if (toolList.some((t) => t.name === toolName)) {
93
+ return server.callTool(toolName, input);
94
+ }
95
+ }
96
+ throw new Error(`Tool '${toolName}' not found in any attached MCPServer.`);
23
97
  }
24
98
  /**
25
99
  * Generates a structured response from the agent.
@@ -41,6 +115,33 @@ var Agent = class {
41
115
  yield { content: typeof chunk === "string" ? chunk : String(chunk) };
42
116
  }
43
117
  }
118
+ /**
119
+ * Builds (or rebuilds) the underlying Mastra agent from the current configuration.
120
+ * Called on construction and whenever tools are added or cleared.
121
+ */
122
+ buildMastraAgent() {
123
+ const toolsRecord = this.buildToolsRecord();
124
+ return new MastraAgent({
125
+ id: this.id,
126
+ name: this.name,
127
+ instructions: this.instructions,
128
+ model: this.model,
129
+ ...Object.keys(toolsRecord).length > 0 ? { tools: toolsRecord } : {}
130
+ });
131
+ }
132
+ /**
133
+ * Merges tools from all attached MCPServer instances into a single record
134
+ * suitable for passing to the Mastra agent constructor.
135
+ */
136
+ buildToolsRecord() {
137
+ const record = {};
138
+ for (const server of this.toolServers) {
139
+ for (const tool of server.listTools()) {
140
+ record[tool.name] = tool;
141
+ }
142
+ }
143
+ return record;
144
+ }
44
145
  };
45
146
  export {
46
147
  Agent
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent.ts"],"sourcesContent":["import { Agent as MastraAgent } from '@mastra/core/agent';\nimport type { LanguageModelV1 } from 'ai';\n\n/**\n * Configuration for creating an AgentForge Agent.\n */\nexport interface AgentConfig {\n /** A unique identifier for the agent. */\n id: string;\n /** A human-readable name for the agent. */\n name: string;\n /** The system prompt or instructions for the agent. */\n instructions: string;\n /**\n * The language model to use. Pass a LanguageModelV1 instance\n * (e.g., from `@ai-sdk/openai`, `@ai-sdk/anthropic`, etc.).\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n * const agent = new Agent({\n * model: openai('gpt-4o-mini'),\n * // ...\n * });\n * ```\n */\n model: LanguageModelV1;\n /** A dictionary of tools available to the agent. */\n tools?: Record<string, unknown>;\n}\n\n/**\n * Represents a structured response from an agent generation call.\n */\nexport interface AgentResponse {\n /** The text content of the response. */\n text: string;\n /** Optional tool call results. */\n toolResults?: unknown[];\n}\n\n/**\n * Represents a single chunk in a streaming response.\n */\nexport interface StreamChunk {\n /** The text content of this chunk. */\n content: string;\n}\n\n/**\n * The core Agent class for the AgentForge framework.\n *\n * Wraps the Mastra Agent to provide a simplified, curated API for\n * creating and interacting with AI agents. Supports any AI SDK-compatible\n * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key).\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant.',\n * model: openai('gpt-4o-mini'),\n * });\n *\n * const response = await agent.generate('Hello!');\n * ```\n */\nexport class Agent {\n /** The agent's unique ID. */\n public readonly id: string;\n\n /** The agent's human-readable name. */\n public readonly name: string;\n\n /** The underlying Mastra agent instance. */\n private mastraAgent: MastraAgent;\n\n /**\n * Creates a new AgentForge Agent.\n * @param config - The configuration for the agent.\n */\n constructor(config: AgentConfig) {\n this.id = config.id;\n this.name = config.name;\n\n this.mastraAgent = new MastraAgent({\n name: config.name,\n instructions: config.instructions,\n model: config.model,\n ...(config.tools ? { tools: config.tools as Record<string, never> } : {}),\n });\n }\n\n /**\n * Generates a structured response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns A promise that resolves to the agent's response.\n */\n async generate(prompt: string): Promise<AgentResponse> {\n const result = await this.mastraAgent.generate(prompt);\n return result as unknown as AgentResponse;\n }\n\n /**\n * Generates a streaming response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns An async iterable that yields response chunks.\n */\n async *stream(prompt: string): AsyncGenerator<StreamChunk> {\n const result = await this.mastraAgent.stream(prompt);\n for await (const chunk of result.textStream) {\n yield { content: typeof chunk === 'string' ? chunk : String(chunk) };\n }\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS,mBAAmB;AAsE9B,IAAM,QAAN,MAAY;AAAA;AAAA,EAED;AAAA;AAAA,EAGA;AAAA;AAAA,EAGR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,YAAY,QAAqB;AAC/B,SAAK,KAAK,OAAO;AACjB,SAAK,OAAO,OAAO;AAEnB,SAAK,cAAc,IAAI,YAAY;AAAA,MACjC,MAAM,OAAO;AAAA,MACb,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,MACd,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAA+B,IAAI,CAAC;AAAA,IACzE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,QAAwC;AACrD,UAAM,SAAS,MAAM,KAAK,YAAY,SAAS,MAAM;AACrD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OAAO,QAA6C;AACzD,UAAM,SAAS,MAAM,KAAK,YAAY,OAAO,MAAM;AACnD,qBAAiB,SAAS,OAAO,YAAY;AAC3C,YAAM,EAAE,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK,EAAE;AAAA,IACrE;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/agent.ts"],"sourcesContent":["import { Agent as MastraAgent } from '@mastra/core/agent';\nimport type { LanguageModelV1 } from 'ai';\nimport type { MCPServer } from './mcp-server.js';\n\n/**\n * Supported model types for AgentForge agents.\n *\n * - `LanguageModelV1`: Any AI SDK v4 model instance (e.g., `openai('gpt-4o')`)\n * - `string`: A Mastra model router ID (e.g., `'openai/gpt-4o'`)\n */\nexport type AgentModel = LanguageModelV1 | string;\n\n/**\n * Configuration for creating an AgentForge Agent.\n */\nexport interface AgentConfig {\n /** A unique identifier for the agent. */\n id: string;\n /** A human-readable name for the agent. */\n name: string;\n /** The system prompt or instructions for the agent. */\n instructions: string;\n /**\n * The language model to use. Accepts either:\n * - A `LanguageModelV1` instance (e.g., from `@ai-sdk/openai`)\n * - A string model ID (e.g., `'openai/gpt-4o'`)\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n *\n * // Using an AI SDK model instance (BYOK)\n * const agent = new Agent({\n * model: openai('gpt-4o-mini'),\n * // ...\n * });\n *\n * // Using a Mastra model router string\n * const agent = new Agent({\n * model: 'openai/gpt-4o-mini',\n * // ...\n * });\n * ```\n */\n model: AgentModel;\n /** An MCPServer instance providing tools for the agent. */\n tools?: MCPServer;\n}\n\n/**\n * Represents a structured response from an agent generation call.\n */\nexport interface AgentResponse {\n /** The text content of the response. */\n text: string;\n /** Optional tool call results. */\n toolResults?: unknown[];\n}\n\n/**\n * Represents a single chunk in a streaming response.\n */\nexport interface StreamChunk {\n /** The text content of this chunk. */\n content: string;\n}\n\n/**\n * The core Agent class for the AgentForge framework.\n *\n * Wraps the Mastra Agent to provide a simplified, curated API for\n * creating and interacting with AI agents. Supports any AI SDK-compatible\n * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key),\n * or Mastra model router string IDs.\n *\n * Tools can be provided at construction time via the `tools` config option,\n * or added dynamically after construction using the `addTools()` method.\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n * import { Agent, MCPServer } from '@agentforge-ai/core';\n *\n * const tools = new MCPServer();\n * tools.registerTool({ ... });\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant.',\n * model: openai('gpt-4o-mini'),\n * tools: tools,\n * });\n *\n * // Or add tools dynamically:\n * const moreTools = new MCPServer();\n * moreTools.registerTool({ ... });\n * agent.addTools(moreTools);\n *\n * const response = await agent.generate('Hello!');\n * ```\n */\nexport class Agent {\n /** The agent's unique ID. */\n public readonly id: string;\n\n /** The agent's human-readable name. */\n public readonly name: string;\n\n /** The agent's instructions (system prompt). */\n public readonly instructions: string;\n\n /** The agent's model configuration. */\n public readonly model: AgentModel;\n\n /** The underlying Mastra agent instance. */\n private mastraAgent: MastraAgent;\n\n /** The collection of MCP servers providing tools to this agent. */\n private toolServers: MCPServer[] = [];\n\n /**\n * Creates a new AgentForge Agent.\n * @param config - The configuration for the agent.\n */\n constructor(config: AgentConfig) {\n this.id = config.id;\n this.name = config.name;\n this.instructions = config.instructions;\n this.model = config.model;\n\n if (config.tools) {\n this.toolServers.push(config.tools);\n }\n\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Dynamically adds tools from an MCPServer to this agent.\n *\n * This method allows you to extend an agent's capabilities after construction.\n * Multiple MCPServer instances can be added, and their tools are merged together.\n * The underlying Mastra agent is rebuilt to include the new tools.\n *\n * @param server - An MCPServer instance containing the tools to add.\n *\n * @example\n * ```typescript\n * const agent = new Agent({ id: 'a', name: 'A', instructions: '...', model: 'openai/gpt-4o' });\n *\n * const financialTools = new MCPServer();\n * financialTools.registerTool({ name: 'get_stock_price', ... });\n * agent.addTools(financialTools);\n *\n * const adminTools = new MCPServer();\n * adminTools.registerTool({ name: 'delete_user', ... });\n * agent.addTools(adminTools);\n *\n * // Agent now has both get_stock_price and delete_user tools\n * const tools = agent.getTools();\n * ```\n */\n addTools(server: MCPServer): void {\n this.toolServers.push(server);\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Removes all tools from this agent.\n *\n * Clears all registered MCPServer instances and rebuilds the underlying\n * Mastra agent without any tools.\n */\n clearTools(): void {\n this.toolServers = [];\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Returns a flat list of all tool schemas registered across all MCPServer instances.\n *\n * @returns An array of tool schema descriptors from all attached MCPServers.\n */\n getTools(): ReturnType<MCPServer['listTools']> {\n return this.toolServers.flatMap((server) => server.listTools());\n }\n\n /**\n * Invokes a tool by name across all attached MCPServer instances.\n *\n * Searches through all registered MCPServers for the named tool and\n * invokes it with the provided input. Throws if the tool is not found\n * in any server.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to pass to the tool.\n * @returns A promise that resolves with the tool's output.\n * @throws {Error} If the tool is not found in any attached MCPServer.\n */\n async callTool(toolName: string, input: unknown): Promise<unknown> {\n for (const server of this.toolServers) {\n const toolList = server.listTools();\n if (toolList.some((t) => t.name === toolName)) {\n return server.callTool(toolName, input);\n }\n }\n throw new Error(`Tool '${toolName}' not found in any attached MCPServer.`);\n }\n\n /**\n * Generates a structured response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns A promise that resolves to the agent's response.\n */\n async generate(prompt: string): Promise<AgentResponse> {\n const result = await this.mastraAgent.generate(prompt);\n return result as unknown as AgentResponse;\n }\n\n /**\n * Generates a streaming response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns An async iterable that yields response chunks.\n */\n async *stream(prompt: string): AsyncGenerator<StreamChunk> {\n const result = await this.mastraAgent.stream(prompt);\n for await (const chunk of result.textStream) {\n yield { content: typeof chunk === 'string' ? chunk : String(chunk) };\n }\n }\n\n /**\n * Builds (or rebuilds) the underlying Mastra agent from the current configuration.\n * Called on construction and whenever tools are added or cleared.\n */\n private buildMastraAgent(): MastraAgent {\n const toolsRecord = this.buildToolsRecord();\n\n return new MastraAgent({\n id: this.id,\n name: this.name,\n instructions: this.instructions,\n model: this.model as Parameters<typeof MastraAgent.prototype.generate>[0] extends { model?: infer M } ? M : never,\n ...(Object.keys(toolsRecord).length > 0 ? { tools: toolsRecord as Record<string, never> } : {}),\n });\n }\n\n /**\n * Merges tools from all attached MCPServer instances into a single record\n * suitable for passing to the Mastra agent constructor.\n */\n private buildToolsRecord(): Record<string, unknown> {\n const record: Record<string, unknown> = {};\n for (const server of this.toolServers) {\n for (const tool of server.listTools()) {\n record[tool.name] = tool;\n }\n }\n return record;\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS,mBAAmB;AAsG9B,IAAM,QAAN,MAAY;AAAA;AAAA,EAED;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGR;AAAA;AAAA,EAGA,cAA2B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpC,YAAY,QAAqB;AAC/B,SAAK,KAAK,OAAO;AACjB,SAAK,OAAO,OAAO;AACnB,SAAK,eAAe,OAAO;AAC3B,SAAK,QAAQ,OAAO;AAEpB,QAAI,OAAO,OAAO;AAChB,WAAK,YAAY,KAAK,OAAO,KAAK;AAAA,IACpC;AAEA,SAAK,cAAc,KAAK,iBAAiB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,SAAS,QAAyB;AAChC,SAAK,YAAY,KAAK,MAAM;AAC5B,SAAK,cAAc,KAAK,iBAAiB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAmB;AACjB,SAAK,cAAc,CAAC;AACpB,SAAK,cAAc,KAAK,iBAAiB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAA+C;AAC7C,WAAO,KAAK,YAAY,QAAQ,CAAC,WAAW,OAAO,UAAU,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,SAAS,UAAkB,OAAkC;AACjE,eAAW,UAAU,KAAK,aAAa;AACrC,YAAM,WAAW,OAAO,UAAU;AAClC,UAAI,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,GAAG;AAC7C,eAAO,OAAO,SAAS,UAAU,KAAK;AAAA,MACxC;AAAA,IACF;AACA,UAAM,IAAI,MAAM,SAAS,QAAQ,wCAAwC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,QAAwC;AACrD,UAAM,SAAS,MAAM,KAAK,YAAY,SAAS,MAAM;AACrD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OAAO,QAA6C;AACzD,UAAM,SAAS,MAAM,KAAK,YAAY,OAAO,MAAM;AACnD,qBAAiB,SAAS,OAAO,YAAY;AAC3C,YAAM,EAAE,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK,EAAE;AAAA,IACrE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAgC;AACtC,UAAM,cAAc,KAAK,iBAAiB;AAE1C,WAAO,IAAI,YAAY;AAAA,MACrB,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,cAAc,KAAK;AAAA,MACnB,OAAO,KAAK;AAAA,MACZ,GAAI,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,EAAE,OAAO,YAAqC,IAAI,CAAC;AAAA,IAC/F,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAA4C;AAClD,UAAM,SAAkC,CAAC;AACzC,eAAW,UAAU,KAAK,aAAa;AACrC,iBAAW,QAAQ,OAAO,UAAU,GAAG;AACrC,eAAO,KAAK,IAAI,IAAI;AAAA,MACtB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { Agent, AgentConfig, AgentResponse, StreamChunk } from './agent.js';
1
+ export { Agent, AgentConfig, AgentModel, AgentResponse, StreamChunk } from './agent.js';
2
2
  export { SandboxConfig, SandboxExecutionError, SandboxManager, SandboxResult, SandboxRunOptions, TimeoutError } from './sandbox.js';
3
- export { MCPServer, Tool, ToolSchema } from './mcp-server.js';
3
+ export { MCPServer, MCPServerConfig, Tool, ToolSchema } from './mcp-server.js';
4
4
  import 'ai';
5
5
  import 'zod';
package/dist/index.js CHANGED
@@ -5,8 +5,14 @@ var Agent = class {
5
5
  id;
6
6
  /** The agent's human-readable name. */
7
7
  name;
8
+ /** The agent's instructions (system prompt). */
9
+ instructions;
10
+ /** The agent's model configuration. */
11
+ model;
8
12
  /** The underlying Mastra agent instance. */
9
13
  mastraAgent;
14
+ /** The collection of MCP servers providing tools to this agent. */
15
+ toolServers = [];
10
16
  /**
11
17
  * Creates a new AgentForge Agent.
12
18
  * @param config - The configuration for the agent.
@@ -14,12 +20,80 @@ var Agent = class {
14
20
  constructor(config) {
15
21
  this.id = config.id;
16
22
  this.name = config.name;
17
- this.mastraAgent = new MastraAgent({
18
- name: config.name,
19
- instructions: config.instructions,
20
- model: config.model,
21
- ...config.tools ? { tools: config.tools } : {}
22
- });
23
+ this.instructions = config.instructions;
24
+ this.model = config.model;
25
+ if (config.tools) {
26
+ this.toolServers.push(config.tools);
27
+ }
28
+ this.mastraAgent = this.buildMastraAgent();
29
+ }
30
+ /**
31
+ * Dynamically adds tools from an MCPServer to this agent.
32
+ *
33
+ * This method allows you to extend an agent's capabilities after construction.
34
+ * Multiple MCPServer instances can be added, and their tools are merged together.
35
+ * The underlying Mastra agent is rebuilt to include the new tools.
36
+ *
37
+ * @param server - An MCPServer instance containing the tools to add.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const agent = new Agent({ id: 'a', name: 'A', instructions: '...', model: 'openai/gpt-4o' });
42
+ *
43
+ * const financialTools = new MCPServer();
44
+ * financialTools.registerTool({ name: 'get_stock_price', ... });
45
+ * agent.addTools(financialTools);
46
+ *
47
+ * const adminTools = new MCPServer();
48
+ * adminTools.registerTool({ name: 'delete_user', ... });
49
+ * agent.addTools(adminTools);
50
+ *
51
+ * // Agent now has both get_stock_price and delete_user tools
52
+ * const tools = agent.getTools();
53
+ * ```
54
+ */
55
+ addTools(server) {
56
+ this.toolServers.push(server);
57
+ this.mastraAgent = this.buildMastraAgent();
58
+ }
59
+ /**
60
+ * Removes all tools from this agent.
61
+ *
62
+ * Clears all registered MCPServer instances and rebuilds the underlying
63
+ * Mastra agent without any tools.
64
+ */
65
+ clearTools() {
66
+ this.toolServers = [];
67
+ this.mastraAgent = this.buildMastraAgent();
68
+ }
69
+ /**
70
+ * Returns a flat list of all tool schemas registered across all MCPServer instances.
71
+ *
72
+ * @returns An array of tool schema descriptors from all attached MCPServers.
73
+ */
74
+ getTools() {
75
+ return this.toolServers.flatMap((server) => server.listTools());
76
+ }
77
+ /**
78
+ * Invokes a tool by name across all attached MCPServer instances.
79
+ *
80
+ * Searches through all registered MCPServers for the named tool and
81
+ * invokes it with the provided input. Throws if the tool is not found
82
+ * in any server.
83
+ *
84
+ * @param toolName - The name of the tool to invoke.
85
+ * @param input - The input to pass to the tool.
86
+ * @returns A promise that resolves with the tool's output.
87
+ * @throws {Error} If the tool is not found in any attached MCPServer.
88
+ */
89
+ async callTool(toolName, input) {
90
+ for (const server of this.toolServers) {
91
+ const toolList = server.listTools();
92
+ if (toolList.some((t) => t.name === toolName)) {
93
+ return server.callTool(toolName, input);
94
+ }
95
+ }
96
+ throw new Error(`Tool '${toolName}' not found in any attached MCPServer.`);
23
97
  }
24
98
  /**
25
99
  * Generates a structured response from the agent.
@@ -41,6 +115,33 @@ var Agent = class {
41
115
  yield { content: typeof chunk === "string" ? chunk : String(chunk) };
42
116
  }
43
117
  }
118
+ /**
119
+ * Builds (or rebuilds) the underlying Mastra agent from the current configuration.
120
+ * Called on construction and whenever tools are added or cleared.
121
+ */
122
+ buildMastraAgent() {
123
+ const toolsRecord = this.buildToolsRecord();
124
+ return new MastraAgent({
125
+ id: this.id,
126
+ name: this.name,
127
+ instructions: this.instructions,
128
+ model: this.model,
129
+ ...Object.keys(toolsRecord).length > 0 ? { tools: toolsRecord } : {}
130
+ });
131
+ }
132
+ /**
133
+ * Merges tools from all attached MCPServer instances into a single record
134
+ * suitable for passing to the Mastra agent constructor.
135
+ */
136
+ buildToolsRecord() {
137
+ const record = {};
138
+ for (const server of this.toolServers) {
139
+ for (const tool of server.listTools()) {
140
+ record[tool.name] = tool;
141
+ }
142
+ }
143
+ return record;
144
+ }
44
145
  };
45
146
 
46
147
  // src/sandbox.ts
@@ -120,7 +221,19 @@ var SandboxManager = class {
120
221
  // src/mcp-server.ts
121
222
  import { z } from "zod";
122
223
  var MCPServer = class {
224
+ /** The server name. */
225
+ name;
226
+ /** The server version. */
227
+ version;
123
228
  tools = /* @__PURE__ */ new Map();
229
+ /**
230
+ * Creates a new MCP server instance.
231
+ * @param config - Optional server configuration.
232
+ */
233
+ constructor(config) {
234
+ this.name = config?.name ?? "agentforge-mcp";
235
+ this.version = config?.version ?? "0.0.0";
236
+ }
124
237
  /**
125
238
  * Registers a new tool with the MCP server.
126
239
  *
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent.ts","../src/sandbox.ts","../src/mcp-server.ts"],"sourcesContent":["import { Agent as MastraAgent } from '@mastra/core/agent';\nimport type { LanguageModelV1 } from 'ai';\n\n/**\n * Configuration for creating an AgentForge Agent.\n */\nexport interface AgentConfig {\n /** A unique identifier for the agent. */\n id: string;\n /** A human-readable name for the agent. */\n name: string;\n /** The system prompt or instructions for the agent. */\n instructions: string;\n /**\n * The language model to use. Pass a LanguageModelV1 instance\n * (e.g., from `@ai-sdk/openai`, `@ai-sdk/anthropic`, etc.).\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n * const agent = new Agent({\n * model: openai('gpt-4o-mini'),\n * // ...\n * });\n * ```\n */\n model: LanguageModelV1;\n /** A dictionary of tools available to the agent. */\n tools?: Record<string, unknown>;\n}\n\n/**\n * Represents a structured response from an agent generation call.\n */\nexport interface AgentResponse {\n /** The text content of the response. */\n text: string;\n /** Optional tool call results. */\n toolResults?: unknown[];\n}\n\n/**\n * Represents a single chunk in a streaming response.\n */\nexport interface StreamChunk {\n /** The text content of this chunk. */\n content: string;\n}\n\n/**\n * The core Agent class for the AgentForge framework.\n *\n * Wraps the Mastra Agent to provide a simplified, curated API for\n * creating and interacting with AI agents. Supports any AI SDK-compatible\n * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key).\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant.',\n * model: openai('gpt-4o-mini'),\n * });\n *\n * const response = await agent.generate('Hello!');\n * ```\n */\nexport class Agent {\n /** The agent's unique ID. */\n public readonly id: string;\n\n /** The agent's human-readable name. */\n public readonly name: string;\n\n /** The underlying Mastra agent instance. */\n private mastraAgent: MastraAgent;\n\n /**\n * Creates a new AgentForge Agent.\n * @param config - The configuration for the agent.\n */\n constructor(config: AgentConfig) {\n this.id = config.id;\n this.name = config.name;\n\n this.mastraAgent = new MastraAgent({\n name: config.name,\n instructions: config.instructions,\n model: config.model,\n ...(config.tools ? { tools: config.tools as Record<string, never> } : {}),\n });\n }\n\n /**\n * Generates a structured response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns A promise that resolves to the agent's response.\n */\n async generate(prompt: string): Promise<AgentResponse> {\n const result = await this.mastraAgent.generate(prompt);\n return result as unknown as AgentResponse;\n }\n\n /**\n * Generates a streaming response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns An async iterable that yields response chunks.\n */\n async *stream(prompt: string): AsyncGenerator<StreamChunk> {\n const result = await this.mastraAgent.stream(prompt);\n for await (const chunk of result.textStream) {\n yield { content: typeof chunk === 'string' ? chunk : String(chunk) };\n }\n }\n}\n","import { Sandbox } from '@e2b/code-interpreter';\n\n/**\n * Configuration for the SandboxManager.\n */\nexport interface SandboxConfig {\n /**\n * The default execution timeout in milliseconds.\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Options for a specific sandbox run.\n */\nexport interface SandboxRunOptions {\n /**\n * The execution timeout in milliseconds for this specific run.\n */\n timeout?: number;\n}\n\n/**\n * Represents the result of a sandbox code execution.\n */\nexport interface SandboxResult {\n /** The output/results from the code execution. */\n output: unknown;\n /** Stdout logs produced during execution. */\n stdout?: string[];\n /** Stderr logs produced during execution. */\n stderr?: string[];\n}\n\n/**\n * A custom error class for sandbox timeouts.\n */\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * A custom error class for sandbox execution errors.\n */\nexport class SandboxExecutionError extends Error {\n /** The name of the execution error (e.g., 'SyntaxError'). */\n public readonly errorName: string;\n /** The raw traceback from the sandbox. */\n public readonly traceback: string;\n\n constructor(name: string, value: string, traceback: string) {\n super(`${name}: ${value}`);\n this.name = 'SandboxExecutionError';\n this.errorName = name;\n this.traceback = traceback;\n }\n}\n\n/**\n * Manages the lifecycle of E2B sandboxes for secure code execution.\n *\n * All tool code execution in AgentForge MUST occur within an E2B sandbox\n * to ensure security isolation and prevent malicious code from affecting\n * the host system.\n *\n * @example\n * ```typescript\n * const manager = new SandboxManager({ timeout: 10000 });\n * const result = await manager.runCode('1 + 1');\n * console.log(result); // { output: [...], stdout: [], stderr: [] }\n * ```\n */\nexport class SandboxManager {\n private sandbox: Sandbox | null = null;\n private defaultTimeout: number;\n\n /**\n * Creates a new SandboxManager.\n * @param config - The configuration for the sandbox manager.\n */\n constructor(config: SandboxConfig = {}) {\n this.defaultTimeout = config.timeout ?? 30000;\n }\n\n /**\n * Executes a snippet of code within a secure E2B sandbox.\n *\n * @param code - The code to execute.\n * @param options - Options for this specific run.\n * @returns A promise that resolves to the result of the code execution.\n * @throws {SandboxExecutionError} If the code throws an error.\n */\n async runCode(code: string, options?: SandboxRunOptions): Promise<SandboxResult> {\n const timeoutMs = options?.timeout ?? this.defaultTimeout;\n\n try {\n this.sandbox = await Sandbox.create();\n const execution = await this.sandbox.runCode(code, { timeoutMs });\n\n if (execution.error) {\n throw new SandboxExecutionError(\n execution.error.name,\n execution.error.value,\n execution.error.traceback,\n );\n }\n\n return {\n output: execution.results,\n stdout: execution.logs.stdout,\n stderr: execution.logs.stderr,\n };\n } finally {\n if (this.sandbox) {\n await this.sandbox.kill();\n this.sandbox = null;\n }\n }\n }\n\n /**\n * Terminates the sandbox and releases all associated resources.\n * @returns A promise that resolves when the cleanup is complete.\n */\n async cleanup(): Promise<void> {\n if (this.sandbox) {\n await this.sandbox.kill();\n this.sandbox = null;\n }\n }\n}\n","import { z } from 'zod';\n\n/**\n * Schema descriptor for tool listing.\n */\nexport interface ToolSchema {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** JSON Schema representation of the input. */\n inputSchema: Record<string, unknown>;\n /** JSON Schema representation of the output. */\n outputSchema: Record<string, unknown>;\n}\n\n/**\n * Represents a tool that can be registered and executed by the MCP server.\n *\n * @typeParam TInput - The Zod schema type for the tool's input.\n * @typeParam TOutput - The Zod schema type for the tool's output.\n */\nexport interface Tool<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** The Zod schema for the tool's input. */\n inputSchema: TInput;\n /** The Zod schema for the tool's output. */\n outputSchema: TOutput;\n /**\n * The function that implements the tool's logic.\n * @param input - The validated input matching the input schema.\n * @returns A promise that resolves with the tool's output.\n */\n handler: (input: z.infer<TInput>) => Promise<z.infer<TOutput>>;\n}\n\n/**\n * A server that implements the Model Context Protocol (MCP) for tool communication.\n *\n * Provides a central registry for tools that agents can discover and invoke.\n * All tool inputs and outputs are validated against their Zod schemas.\n *\n * @example\n * ```typescript\n * const server = new MCPServer();\n *\n * server.registerTool({\n * name: 'add',\n * description: 'Adds two numbers',\n * inputSchema: z.object({ a: z.number(), b: z.number() }),\n * outputSchema: z.number(),\n * handler: async ({ a, b }) => a + b,\n * });\n *\n * const result = await server.callTool('add', { a: 5, b: 3 });\n * // result === 8\n * ```\n */\nexport class MCPServer {\n private tools: Map<string, Tool> = new Map();\n\n /**\n * Registers a new tool with the MCP server.\n *\n * @param tool - The tool definition to register.\n * @throws {Error} If a tool with the same name is already registered.\n */\n public registerTool<\n TInput extends z.ZodTypeAny,\n TOutput extends z.ZodTypeAny,\n >(tool: Tool<TInput, TOutput>): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool with name '${tool.name}' is already registered.`);\n }\n this.tools.set(tool.name, tool as unknown as Tool);\n }\n\n /**\n * Retrieves a list of all registered tools and their schemas.\n *\n * @returns An array of tool schema descriptors.\n */\n public listTools(): ToolSchema[] {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.zodToJsonSchema(tool.inputSchema),\n outputSchema: this.zodToJsonSchema(tool.outputSchema),\n }));\n }\n\n /**\n * Invokes a specified tool with the provided input.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to the tool (will be validated against the schema).\n * @returns A promise that resolves with the validated result.\n * @throws {Error} If the tool is not found or input/output validation fails.\n */\n public async callTool(toolName: string, input: unknown): Promise<unknown> {\n const tool = this.tools.get(toolName);\n if (!tool) {\n throw new Error(`Tool with name '${toolName}' not found.`);\n }\n\n const parsedInput = tool.inputSchema.safeParse(input);\n if (!parsedInput.success) {\n throw new Error(\n `Invalid input for tool '${toolName}': ${parsedInput.error.message}`\n );\n }\n\n const result = await tool.handler(parsedInput.data);\n\n const parsedOutput = tool.outputSchema.safeParse(result);\n if (!parsedOutput.success) {\n throw new Error(\n `Invalid output from tool '${toolName}': ${parsedOutput.error.message}`\n );\n }\n\n return parsedOutput.data;\n }\n\n /**\n * Converts a Zod schema to a simplified JSON Schema representation.\n * @param schema - The Zod schema to convert.\n * @returns A simplified JSON Schema object.\n */\n private zodToJsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {\n // Simple conversion - in production, use zod-to-json-schema\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = { type: this.getZodTypeName(value as z.ZodTypeAny) };\n }\n return { type: 'object', properties };\n }\n return { type: this.getZodTypeName(schema) };\n }\n\n /**\n * Gets the type name for a Zod schema.\n */\n private getZodTypeName(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodString) return 'string';\n if (schema instanceof z.ZodNumber) return 'number';\n if (schema instanceof z.ZodBoolean) return 'boolean';\n if (schema instanceof z.ZodArray) return 'array';\n if (schema instanceof z.ZodObject) return 'object';\n return 'unknown';\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS,mBAAmB;AAsE9B,IAAM,QAAN,MAAY;AAAA;AAAA,EAED;AAAA;AAAA,EAGA;AAAA;AAAA,EAGR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,YAAY,QAAqB;AAC/B,SAAK,KAAK,OAAO;AACjB,SAAK,OAAO,OAAO;AAEnB,SAAK,cAAc,IAAI,YAAY;AAAA,MACjC,MAAM,OAAO;AAAA,MACb,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,MACd,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAA+B,IAAI,CAAC;AAAA,IACzE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,QAAwC;AACrD,UAAM,SAAS,MAAM,KAAK,YAAY,SAAS,MAAM;AACrD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OAAO,QAA6C;AACzD,UAAM,SAAS,MAAM,KAAK,YAAY,OAAO,MAAM;AACnD,qBAAiB,SAAS,OAAO,YAAY;AAC3C,YAAM,EAAE,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK,EAAE;AAAA,IACrE;AAAA,EACF;AACF;;;ACrHA,SAAS,eAAe;AAsCjB,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,wBAAN,cAAoC,MAAM;AAAA;AAAA,EAE/B;AAAA;AAAA,EAEA;AAAA,EAEhB,YAAY,MAAc,OAAe,WAAmB;AAC1D,UAAM,GAAG,IAAI,KAAK,KAAK,EAAE;AACzB,SAAK,OAAO;AACZ,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EACnB;AACF;AAgBO,IAAM,iBAAN,MAAqB;AAAA,EAClB,UAA0B;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,YAAY,SAAwB,CAAC,GAAG;AACtC,SAAK,iBAAiB,OAAO,WAAW;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,MAAc,SAAqD;AAC/E,UAAM,YAAY,SAAS,WAAW,KAAK;AAE3C,QAAI;AACF,WAAK,UAAU,MAAM,QAAQ,OAAO;AACpC,YAAM,YAAY,MAAM,KAAK,QAAQ,QAAQ,MAAM,EAAE,UAAU,CAAC;AAEhE,UAAI,UAAU,OAAO;AACnB,cAAM,IAAI;AAAA,UACR,UAAU,MAAM;AAAA,UAChB,UAAU,MAAM;AAAA,UAChB,UAAU,MAAM;AAAA,QAClB;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,UAAU;AAAA,QAClB,QAAQ,UAAU,KAAK;AAAA,QACvB,QAAQ,UAAU,KAAK;AAAA,MACzB;AAAA,IACF,UAAE;AACA,UAAI,KAAK,SAAS;AAChB,cAAM,KAAK,QAAQ,KAAK;AACxB,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAyB;AAC7B,QAAI,KAAK,SAAS;AAChB,YAAM,KAAK,QAAQ,KAAK;AACxB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AACF;;;ACtIA,SAAS,SAAS;AAgEX,IAAM,YAAN,MAAgB;AAAA,EACb,QAA2B,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpC,aAGL,MAAmC;AACnC,QAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG;AAC7B,YAAM,IAAI,MAAM,mBAAmB,KAAK,IAAI,0BAA0B;AAAA,IACxE;AACA,SAAK,MAAM,IAAI,KAAK,MAAM,IAAuB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAA0B;AAC/B,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU;AAAA,MACpD,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,gBAAgB,KAAK,WAAW;AAAA,MAClD,cAAc,KAAK,gBAAgB,KAAK,YAAY;AAAA,IACtD,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,SAAS,UAAkB,OAAkC;AACxE,UAAM,OAAO,KAAK,MAAM,IAAI,QAAQ;AACpC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,mBAAmB,QAAQ,cAAc;AAAA,IAC3D;AAEA,UAAM,cAAc,KAAK,YAAY,UAAU,KAAK;AACpD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,IAAI;AAAA,QACR,2BAA2B,QAAQ,MAAM,YAAY,MAAM,OAAO;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,YAAY,IAAI;AAElD,UAAM,eAAe,KAAK,aAAa,UAAU,MAAM;AACvD,QAAI,CAAC,aAAa,SAAS;AACzB,YAAM,IAAI;AAAA,QACR,6BAA6B,QAAQ,MAAM,aAAa,MAAM,OAAO;AAAA,MACvE;AAAA,IACF;AAEA,WAAO,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,QAA+C;AAErE,QAAI,kBAAkB,EAAE,WAAW;AACjC,YAAM,QAAQ,OAAO;AACrB,YAAM,aAAsC,CAAC;AAC7C,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,mBAAW,GAAG,IAAI,EAAE,MAAM,KAAK,eAAe,KAAqB,EAAE;AAAA,MACvE;AACA,aAAO,EAAE,MAAM,UAAU,WAAW;AAAA,IACtC;AACA,WAAO,EAAE,MAAM,KAAK,eAAe,MAAM,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAA8B;AACnD,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,QAAI,kBAAkB,EAAE,SAAU,QAAO;AACzC,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/agent.ts","../src/sandbox.ts","../src/mcp-server.ts"],"sourcesContent":["import { Agent as MastraAgent } from '@mastra/core/agent';\nimport type { LanguageModelV1 } from 'ai';\nimport type { MCPServer } from './mcp-server.js';\n\n/**\n * Supported model types for AgentForge agents.\n *\n * - `LanguageModelV1`: Any AI SDK v4 model instance (e.g., `openai('gpt-4o')`)\n * - `string`: A Mastra model router ID (e.g., `'openai/gpt-4o'`)\n */\nexport type AgentModel = LanguageModelV1 | string;\n\n/**\n * Configuration for creating an AgentForge Agent.\n */\nexport interface AgentConfig {\n /** A unique identifier for the agent. */\n id: string;\n /** A human-readable name for the agent. */\n name: string;\n /** The system prompt or instructions for the agent. */\n instructions: string;\n /**\n * The language model to use. Accepts either:\n * - A `LanguageModelV1` instance (e.g., from `@ai-sdk/openai`)\n * - A string model ID (e.g., `'openai/gpt-4o'`)\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n *\n * // Using an AI SDK model instance (BYOK)\n * const agent = new Agent({\n * model: openai('gpt-4o-mini'),\n * // ...\n * });\n *\n * // Using a Mastra model router string\n * const agent = new Agent({\n * model: 'openai/gpt-4o-mini',\n * // ...\n * });\n * ```\n */\n model: AgentModel;\n /** An MCPServer instance providing tools for the agent. */\n tools?: MCPServer;\n}\n\n/**\n * Represents a structured response from an agent generation call.\n */\nexport interface AgentResponse {\n /** The text content of the response. */\n text: string;\n /** Optional tool call results. */\n toolResults?: unknown[];\n}\n\n/**\n * Represents a single chunk in a streaming response.\n */\nexport interface StreamChunk {\n /** The text content of this chunk. */\n content: string;\n}\n\n/**\n * The core Agent class for the AgentForge framework.\n *\n * Wraps the Mastra Agent to provide a simplified, curated API for\n * creating and interacting with AI agents. Supports any AI SDK-compatible\n * model provider (OpenAI, Anthropic, Google, etc.) via BYOK (Bring Your Own Key),\n * or Mastra model router string IDs.\n *\n * Tools can be provided at construction time via the `tools` config option,\n * or added dynamically after construction using the `addTools()` method.\n *\n * @example\n * ```typescript\n * import { openai } from '@ai-sdk/openai';\n * import { Agent, MCPServer } from '@agentforge-ai/core';\n *\n * const tools = new MCPServer();\n * tools.registerTool({ ... });\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant.',\n * model: openai('gpt-4o-mini'),\n * tools: tools,\n * });\n *\n * // Or add tools dynamically:\n * const moreTools = new MCPServer();\n * moreTools.registerTool({ ... });\n * agent.addTools(moreTools);\n *\n * const response = await agent.generate('Hello!');\n * ```\n */\nexport class Agent {\n /** The agent's unique ID. */\n public readonly id: string;\n\n /** The agent's human-readable name. */\n public readonly name: string;\n\n /** The agent's instructions (system prompt). */\n public readonly instructions: string;\n\n /** The agent's model configuration. */\n public readonly model: AgentModel;\n\n /** The underlying Mastra agent instance. */\n private mastraAgent: MastraAgent;\n\n /** The collection of MCP servers providing tools to this agent. */\n private toolServers: MCPServer[] = [];\n\n /**\n * Creates a new AgentForge Agent.\n * @param config - The configuration for the agent.\n */\n constructor(config: AgentConfig) {\n this.id = config.id;\n this.name = config.name;\n this.instructions = config.instructions;\n this.model = config.model;\n\n if (config.tools) {\n this.toolServers.push(config.tools);\n }\n\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Dynamically adds tools from an MCPServer to this agent.\n *\n * This method allows you to extend an agent's capabilities after construction.\n * Multiple MCPServer instances can be added, and their tools are merged together.\n * The underlying Mastra agent is rebuilt to include the new tools.\n *\n * @param server - An MCPServer instance containing the tools to add.\n *\n * @example\n * ```typescript\n * const agent = new Agent({ id: 'a', name: 'A', instructions: '...', model: 'openai/gpt-4o' });\n *\n * const financialTools = new MCPServer();\n * financialTools.registerTool({ name: 'get_stock_price', ... });\n * agent.addTools(financialTools);\n *\n * const adminTools = new MCPServer();\n * adminTools.registerTool({ name: 'delete_user', ... });\n * agent.addTools(adminTools);\n *\n * // Agent now has both get_stock_price and delete_user tools\n * const tools = agent.getTools();\n * ```\n */\n addTools(server: MCPServer): void {\n this.toolServers.push(server);\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Removes all tools from this agent.\n *\n * Clears all registered MCPServer instances and rebuilds the underlying\n * Mastra agent without any tools.\n */\n clearTools(): void {\n this.toolServers = [];\n this.mastraAgent = this.buildMastraAgent();\n }\n\n /**\n * Returns a flat list of all tool schemas registered across all MCPServer instances.\n *\n * @returns An array of tool schema descriptors from all attached MCPServers.\n */\n getTools(): ReturnType<MCPServer['listTools']> {\n return this.toolServers.flatMap((server) => server.listTools());\n }\n\n /**\n * Invokes a tool by name across all attached MCPServer instances.\n *\n * Searches through all registered MCPServers for the named tool and\n * invokes it with the provided input. Throws if the tool is not found\n * in any server.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to pass to the tool.\n * @returns A promise that resolves with the tool's output.\n * @throws {Error} If the tool is not found in any attached MCPServer.\n */\n async callTool(toolName: string, input: unknown): Promise<unknown> {\n for (const server of this.toolServers) {\n const toolList = server.listTools();\n if (toolList.some((t) => t.name === toolName)) {\n return server.callTool(toolName, input);\n }\n }\n throw new Error(`Tool '${toolName}' not found in any attached MCPServer.`);\n }\n\n /**\n * Generates a structured response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns A promise that resolves to the agent's response.\n */\n async generate(prompt: string): Promise<AgentResponse> {\n const result = await this.mastraAgent.generate(prompt);\n return result as unknown as AgentResponse;\n }\n\n /**\n * Generates a streaming response from the agent.\n * @param prompt - The user's prompt or input.\n * @returns An async iterable that yields response chunks.\n */\n async *stream(prompt: string): AsyncGenerator<StreamChunk> {\n const result = await this.mastraAgent.stream(prompt);\n for await (const chunk of result.textStream) {\n yield { content: typeof chunk === 'string' ? chunk : String(chunk) };\n }\n }\n\n /**\n * Builds (or rebuilds) the underlying Mastra agent from the current configuration.\n * Called on construction and whenever tools are added or cleared.\n */\n private buildMastraAgent(): MastraAgent {\n const toolsRecord = this.buildToolsRecord();\n\n return new MastraAgent({\n id: this.id,\n name: this.name,\n instructions: this.instructions,\n model: this.model as Parameters<typeof MastraAgent.prototype.generate>[0] extends { model?: infer M } ? M : never,\n ...(Object.keys(toolsRecord).length > 0 ? { tools: toolsRecord as Record<string, never> } : {}),\n });\n }\n\n /**\n * Merges tools from all attached MCPServer instances into a single record\n * suitable for passing to the Mastra agent constructor.\n */\n private buildToolsRecord(): Record<string, unknown> {\n const record: Record<string, unknown> = {};\n for (const server of this.toolServers) {\n for (const tool of server.listTools()) {\n record[tool.name] = tool;\n }\n }\n return record;\n }\n}\n","import { Sandbox } from '@e2b/code-interpreter';\n\n/**\n * Configuration for the SandboxManager.\n */\nexport interface SandboxConfig {\n /**\n * The default execution timeout in milliseconds.\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Options for a specific sandbox run.\n */\nexport interface SandboxRunOptions {\n /**\n * The execution timeout in milliseconds for this specific run.\n */\n timeout?: number;\n}\n\n/**\n * Represents the result of a sandbox code execution.\n */\nexport interface SandboxResult {\n /** The output/results from the code execution. */\n output: unknown;\n /** Stdout logs produced during execution. */\n stdout?: string[];\n /** Stderr logs produced during execution. */\n stderr?: string[];\n}\n\n/**\n * A custom error class for sandbox timeouts.\n */\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * A custom error class for sandbox execution errors.\n */\nexport class SandboxExecutionError extends Error {\n /** The name of the execution error (e.g., 'SyntaxError'). */\n public readonly errorName: string;\n /** The raw traceback from the sandbox. */\n public readonly traceback: string;\n\n constructor(name: string, value: string, traceback: string) {\n super(`${name}: ${value}`);\n this.name = 'SandboxExecutionError';\n this.errorName = name;\n this.traceback = traceback;\n }\n}\n\n/**\n * Manages the lifecycle of E2B sandboxes for secure code execution.\n *\n * All tool code execution in AgentForge MUST occur within an E2B sandbox\n * to ensure security isolation and prevent malicious code from affecting\n * the host system.\n *\n * @example\n * ```typescript\n * const manager = new SandboxManager({ timeout: 10000 });\n * const result = await manager.runCode('1 + 1');\n * console.log(result); // { output: [...], stdout: [], stderr: [] }\n * ```\n */\nexport class SandboxManager {\n private sandbox: Sandbox | null = null;\n private defaultTimeout: number;\n\n /**\n * Creates a new SandboxManager.\n * @param config - The configuration for the sandbox manager.\n */\n constructor(config: SandboxConfig = {}) {\n this.defaultTimeout = config.timeout ?? 30000;\n }\n\n /**\n * Executes a snippet of code within a secure E2B sandbox.\n *\n * @param code - The code to execute.\n * @param options - Options for this specific run.\n * @returns A promise that resolves to the result of the code execution.\n * @throws {SandboxExecutionError} If the code throws an error.\n */\n async runCode(code: string, options?: SandboxRunOptions): Promise<SandboxResult> {\n const timeoutMs = options?.timeout ?? this.defaultTimeout;\n\n try {\n this.sandbox = await Sandbox.create();\n const execution = await this.sandbox.runCode(code, { timeoutMs });\n\n if (execution.error) {\n throw new SandboxExecutionError(\n execution.error.name,\n execution.error.value,\n execution.error.traceback,\n );\n }\n\n return {\n output: execution.results,\n stdout: execution.logs.stdout,\n stderr: execution.logs.stderr,\n };\n } finally {\n if (this.sandbox) {\n await this.sandbox.kill();\n this.sandbox = null;\n }\n }\n }\n\n /**\n * Terminates the sandbox and releases all associated resources.\n * @returns A promise that resolves when the cleanup is complete.\n */\n async cleanup(): Promise<void> {\n if (this.sandbox) {\n await this.sandbox.kill();\n this.sandbox = null;\n }\n }\n}\n","import { z } from 'zod';\n\n/**\n * Configuration for creating an MCP server.\n */\nexport interface MCPServerConfig {\n /** The name of the MCP server. */\n name?: string;\n /** The version of the MCP server. */\n version?: string;\n}\n\n/**\n * Schema descriptor for tool listing.\n */\nexport interface ToolSchema {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** JSON Schema representation of the input. */\n inputSchema: Record<string, unknown>;\n /** JSON Schema representation of the output. */\n outputSchema: Record<string, unknown>;\n}\n\n/**\n * Represents a tool that can be registered and executed by the MCP server.\n *\n * @typeParam TInput - The Zod schema type for the tool's input.\n * @typeParam TOutput - The Zod schema type for the tool's output.\n */\nexport interface Tool<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** The Zod schema for the tool's input. */\n inputSchema: TInput;\n /** The Zod schema for the tool's output. */\n outputSchema: TOutput;\n /**\n * The function that implements the tool's logic.\n * @param input - The validated input matching the input schema.\n * @returns A promise that resolves with the tool's output.\n */\n handler: (input: z.infer<TInput>) => Promise<z.infer<TOutput>>;\n}\n\n/**\n * A server that implements the Model Context Protocol (MCP) for tool communication.\n *\n * Provides a central registry for tools that agents can discover and invoke.\n * All tool inputs and outputs are validated against their Zod schemas.\n *\n * @example\n * ```typescript\n * const server = new MCPServer({ name: 'my-tools', version: '1.0.0' });\n *\n * server.registerTool({\n * name: 'add',\n * description: 'Adds two numbers',\n * inputSchema: z.object({ a: z.number(), b: z.number() }),\n * outputSchema: z.number(),\n * handler: async ({ a, b }) => a + b,\n * });\n *\n * const result = await server.callTool('add', { a: 5, b: 3 });\n * // result === 8\n * ```\n */\nexport class MCPServer {\n /** The server name. */\n public readonly name: string;\n /** The server version. */\n public readonly version: string;\n private tools: Map<string, Tool> = new Map();\n\n /**\n * Creates a new MCP server instance.\n * @param config - Optional server configuration.\n */\n constructor(config?: MCPServerConfig) {\n this.name = config?.name ?? 'agentforge-mcp';\n this.version = config?.version ?? '0.0.0';\n }\n\n /**\n * Registers a new tool with the MCP server.\n *\n * @param tool - The tool definition to register.\n * @throws {Error} If a tool with the same name is already registered.\n */\n public registerTool<\n TInput extends z.ZodTypeAny,\n TOutput extends z.ZodTypeAny,\n >(tool: Tool<TInput, TOutput>): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool with name '${tool.name}' is already registered.`);\n }\n this.tools.set(tool.name, tool as unknown as Tool);\n }\n\n /**\n * Retrieves a list of all registered tools and their schemas.\n *\n * @returns An array of tool schema descriptors.\n */\n public listTools(): ToolSchema[] {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.zodToJsonSchema(tool.inputSchema),\n outputSchema: this.zodToJsonSchema(tool.outputSchema),\n }));\n }\n\n /**\n * Invokes a specified tool with the provided input.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to the tool (will be validated against the schema).\n * @returns A promise that resolves with the validated result.\n * @throws {Error} If the tool is not found or input/output validation fails.\n */\n public async callTool(toolName: string, input: unknown): Promise<unknown> {\n const tool = this.tools.get(toolName);\n if (!tool) {\n throw new Error(`Tool with name '${toolName}' not found.`);\n }\n\n const parsedInput = tool.inputSchema.safeParse(input);\n if (!parsedInput.success) {\n throw new Error(\n `Invalid input for tool '${toolName}': ${parsedInput.error.message}`\n );\n }\n\n const result = await tool.handler(parsedInput.data);\n\n const parsedOutput = tool.outputSchema.safeParse(result);\n if (!parsedOutput.success) {\n throw new Error(\n `Invalid output from tool '${toolName}': ${parsedOutput.error.message}`\n );\n }\n\n return parsedOutput.data;\n }\n\n /**\n * Converts a Zod schema to a simplified JSON Schema representation.\n * @param schema - The Zod schema to convert.\n * @returns A simplified JSON Schema object.\n */\n private zodToJsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = { type: this.getZodTypeName(value as z.ZodTypeAny) };\n }\n return { type: 'object', properties };\n }\n return { type: this.getZodTypeName(schema) };\n }\n\n /**\n * Gets the type name for a Zod schema.\n */\n private getZodTypeName(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodString) return 'string';\n if (schema instanceof z.ZodNumber) return 'number';\n if (schema instanceof z.ZodBoolean) return 'boolean';\n if (schema instanceof z.ZodArray) return 'array';\n if (schema instanceof z.ZodObject) return 'object';\n return 'unknown';\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,14 @@
1
1
  import { z } from 'zod';
2
2
 
3
+ /**
4
+ * Configuration for creating an MCP server.
5
+ */
6
+ interface MCPServerConfig {
7
+ /** The name of the MCP server. */
8
+ name?: string;
9
+ /** The version of the MCP server. */
10
+ version?: string;
11
+ }
3
12
  /**
4
13
  * Schema descriptor for tool listing.
5
14
  */
@@ -43,7 +52,7 @@ interface Tool<TInput extends z.ZodTypeAny = z.ZodTypeAny, TOutput extends z.Zod
43
52
  *
44
53
  * @example
45
54
  * ```typescript
46
- * const server = new MCPServer();
55
+ * const server = new MCPServer({ name: 'my-tools', version: '1.0.0' });
47
56
  *
48
57
  * server.registerTool({
49
58
  * name: 'add',
@@ -58,7 +67,16 @@ interface Tool<TInput extends z.ZodTypeAny = z.ZodTypeAny, TOutput extends z.Zod
58
67
  * ```
59
68
  */
60
69
  declare class MCPServer {
70
+ /** The server name. */
71
+ readonly name: string;
72
+ /** The server version. */
73
+ readonly version: string;
61
74
  private tools;
75
+ /**
76
+ * Creates a new MCP server instance.
77
+ * @param config - Optional server configuration.
78
+ */
79
+ constructor(config?: MCPServerConfig);
62
80
  /**
63
81
  * Registers a new tool with the MCP server.
64
82
  *
@@ -93,4 +111,4 @@ declare class MCPServer {
93
111
  private getZodTypeName;
94
112
  }
95
113
 
96
- export { MCPServer, type Tool, type ToolSchema };
114
+ export { MCPServer, type MCPServerConfig, type Tool, type ToolSchema };
@@ -1,7 +1,19 @@
1
1
  // src/mcp-server.ts
2
2
  import { z } from "zod";
3
3
  var MCPServer = class {
4
+ /** The server name. */
5
+ name;
6
+ /** The server version. */
7
+ version;
4
8
  tools = /* @__PURE__ */ new Map();
9
+ /**
10
+ * Creates a new MCP server instance.
11
+ * @param config - Optional server configuration.
12
+ */
13
+ constructor(config) {
14
+ this.name = config?.name ?? "agentforge-mcp";
15
+ this.version = config?.version ?? "0.0.0";
16
+ }
5
17
  /**
6
18
  * Registers a new tool with the MCP server.
7
19
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp-server.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Schema descriptor for tool listing.\n */\nexport interface ToolSchema {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** JSON Schema representation of the input. */\n inputSchema: Record<string, unknown>;\n /** JSON Schema representation of the output. */\n outputSchema: Record<string, unknown>;\n}\n\n/**\n * Represents a tool that can be registered and executed by the MCP server.\n *\n * @typeParam TInput - The Zod schema type for the tool's input.\n * @typeParam TOutput - The Zod schema type for the tool's output.\n */\nexport interface Tool<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** The Zod schema for the tool's input. */\n inputSchema: TInput;\n /** The Zod schema for the tool's output. */\n outputSchema: TOutput;\n /**\n * The function that implements the tool's logic.\n * @param input - The validated input matching the input schema.\n * @returns A promise that resolves with the tool's output.\n */\n handler: (input: z.infer<TInput>) => Promise<z.infer<TOutput>>;\n}\n\n/**\n * A server that implements the Model Context Protocol (MCP) for tool communication.\n *\n * Provides a central registry for tools that agents can discover and invoke.\n * All tool inputs and outputs are validated against their Zod schemas.\n *\n * @example\n * ```typescript\n * const server = new MCPServer();\n *\n * server.registerTool({\n * name: 'add',\n * description: 'Adds two numbers',\n * inputSchema: z.object({ a: z.number(), b: z.number() }),\n * outputSchema: z.number(),\n * handler: async ({ a, b }) => a + b,\n * });\n *\n * const result = await server.callTool('add', { a: 5, b: 3 });\n * // result === 8\n * ```\n */\nexport class MCPServer {\n private tools: Map<string, Tool> = new Map();\n\n /**\n * Registers a new tool with the MCP server.\n *\n * @param tool - The tool definition to register.\n * @throws {Error} If a tool with the same name is already registered.\n */\n public registerTool<\n TInput extends z.ZodTypeAny,\n TOutput extends z.ZodTypeAny,\n >(tool: Tool<TInput, TOutput>): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool with name '${tool.name}' is already registered.`);\n }\n this.tools.set(tool.name, tool as unknown as Tool);\n }\n\n /**\n * Retrieves a list of all registered tools and their schemas.\n *\n * @returns An array of tool schema descriptors.\n */\n public listTools(): ToolSchema[] {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.zodToJsonSchema(tool.inputSchema),\n outputSchema: this.zodToJsonSchema(tool.outputSchema),\n }));\n }\n\n /**\n * Invokes a specified tool with the provided input.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to the tool (will be validated against the schema).\n * @returns A promise that resolves with the validated result.\n * @throws {Error} If the tool is not found or input/output validation fails.\n */\n public async callTool(toolName: string, input: unknown): Promise<unknown> {\n const tool = this.tools.get(toolName);\n if (!tool) {\n throw new Error(`Tool with name '${toolName}' not found.`);\n }\n\n const parsedInput = tool.inputSchema.safeParse(input);\n if (!parsedInput.success) {\n throw new Error(\n `Invalid input for tool '${toolName}': ${parsedInput.error.message}`\n );\n }\n\n const result = await tool.handler(parsedInput.data);\n\n const parsedOutput = tool.outputSchema.safeParse(result);\n if (!parsedOutput.success) {\n throw new Error(\n `Invalid output from tool '${toolName}': ${parsedOutput.error.message}`\n );\n }\n\n return parsedOutput.data;\n }\n\n /**\n * Converts a Zod schema to a simplified JSON Schema representation.\n * @param schema - The Zod schema to convert.\n * @returns A simplified JSON Schema object.\n */\n private zodToJsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {\n // Simple conversion - in production, use zod-to-json-schema\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = { type: this.getZodTypeName(value as z.ZodTypeAny) };\n }\n return { type: 'object', properties };\n }\n return { type: this.getZodTypeName(schema) };\n }\n\n /**\n * Gets the type name for a Zod schema.\n */\n private getZodTypeName(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodString) return 'string';\n if (schema instanceof z.ZodNumber) return 'number';\n if (schema instanceof z.ZodBoolean) return 'boolean';\n if (schema instanceof z.ZodArray) return 'array';\n if (schema instanceof z.ZodObject) return 'object';\n return 'unknown';\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAgEX,IAAM,YAAN,MAAgB;AAAA,EACb,QAA2B,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpC,aAGL,MAAmC;AACnC,QAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG;AAC7B,YAAM,IAAI,MAAM,mBAAmB,KAAK,IAAI,0BAA0B;AAAA,IACxE;AACA,SAAK,MAAM,IAAI,KAAK,MAAM,IAAuB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAA0B;AAC/B,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU;AAAA,MACpD,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,gBAAgB,KAAK,WAAW;AAAA,MAClD,cAAc,KAAK,gBAAgB,KAAK,YAAY;AAAA,IACtD,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,SAAS,UAAkB,OAAkC;AACxE,UAAM,OAAO,KAAK,MAAM,IAAI,QAAQ;AACpC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,mBAAmB,QAAQ,cAAc;AAAA,IAC3D;AAEA,UAAM,cAAc,KAAK,YAAY,UAAU,KAAK;AACpD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,IAAI;AAAA,QACR,2BAA2B,QAAQ,MAAM,YAAY,MAAM,OAAO;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,YAAY,IAAI;AAElD,UAAM,eAAe,KAAK,aAAa,UAAU,MAAM;AACvD,QAAI,CAAC,aAAa,SAAS;AACzB,YAAM,IAAI;AAAA,QACR,6BAA6B,QAAQ,MAAM,aAAa,MAAM,OAAO;AAAA,MACvE;AAAA,IACF;AAEA,WAAO,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,QAA+C;AAErE,QAAI,kBAAkB,EAAE,WAAW;AACjC,YAAM,QAAQ,OAAO;AACrB,YAAM,aAAsC,CAAC;AAC7C,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,mBAAW,GAAG,IAAI,EAAE,MAAM,KAAK,eAAe,KAAqB,EAAE;AAAA,MACvE;AACA,aAAO,EAAE,MAAM,UAAU,WAAW;AAAA,IACtC;AACA,WAAO,EAAE,MAAM,KAAK,eAAe,MAAM,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAA8B;AACnD,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,QAAI,kBAAkB,EAAE,SAAU,QAAO;AACzC,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/mcp-server.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Configuration for creating an MCP server.\n */\nexport interface MCPServerConfig {\n /** The name of the MCP server. */\n name?: string;\n /** The version of the MCP server. */\n version?: string;\n}\n\n/**\n * Schema descriptor for tool listing.\n */\nexport interface ToolSchema {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** JSON Schema representation of the input. */\n inputSchema: Record<string, unknown>;\n /** JSON Schema representation of the output. */\n outputSchema: Record<string, unknown>;\n}\n\n/**\n * Represents a tool that can be registered and executed by the MCP server.\n *\n * @typeParam TInput - The Zod schema type for the tool's input.\n * @typeParam TOutput - The Zod schema type for the tool's output.\n */\nexport interface Tool<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n /** The unique name of the tool. */\n name: string;\n /** A human-readable description of the tool. */\n description?: string;\n /** The Zod schema for the tool's input. */\n inputSchema: TInput;\n /** The Zod schema for the tool's output. */\n outputSchema: TOutput;\n /**\n * The function that implements the tool's logic.\n * @param input - The validated input matching the input schema.\n * @returns A promise that resolves with the tool's output.\n */\n handler: (input: z.infer<TInput>) => Promise<z.infer<TOutput>>;\n}\n\n/**\n * A server that implements the Model Context Protocol (MCP) for tool communication.\n *\n * Provides a central registry for tools that agents can discover and invoke.\n * All tool inputs and outputs are validated against their Zod schemas.\n *\n * @example\n * ```typescript\n * const server = new MCPServer({ name: 'my-tools', version: '1.0.0' });\n *\n * server.registerTool({\n * name: 'add',\n * description: 'Adds two numbers',\n * inputSchema: z.object({ a: z.number(), b: z.number() }),\n * outputSchema: z.number(),\n * handler: async ({ a, b }) => a + b,\n * });\n *\n * const result = await server.callTool('add', { a: 5, b: 3 });\n * // result === 8\n * ```\n */\nexport class MCPServer {\n /** The server name. */\n public readonly name: string;\n /** The server version. */\n public readonly version: string;\n private tools: Map<string, Tool> = new Map();\n\n /**\n * Creates a new MCP server instance.\n * @param config - Optional server configuration.\n */\n constructor(config?: MCPServerConfig) {\n this.name = config?.name ?? 'agentforge-mcp';\n this.version = config?.version ?? '0.0.0';\n }\n\n /**\n * Registers a new tool with the MCP server.\n *\n * @param tool - The tool definition to register.\n * @throws {Error} If a tool with the same name is already registered.\n */\n public registerTool<\n TInput extends z.ZodTypeAny,\n TOutput extends z.ZodTypeAny,\n >(tool: Tool<TInput, TOutput>): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool with name '${tool.name}' is already registered.`);\n }\n this.tools.set(tool.name, tool as unknown as Tool);\n }\n\n /**\n * Retrieves a list of all registered tools and their schemas.\n *\n * @returns An array of tool schema descriptors.\n */\n public listTools(): ToolSchema[] {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.zodToJsonSchema(tool.inputSchema),\n outputSchema: this.zodToJsonSchema(tool.outputSchema),\n }));\n }\n\n /**\n * Invokes a specified tool with the provided input.\n *\n * @param toolName - The name of the tool to invoke.\n * @param input - The input to the tool (will be validated against the schema).\n * @returns A promise that resolves with the validated result.\n * @throws {Error} If the tool is not found or input/output validation fails.\n */\n public async callTool(toolName: string, input: unknown): Promise<unknown> {\n const tool = this.tools.get(toolName);\n if (!tool) {\n throw new Error(`Tool with name '${toolName}' not found.`);\n }\n\n const parsedInput = tool.inputSchema.safeParse(input);\n if (!parsedInput.success) {\n throw new Error(\n `Invalid input for tool '${toolName}': ${parsedInput.error.message}`\n );\n }\n\n const result = await tool.handler(parsedInput.data);\n\n const parsedOutput = tool.outputSchema.safeParse(result);\n if (!parsedOutput.success) {\n throw new Error(\n `Invalid output from tool '${toolName}': ${parsedOutput.error.message}`\n );\n }\n\n return parsedOutput.data;\n }\n\n /**\n * Converts a Zod schema to a simplified JSON Schema representation.\n * @param schema - The Zod schema to convert.\n * @returns A simplified JSON Schema object.\n */\n private zodToJsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = { type: this.getZodTypeName(value as z.ZodTypeAny) };\n }\n return { type: 'object', properties };\n }\n return { type: this.getZodTypeName(schema) };\n }\n\n /**\n * Gets the type name for a Zod schema.\n */\n private getZodTypeName(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodString) return 'string';\n if (schema instanceof z.ZodNumber) return 'number';\n if (schema instanceof z.ZodBoolean) return 'boolean';\n if (schema instanceof z.ZodArray) return 'array';\n if (schema instanceof z.ZodObject) return 'object';\n return 'unknown';\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS;AA0EX,IAAM,YAAN,MAAgB;AAAA;AAAA,EAEL;AAAA;AAAA,EAEA;AAAA,EACR,QAA2B,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3C,YAAY,QAA0B;AACpC,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,UAAU,QAAQ,WAAW;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,aAGL,MAAmC;AACnC,QAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG;AAC7B,YAAM,IAAI,MAAM,mBAAmB,KAAK,IAAI,0BAA0B;AAAA,IACxE;AACA,SAAK,MAAM,IAAI,KAAK,MAAM,IAAuB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAA0B;AAC/B,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU;AAAA,MACpD,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,gBAAgB,KAAK,WAAW;AAAA,MAClD,cAAc,KAAK,gBAAgB,KAAK,YAAY;AAAA,IACtD,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,SAAS,UAAkB,OAAkC;AACxE,UAAM,OAAO,KAAK,MAAM,IAAI,QAAQ;AACpC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,mBAAmB,QAAQ,cAAc;AAAA,IAC3D;AAEA,UAAM,cAAc,KAAK,YAAY,UAAU,KAAK;AACpD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,IAAI;AAAA,QACR,2BAA2B,QAAQ,MAAM,YAAY,MAAM,OAAO;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,YAAY,IAAI;AAElD,UAAM,eAAe,KAAK,aAAa,UAAU,MAAM;AACvD,QAAI,CAAC,aAAa,SAAS;AACzB,YAAM,IAAI;AAAA,QACR,6BAA6B,QAAQ,MAAM,aAAa,MAAM,OAAO;AAAA,MACvE;AAAA,IACF;AAEA,WAAO,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,QAA+C;AACrE,QAAI,kBAAkB,EAAE,WAAW;AACjC,YAAM,QAAQ,OAAO;AACrB,YAAM,aAAsC,CAAC;AAC7C,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,mBAAW,GAAG,IAAI,EAAE,MAAM,KAAK,eAAe,KAAqB,EAAE;AAAA,MACvE;AACA,aAAO,EAAE,MAAM,UAAU,WAAW;AAAA,IACtC;AACA,WAAO,EAAE,MAAM,KAAK,eAAe,MAAM,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAA8B;AACnD,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,QAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,QAAI,kBAAkB,EAAE,SAAU,QAAO;AACzC,QAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,WAAO;AAAA,EACT;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge-ai/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Core agent primitives, sandbox integration, and MCP server for AgentForge",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -30,13 +30,14 @@
30
30
  "scripts": {
31
31
  "build": "tsup",
32
32
  "test": "vitest run",
33
+ "test:coverage": "vitest run --coverage",
33
34
  "test:watch": "vitest",
34
35
  "typecheck": "tsc --noEmit",
35
36
  "lint": "eslint src/",
36
37
  "clean": "rm -rf dist"
37
38
  },
38
39
  "dependencies": {
39
- "@mastra/core": "^0.5.0",
40
+ "@mastra/core": "^1.4.0",
40
41
  "ai": "^4.0.0",
41
42
  "@e2b/code-interpreter": "^1.0.0",
42
43
  "zod": "^3.23.0"