Skip to content

Commit 61bc522

Browse files
committed
fix mcp
Signed-off-by: Chen Zhang <[email protected]>
1 parent 9db3300 commit 61bc522

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

vllm/entrypoints/context.py

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
# SPDX-License-Identifier: Apache-2.0
22
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3+
import json
34
import logging
45
from abc import ABC, abstractmethod
6+
from typing import TYPE_CHECKING, Union
57

6-
from openai_harmony import Message, Role, StreamState
8+
from openai_harmony import Author, Message, Role, StreamState, TextContent
79

810
from vllm.entrypoints.harmony_utils import (
911
get_encoding, get_streamable_parser_for_assistant, render_for_completion)
1012
from vllm.entrypoints.tool import Tool
1113
from vllm.outputs import RequestOutput
1214

15+
if TYPE_CHECKING:
16+
from mcp.client import ClientSession
17+
1318
logger = logging.getLogger(__name__)
1419

1520

@@ -107,19 +112,41 @@ async def call_tool(self) -> list[Message]:
107112
def render_for_completion(self) -> list[int]:
108113
return render_for_completion(self.messages)
109114

110-
async def call_search_tool(
111-
self,
112-
tool_session: Tool,
113-
last_msg: Message,
114-
) -> list[Message]:
115-
return await tool_session.get_result(self)
116-
117-
async def call_python_tool(
118-
self,
119-
tool_session: Tool,
120-
last_msg: Message,
121-
) -> list[Message]:
122-
return await tool_session.get_result(self)
115+
async def call_search_tool(self, tool_session: Union["ClientSession",
116+
Tool],
117+
last_msg: Message) -> list[Message]:
118+
if isinstance(tool_session, Tool):
119+
return await tool_session.get_result(self)
120+
tool_name = last_msg.recipient.split(".")[1]
121+
args = json.loads(last_msg.content[0].text)
122+
result = await tool_session.call_tool(tool_name, args)
123+
result_str = result.content[0].text
124+
content = TextContent(text=result_str)
125+
author = Author(role=Role.TOOL, name=last_msg.recipient)
126+
return [
127+
Message(author=author, content=[content], recipient=Role.ASSISTANT)
128+
]
129+
130+
async def call_python_tool(self, tool_session: Union["ClientSession",
131+
Tool],
132+
last_msg: Message) -> list[Message]:
133+
if isinstance(tool_session, Tool):
134+
return await tool_session.get_result(self)
135+
param = {
136+
"code": last_msg.content[0].text,
137+
}
138+
result = await tool_session.call_tool("python", param)
139+
result_str = result.content[0].text
140+
141+
content = TextContent(text=result_str)
142+
author = Author(role=Role.TOOL, name="python")
143+
144+
return [
145+
Message(author=author,
146+
content=[content],
147+
channel=last_msg.channel,
148+
recipient=Role.ASSISTANT)
149+
]
123150

124151

125152
class StreamingHarmonyContext(HarmonyContext):

vllm/entrypoints/openai/serving_responses.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
# yapf: enable
5454
from vllm.entrypoints.openai.serving_engine import OpenAIServing
5555
from vllm.entrypoints.openai.serving_models import OpenAIServingModels
56-
from vllm.entrypoints.tool_server import ToolServer
56+
from vllm.entrypoints.tool_server import MCPToolServer, ToolServer
5757
from vllm.inputs.data import TokensPrompt as EngineTokensPrompt
5858
from vllm.logger import init_logger
5959
from vllm.outputs import CompletionOutput
@@ -237,6 +237,15 @@ async def create_responses(
237237
if raw_request:
238238
raw_request.state.request_metadata = request_metadata
239239

240+
if self.tool_server is not None and isinstance(
241+
self.tool_server, MCPToolServer
242+
) and (request.background or request.stream) and request.tools and any(
243+
tool.type in ["web_search_preview", "code_interpreter"]
244+
for tool in request.tools):
245+
return self.create_error_response(
246+
"MCP tool server is not supported in background mode and "
247+
"streaming mode")
248+
240249
# Schedule the request and get the result generator.
241250
generators: list[AsyncGenerator[ConversationContext, None]] = []
242251

vllm/entrypoints/tool_server.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from contextlib import AbstractAsyncContextManager, asynccontextmanager
55
from typing import TYPE_CHECKING, Any, Optional
66

7-
from openai_harmony import ToolNamespaceConfig
7+
from openai_harmony import ToolDescription, ToolNamespaceConfig
88

99
from vllm.entrypoints.tool import HarmonyBrowserTool, HarmonyPythonTool, Tool
1010
from vllm.logger import init_logger
@@ -105,7 +105,6 @@ def __init__(self):
105105
self.harmony_tool_descriptions = {}
106106

107107
async def add_tool_server(self, server_url: str):
108-
from mcp.types import ToolDescription
109108
tool_urls = server_url.split(",")
110109
self.harmony_tool_descriptions = {}
111110
self.urls: dict[str, str] = {}
@@ -133,6 +132,8 @@ async def add_tool_server(self, server_url: str):
133132
logger.warning(
134133
"Tool %s already exists. Ignoring duplicate tool server %s",
135134
tool_from_mcp.name, url)
135+
logger.info("MCPToolServer initialized with tools: %s",
136+
list(self.harmony_tool_descriptions.keys()))
136137

137138
def has_tool(self, tool_name: str):
138139
return tool_name in self.harmony_tool_descriptions

0 commit comments

Comments
 (0)