modelcontextprotocol / modelcontextprotocol/typescript-sdk

The MCP client using a tool launched with uvx does not terminate.

Open
#320 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs confirmation potentially close
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

Describe the bug
As shown in the attached sample, a client that uses a tool launched with uvx does not terminate.
While it is possible to forcefully terminate the process using something like process.exit(0), doing so leaves the uvx cache in a state where it appears to still be in use by the MCP client process.
This issue does not seem to occur when using npx instead.
A similar issue also occurs on Windows Claude Desktop as well.

To Reproduce
Run the attached sample.

Expected behavior
Exit the client process.

==========

import { Anthropic } from "@anthropic-ai/sdk";
import {
  MessageParam,
  Tool,
  ToolUseBlock,
} from "@anthropic-ai/sdk/resources/messages/messages.mjs";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import dotenv from "dotenv";

dotenv.config();

if (!process.env.ANTHROPIC_API_KEY) {
  throw new Error("ANTHROPIC_API_KEY is not set");
}

const anthropic = new Anthropic();
const anthropicTools: Tool[] = [];

const mcp = new Client({ name: "test-client", version: "1.0.0" });
  
const transport = new StdioClientTransport({
  command: "uvx",
  args: [ "mcp-server-time", "--local-timezone=Asia/Tokyo" ],
});
await mcp.connect(transport);
  
const toolsResult = await mcp.listTools();
for (const tool of toolsResult.tools) {
  anthropicTools.push({
    name: tool.name,
    description: tool.description,
    input_schema: tool.inputSchema,
  });
}

console.log("MCP Client Started!");

const messages: MessageParam[] = [
  {
    role: "user",
    content: "What time is it now?",
  },
];

const response = await anthropic.messages.create({
  model: "claude-3-5-sonnet-20241022",
  max_tokens: 1000,
  messages,
  tools: anthropicTools,
});
messages.push({
  role: "assistant",
  content: response.content,
});

for (const content of response.content) {
  if (content.type === "text") {
    console.log("<<<" + content.text + ">>>");
  } else if (content.type === "tool_use") {
    const toolName = content.name;
    const toolArgs = content.input as { [x: string]: unknown } | undefined;
    console.log(`[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`);
    const result = await mcp.callTool({
      name: toolName,
      arguments: toolArgs,
    });
    console.log(`[Result of tool ${toolName}]: ${JSON.stringify(result.content, null, 2)}`);
    messages.push({
      role: "user",
      content: [{
          type: "tool_result",
          tool_use_id: content.id,
          content: result.content as string,
        },
      ]
    });
    const response = await anthropic.messages.create({
      model: "claude-3-5-sonnet-20241022",
      max_tokens: 1000,
      messages,
    });
    for (const content of response.content) {
      if (content.type === "text") {
        console.log("<<<" + content.text + ">>>");
      }
    }
  }
}

await mcp.close();

console.log("MCP Client Closed!");

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the attached TypeScript sample with StdioClientTransport and the uvx command. Trace the lifecycle from mcp.connect through mcp.close, comparing the uvx behavior with the npx behavior described in the issue. Done means the client exits normally without process.exit(0), and the uvx cache is not left appearing in use.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.