Skip to content

The mcp client connect failed #327

@zhouhao27

Description

@zhouhao27

Here is my MCP client app:

class MCPClient {
  private mcp: Client;
  private openai: OpenAI;
  private transport: StdioClientTransport | null = null;
  private tools: ChatCompletionTool[] = [];

  constructor() {
    this.openai = new OpenAI({
      baseURL: OLLAMA_BASE_URL,
      apiKey: OLLAMA_API_KEY || "ollama", // Ollama doesn't require an API key for local instances
    });
    this.mcp = new Client({ name: "mcp-client-cli", version: "1.0.0" });
    console.log("MCP Client initialized");
  }

  async connectToServer() {
    const transport = new StdioClientTransport({
      command: "node",
      args: ["../mcp-servers/echo/build/index.js"],
    });

    await this.mcp.connect(transport);
    console.log("Connected to server");

    this.transport = transport;
  }

  async processQuery(query: string) {
    const messages: ChatCompletionMessageParam[] = [
      {
        role: "user",
        content: query,
      },
    ];

    try {
      const response = await this.openai.chat.completions.create({
        model: OLLAMA_MODEL,
        messages,
        tools: this.tools,
      });

      const finalText = [];
      const toolResults = [];
      
      // Get the assistant's response
      const assistantMessage = response.choices[0].message;
      
      // Check if there's a text response
      if (assistantMessage.content) {
        finalText.push(assistantMessage.content);
      }
      
      // Check if there are tool calls
      if (assistantMessage.tool_calls && assistantMessage.tool_calls.length > 0) {
        for (const toolCall of assistantMessage.tool_calls) {
          const toolName = toolCall.function.name;
          let toolArgs;
          
          try {
            toolArgs = JSON.parse(toolCall.function.arguments);
          } catch (e) {
            console.error("Failed to parse tool arguments:", e);
            toolArgs = {};
          }
          
          const result = await this.mcp.callTool({
            name: toolName,
            arguments: toolArgs,
          });
          
          toolResults.push(result);
          finalText.push(
            `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`
          );
          
          // Add the tool result to the messages
          messages.push({
            role: "user",
            content: result.content as string,
          });
          
          // Get a follow-up response from the model
          const followUpResponse = await this.openai.chat.completions.create({
            model: OLLAMA_MODEL,
            max_tokens: 1000,
            messages,
          });
          
          if (followUpResponse.choices[0].message.content) {
            finalText.push(followUpResponse.choices[0].message.content);
          }
        }
      }
      
      return finalText.join("\n");
    } catch (error) {
      console.error("Error querying Ollama:", error);
      return `Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`;
    }

  }

  async chatLoop() {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });

    try {
      console.log("\nMCP Client Started!");
      console.log("Type your queries or 'quit' to exit.");

      while (true) {
        const message = await rl.question("\nQuery: ");
        if (message.toLowerCase() === "quit") {
          break;
        }
        const response = await this.processQuery(message);
        console.log("\n" + response);
      }
    } finally {
      rl.close();
    }
  }

  async cleanup() {
    await this.mcp.close();
  }
}

async function main() {
  const mcpClient = new MCPClient();
  try {
    await mcpClient.connectToServer(); 
    await mcpClient.chatLoop();
  } finally {
    await mcpClient.cleanup();
    process.exit(0);
  }
}

main();

Every time, the app exit without any console log when I call await this.mcp.connect(transport);. The MCP server is in the correct path. Here is the code:

import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

const server = new McpServer({
  name: "Echo",
  version: "1.0.0"
});

server.resource(
  "echo",
  new ResourceTemplate("echo://{message}", { list: undefined }),
  async (uri, { message }) => ({
    contents: [{
      uri: uri.href,
      text: `Resource echo: ${message}`
    }]
  })
);

server.tool(
  "echo",
  { message: z.string() },
  async ({ message }) => ({
    content: [{ type: "text", text: `Tool echo: ${message}` }]
  })
);

server.prompt(
  "echo",
  { message: z.string() },
  ({ message }) => ({
    messages: [{
      role: "user",
      content: {
        type: "text",
        text: `Please process this message: ${message}`
      }
    }]
  })
);

export default server;

I compile it with tsc command. The result is in build/index.js.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions