11import { FastMCP } from 'fastmcp' ;
22import { z } from 'zod' ;
3+ import { type PluginToolSpec , createToolFromPluginSpec } from './lib/bitte-plugins' ;
34import { searchAgents , searchAgentsSchema , searchTools , searchToolsSchema } from './lib/search' ;
4- import { services } from './tools' ;
55import { callBitteAPI } from './utils/bitte' ;
66// Export configuration
77export { config } from './config' ;
@@ -24,6 +24,22 @@ export interface ExecuteAgentParams {
2424 input : string ;
2525}
2626
27+ // Create a log wrapper that also logs to console
28+ function wrapLogger ( log : any ) {
29+ return new Proxy ( log , {
30+ get ( target , prop ) {
31+ const originalMethod = target [ prop ] ;
32+ if ( typeof originalMethod === 'function' ) {
33+ return ( ...args : any [ ] ) => {
34+ console . log ( `[${ String ( prop ) } ]` , ...args ) ;
35+ return originalMethod . apply ( target , args ) ;
36+ } ;
37+ }
38+ return originalMethod ;
39+ } ,
40+ } ) ;
41+ }
42+
2743// Create and export the server
2844export const server = new FastMCP ( {
2945 name : 'bitte-ai-mcp-proxy' ,
@@ -49,9 +65,10 @@ server.addTool({
4965 agentId : z . string ( ) . describe ( 'ID of the agent to retrieve' ) ,
5066 } ) ,
5167 execute : async ( args , { log } ) => {
52- log . info ( `Getting agent with ID: ${ args . agentId } ` ) ;
68+ const wrappedLog = wrapLogger ( log ) ;
69+ wrappedLog . info ( `Getting agent with ID: ${ args . agentId } ` ) ;
5370 const endpoint = `/api/agents/${ args . agentId } ` ;
54- const data = await callBitteAPI ( endpoint , 'GET' , undefined , log ) ;
71+ const data = await callBitteAPI ( endpoint , 'GET' , undefined , wrappedLog ) ;
5572 return JSON . stringify ( data ) ;
5673 } ,
5774} ) ;
@@ -64,7 +81,8 @@ server.addTool({
6481 input : z . string ( ) . describe ( 'Input to the agent' ) ,
6582 } ) ,
6683 execute : async ( args , { log, session } ) => {
67- log . info ( `Executing agent with ID: ${ args . agentId } ` ) ;
84+ const wrappedLog = wrapLogger ( log ) ;
85+ wrappedLog . info ( `Executing agent with ID: ${ args . agentId } ` ) ;
6886
6987 try {
7088 // First, search for the agent to make sure it exists
@@ -73,7 +91,7 @@ server.addTool({
7391 query : args . agentId ,
7492 threshold : 0.1 , // Lower threshold for more exact matching
7593 } ,
76- log
94+ wrappedLog
7795 ) ;
7896
7997 // Check if we found a matching agent
@@ -90,7 +108,7 @@ server.addTool({
90108 } ;
91109
92110 // Call the Bitte API to execute the agent
93- const data = await callBitteAPI ( '/chat' , 'POST' , body , log ) ;
111+ const data = await callBitteAPI ( '/chat' , 'POST' , body , wrappedLog ) ;
94112
95113 if ( typeof data === 'string' ) {
96114 return {
@@ -104,7 +122,7 @@ server.addTool({
104122 } ;
105123 } catch ( error ) {
106124 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
107- log . error ( `Error executing agent: ${ errorMessage } ` ) ;
125+ wrappedLog . error ( `Error executing agent: ${ errorMessage } ` ) ;
108126 return {
109127 content : [ { type : 'text' , text : `Error executing agent: ${ errorMessage } ` } ] ,
110128 isError : true ,
@@ -120,11 +138,16 @@ server.addTool({
120138 parameters : z . object ( {
121139 tool : z . string ( ) . describe ( 'The tool to execute' ) ,
122140 params : z . string ( ) . describe ( 'The parameters to pass to the tool as a JSON string' ) ,
141+ metadata : z
142+ . object ( { } )
143+ . describe (
144+ 'Optional metadata to pass to the tool i.e. {accountId: "123", evmAddress: "0x123"}'
145+ )
146+ . optional ( ) ,
123147 } ) ,
124148 execute : async ( args , { log } ) => {
125- log . info ( `Executing execute-tool tool with params: ${ JSON . stringify ( args ) } ` ) ;
126- console . log ( 'execute-tool with args' , JSON . stringify ( args ) ) ;
127- console . log ( 'args' , args ) ;
149+ const wrappedLog = wrapLogger ( log ) ;
150+ wrappedLog . info ( `Executing execute-tool tool with params: ${ JSON . stringify ( args ) } ` ) ;
128151
129152 try {
130153 // Use searchTools to find the specified tool
@@ -133,25 +156,36 @@ server.addTool({
133156 query : args . tool ,
134157 threshold : 0.1 , // Lower threshold for more exact matching
135158 } ,
136- log
159+ wrappedLog
137160 ) ;
138161
139162 // Get the first (best) match
140163 const toolMatch = searchResult . combinedResults [ 0 ] ;
164+
141165 if ( ! toolMatch ) {
142166 throw new Error ( `Tool '${ args . tool } ' not found` ) ;
143167 }
144168
145169 const tool = toolMatch . item as {
146170 execute ?: ( params : Record < string , unknown > ) => Promise < unknown > ;
171+ execution ?: { baseUrl : string ; path : string ; httpMethod : string } ;
172+ function ?: { name : string ; description : string ; parameters ?: any } ;
147173 } ;
148174
149- if ( ! tool || typeof tool . execute !== 'function' ) {
175+ let result : unknown ;
176+
177+ // Check if the tool has an execution field
178+ if ( tool . execution && tool . function ) {
179+ // Create and execute a core tool with HTTP-based execution
180+ const coreTool = createToolFromPluginSpec ( tool as PluginToolSpec , args . metadata ) ;
181+ result = await coreTool . execute ( JSON . parse ( args . params ) ) ;
182+ } else if ( tool . execute && typeof tool . execute === 'function' ) {
183+ // Use the tool's execute method directly
184+ result = await tool . execute ( JSON . parse ( args . params ) ) ;
185+ } else {
150186 throw new Error ( `Tool '${ args . tool } ' found but cannot be executed` ) ;
151187 }
152188
153- const result = await tool . execute ( JSON . parse ( args . params ) ) ;
154-
155189 // Ensure we return a properly typed result
156190 if ( typeof result === 'string' ) {
157191 return {
@@ -164,7 +198,7 @@ server.addTool({
164198 } ;
165199 } catch ( error ) {
166200 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
167- log . error ( `Error executing tool: ${ errorMessage } ` ) ;
201+ wrappedLog . error ( `Error executing tool: ${ errorMessage } ` ) ;
168202 return {
169203 content : [ { type : 'text' , text : `Error executing tool: ${ errorMessage } ` } ] ,
170204 isError : true ,
@@ -179,13 +213,14 @@ server.addTool({
179213 description : 'Search for AI agents across Bitte API and other services' ,
180214 parameters : searchAgentsSchema ,
181215 execute : async ( args , { log } ) => {
182- log . info ( `Searching agents with params: ${ JSON . stringify ( args ) } ` ) ;
216+ const wrappedLog = wrapLogger ( log ) ;
217+ wrappedLog . info ( `Searching agents with params: ${ JSON . stringify ( args ) } ` ) ;
183218 try {
184- const result = await searchAgents ( args , log ) ;
219+ const result = await searchAgents ( args , wrappedLog ) ;
185220 return JSON . stringify ( result ) ;
186221 } catch ( error ) {
187222 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
188- log . error ( `Error searching agents: ${ errorMessage } ` ) ;
223+ wrappedLog . error ( `Error searching agents: ${ errorMessage } ` ) ;
189224 return {
190225 content : [ { type : 'text' , text : `Error searching agents: ${ errorMessage } ` } ] ,
191226 isError : true ,
@@ -200,13 +235,13 @@ server.addTool({
200235 description : 'Search for tools across Bitte API and other services' ,
201236 parameters : searchToolsSchema ,
202237 execute : async ( args , { log } ) => {
203- log . info ( `Searching tools with params: ${ JSON . stringify ( args ) } ` ) ;
238+ const wrappedLog = wrapLogger ( log ) ;
204239 try {
205- const result = await searchTools ( args , log ) ;
240+ const result = await searchTools ( args , wrappedLog ) ;
206241 return JSON . stringify ( result ) ;
207242 } catch ( error ) {
208243 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
209- log . error ( `Error searching tools: ${ errorMessage } ` ) ;
244+ wrappedLog . error ( `Error searching tools: ${ errorMessage } ` ) ;
210245 return {
211246 content : [ { type : 'text' , text : `Error searching tools: ${ errorMessage } ` } ] ,
212247 isError : true ,
0 commit comments