Euler MCP + Code
You can also make use of @modelcontextprotocol/sdk/client
in order to interact with the euler mcp server. This particular client provides a convenient way to establish a connection and communicate with the euler mcp server, enabling you to perform various operations and access the services offered by the server.
Quickstart
Install dependencies
npm install -y @modelcontextprotocol/sdk dotenv openai tsx
Edit client.ts and Set an OPENAI_API_KEY
```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
import dotenv from "dotenv";
import OpenAI from "openai";
dotenv.config();
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
if (!OPENAI_API_KEY) {
throw new Error("OPENAI_API_KEY is not set");
}
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL || "https://api.openai.com/v1";
const MCP_SERVER_URL = process.env.MCP_SERVER_URL || "https://dev.euler.ai/mcp/sse";
function openAiToolAdapter(tool: {
name: string;
description?: string;
input_schema: any;
}) {
return {
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: {
type: "object",
properties: tool.input_schema.properties,
required: tool.input_schema.required,
},
},
};
}
class MCPClient {
private mcp: Client;
private openai: OpenAI;
private tools: Array<any> = [];
private transport: Transport | null = null;
constructor() {
this.openai = new OpenAI({
apiKey: OPENAI_API_KEY,
baseURL: OPENAI_BASE_URL,
});
this.mcp = new Client({ name: "mcp-client", version: "1.0.0" });
}
async connectToServer(serverUrl: string) {
try {
this.transport = new SSEClientTransport(new URL(serverUrl));
await this.mcp.connect(this.transport);
const toolsResult = await this.mcp.listTools();
this.tools = toolsResult.tools.map((tool) => {
return openAiToolAdapter({
name: tool.name,
description: tool.description,
input_schema: tool.inputSchema,
});
});
} catch (e) {
console.log("Failed to connect to MCP server: ", e);
throw e;
}
}
async processQuery(query: string) {
const messages: any[] = [
{
role: "user",
content: query,
},
];
// console.log("Tools: ", JSON.stringify(this.tools, null, 2));
let response = await this.openai.chat.completions.create({
model: "gpt-3.5-turbo",
max_tokens: 1000,
messages,
tools: this.tools,
});
const finalText: string[] = [];
const toolResults: any[] = [];
console.log(
"Response from OpenAI: ",
JSON.stringify(response, null, 2)
);
for (const choice of response.choices) {
const message = choice.message;
if (message.tool_calls) {
toolResults.push(
await this.callTools(message.tool_calls, toolResults, finalText)
)
} else {
finalText.push(message.content || "xx");
}
}
messages.push({
"role": "user",
"content": `Tool Response ${JSON.stringify(toolResults)}`
})
messages.push({
"role": "user",
"content": `Use the Tool Response to answer the user's question: ${query}`
})
response = await this.openai.chat.completions.create({
model: "gpt-3.5-turbo",
max_tokens: 1000,
messages,
});
if (response.choices && response.choices.length > 0) {
finalText.push(
response.choices[0].message.content || "??"
);
}
return finalText.join("\n");
}
async callTools(
tool_calls: OpenAI.Chat.Completions.ChatCompletionMessageToolCall[],
toolResults: any[],
finalText: string[]
) {
for (const tool_call of tool_calls) {
const toolName = tool_call.function.name;
const args = tool_call.function.arguments;
console.log(`Calling tool ${toolName} with args ${JSON.stringify(args)}`);
const toolResult = await this.mcp.callTool({
name: toolName,
arguments: JSON.parse(args),
});
toolResults.push({
name: toolName,
result: toolResult,
});
finalText.push(
`[Calling tool ${toolName} with args ${JSON.stringify(args)}]`
);
}
}
async cleanup() {
await this.mcp.close();
}
}
const client = new MCPClient();
await client.connectToServer(MCP_SERVER_URL);
console.log("Connected to MCP server");
let query = process.argv[2] || "What is the sum of 2 and 3?";
let result = await client.processQuery(query);
console.log("Final result: ", result);
await client.cleanup();
```
Run the client.ts
tsx src/client.ts "Check the current ETH balance of vitalik.eth"
Calling tool resolve_ens with args "{\"ensName\":\"vitalik.eth\"}"
Final result: [Calling tool resolve_ens with args "{\"ensName\":\"vitalik.eth\"}"]
The Tool Response indicates that the resolved address of vitalik.eth is 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045. To check the current ETH balance of this address, it is recommended to use a blockchain explorer or a cryptocurrency wallet that supports querying account balances. You can input this address (0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045) in the search bar of a reliable blockchain explorer such as Etherscan to view the current ETH balance associated with vitalik.eth.
Last updated