Add explanatory comments
This commit is contained in:
parent
a989b3f391
commit
f5637a04a2
1 changed files with 32 additions and 1 deletions
|
|
@ -10,7 +10,7 @@ import readline from "readline/promises";
|
||||||
|
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config(); // load environment variables from .env
|
||||||
|
|
||||||
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
||||||
if (!ANTHROPIC_API_KEY) {
|
if (!ANTHROPIC_API_KEY) {
|
||||||
|
|
@ -23,6 +23,7 @@ class MCPClient {
|
||||||
private transport: StdioClientTransport | null = null;
|
private transport: StdioClientTransport | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
// Initialize Anthropic client and MCP client
|
||||||
this.anthropic = new Anthropic({
|
this.anthropic = new Anthropic({
|
||||||
apiKey: ANTHROPIC_API_KEY,
|
apiKey: ANTHROPIC_API_KEY,
|
||||||
});
|
});
|
||||||
|
|
@ -30,7 +31,13 @@ class MCPClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectToServer(serverScriptPath: string) {
|
async connectToServer(serverScriptPath: string) {
|
||||||
|
/**
|
||||||
|
* Connect to an MCP server
|
||||||
|
*
|
||||||
|
* @param serverScriptPath - Path to the server script (.py or .js)
|
||||||
|
*/
|
||||||
try {
|
try {
|
||||||
|
// Determine script type and appropriate command
|
||||||
const isJs = serverScriptPath.endsWith(".js");
|
const isJs = serverScriptPath.endsWith(".js");
|
||||||
const isPy = serverScriptPath.endsWith(".py");
|
const isPy = serverScriptPath.endsWith(".py");
|
||||||
if (!isJs && !isPy) {
|
if (!isJs && !isPy) {
|
||||||
|
|
@ -41,11 +48,15 @@ class MCPClient {
|
||||||
? "python"
|
? "python"
|
||||||
: "python3"
|
: "python3"
|
||||||
: process.execPath;
|
: process.execPath;
|
||||||
|
|
||||||
|
// Initialize transport and connect to server
|
||||||
this.transport = new StdioClientTransport({
|
this.transport = new StdioClientTransport({
|
||||||
command,
|
command,
|
||||||
args: [serverScriptPath],
|
args: [serverScriptPath],
|
||||||
});
|
});
|
||||||
this.mcp.connect(this.transport);
|
this.mcp.connect(this.transport);
|
||||||
|
|
||||||
|
// List available tools
|
||||||
const toolsResult = await this.mcp.listTools();
|
const toolsResult = await this.mcp.listTools();
|
||||||
const tools = toolsResult.tools.map((tool) => {
|
const tools = toolsResult.tools.map((tool) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -65,6 +76,12 @@ class MCPClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async processQuery(query: string) {
|
async processQuery(query: string) {
|
||||||
|
/**
|
||||||
|
* Process a query using Claude and available tools
|
||||||
|
*
|
||||||
|
* @param query - The user's input query
|
||||||
|
* @returns Processed response as a string
|
||||||
|
*/
|
||||||
const messages: MessageParam[] = [
|
const messages: MessageParam[] = [
|
||||||
{
|
{
|
||||||
role: "user",
|
role: "user",
|
||||||
|
|
@ -72,6 +89,7 @@ class MCPClient {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Get available tools
|
||||||
const toolsResult = await this.mcp.listTools();
|
const toolsResult = await this.mcp.listTools();
|
||||||
const tools: Tool[] = toolsResult.tools.map((tool) => {
|
const tools: Tool[] = toolsResult.tools.map((tool) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -80,6 +98,8 @@ class MCPClient {
|
||||||
input_schema: tool.inputSchema,
|
input_schema: tool.inputSchema,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initial Claude API call
|
||||||
const response = await this.anthropic.messages.create({
|
const response = await this.anthropic.messages.create({
|
||||||
model: "claude-3-5-sonnet-20241022",
|
model: "claude-3-5-sonnet-20241022",
|
||||||
max_tokens: 1000,
|
max_tokens: 1000,
|
||||||
|
|
@ -87,6 +107,7 @@ class MCPClient {
|
||||||
tools,
|
tools,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Process response and handle tool calls
|
||||||
const finalText = [];
|
const finalText = [];
|
||||||
const toolResults = [];
|
const toolResults = [];
|
||||||
|
|
||||||
|
|
@ -94,6 +115,7 @@ class MCPClient {
|
||||||
if (content.type === "text") {
|
if (content.type === "text") {
|
||||||
finalText.push(content.text);
|
finalText.push(content.text);
|
||||||
} else if (content.type === "tool_use") {
|
} else if (content.type === "tool_use") {
|
||||||
|
// Execute tool call
|
||||||
const toolName = content.name;
|
const toolName = content.name;
|
||||||
const toolArgs = content.input as { [x: string]: unknown } | undefined;
|
const toolArgs = content.input as { [x: string]: unknown } | undefined;
|
||||||
|
|
||||||
|
|
@ -106,11 +128,13 @@ class MCPClient {
|
||||||
`[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`
|
`[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Continue conversation with tool results
|
||||||
messages.push({
|
messages.push({
|
||||||
role: "user",
|
role: "user",
|
||||||
content: result.content as string,
|
content: result.content as string,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get next response from Claude
|
||||||
const response = await this.anthropic.messages.create({
|
const response = await this.anthropic.messages.create({
|
||||||
model: "claude-3-5-sonnet-20241022",
|
model: "claude-3-5-sonnet-20241022",
|
||||||
max_tokens: 1000,
|
max_tokens: 1000,
|
||||||
|
|
@ -127,6 +151,9 @@ class MCPClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async chatLoop() {
|
async chatLoop() {
|
||||||
|
/**
|
||||||
|
* Run an interactive chat loop
|
||||||
|
*/
|
||||||
const rl = readline.createInterface({
|
const rl = readline.createInterface({
|
||||||
input: process.stdin,
|
input: process.stdin,
|
||||||
output: process.stdout,
|
output: process.stdout,
|
||||||
|
|
@ -146,9 +173,13 @@ class MCPClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async cleanup() {
|
async cleanup() {
|
||||||
|
/**
|
||||||
|
* Clean up resources
|
||||||
|
*/
|
||||||
await this.mcp.close();
|
await this.mcp.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
if (process.argv.length < 3) {
|
if (process.argv.length < 3) {
|
||||||
console.log("Usage: node index.ts <path_to_server_script>");
|
console.log("Usage: node index.ts <path_to_server_script>");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue