main
py 182 lines 5.89 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Example demonstrating MCP (Model Context Protocol) tools with the Responses API.
4
5 This example shows how to use MCP tools with different allowed_tools configurations:
6 1. No filter (allows all tools from the MCP server)
7 2. Wildcard "*" (explicitly allows all tools)
8 3. Specific tool names (filters to only those tools)
9
10 Set up this example by starting a vLLM OpenAI-compatible server with MCP tools enabled.
11 For example:
12 vllm serve openai/gpt-oss-20b --enforce-eager --tool-server demo
13
14 Environment variables:
15 - VLLM_ENABLE_RESPONSES_API_STORE=1
16 - VLLM_GPT_OSS_SYSTEM_TOOL_MCP_LABELS=code_interpreter,container
17 - VLLM_GPT_OSS_HARMONY_SYSTEM_INSTRUCTIONS=1
18 """
19
20 from openai import OpenAI
21
22
23 def example_no_filter():
24 """Example with no allowed_tools filter - allows all tools."""
25 print("=" * 60)
26 print("Example 1: No allowed_tools filter (allows all tools)")
27 print("=" * 60)
28
29 base_url = "http://0.0.0.0:8000/v1"
30 client = OpenAI(base_url=base_url, api_key="empty")
31 model = client.models.list().data[0].id
32
33 response = client.responses.create(
34 model=model,
35 input="Execute this code: print('Hello from Python!')",
36 instructions="Use the Python tool to execute code.",
37 tools=[
38 {
39 "type": "mcp",
40 "server_label": "code_interpreter",
41 "server_url": "http://localhost:8888",
42 # No allowed_tools specified - all tools are available
43 }
44 ],
45 )
46
47 print(f"Status: {response.status}")
48 print(f"Output: {response.output_text}")
49 print()
50
51
52 def example_wildcard():
53 """Example with allowed_tools=['*'] - explicitly allows all tools."""
54 print("=" * 60)
55 print("Example 2: allowed_tools=['*'] (select all tools)")
56 print("=" * 60)
57
58 base_url = "http://0.0.0.0:8000/v1"
59 client = OpenAI(base_url=base_url, api_key="empty")
60 model = client.models.list().data[0].id
61
62 response = client.responses.create(
63 model=model,
64 input="Execute this code: print('Hello from Python with wildcard!')",
65 instructions="Use the Python tool to execute code.",
66 tools=[
67 {
68 "type": "mcp",
69 "server_label": "code_interpreter",
70 "server_url": "http://localhost:8888",
71 # Using "*" to explicitly allow all tools from this MCP server
72 # This is equivalent to not specifying allowed_tools
73 "allowed_tools": ["*"],
74 }
75 ],
76 )
77
78 print(f"Status: {response.status}")
79 print(f"Output: {response.output_text}")
80 print()
81
82
83 def example_specific_tools():
84 """Example with specific allowed_tools list - filters available tools.
85
86 Note: This example uses 'web_search_preview' (browser) which has multiple
87 sub-tools: 'search', 'open', 'find'. The code_interpreter (python) doesn't
88 have sub-tools, so filtering doesn't apply there.
89 """
90 print("=" * 60)
91 print("Example 3: allowed_tools=['search'] (filter browser to specific tools)")
92 print("=" * 60)
93
94 base_url = "http://0.0.0.0:8000/v1"
95 client = OpenAI(base_url=base_url, api_key="empty")
96 model = client.models.list().data[0].id
97
98 response = client.responses.create(
99 model=model,
100 input="Search for 'Python programming tutorials'",
101 instructions="Use the browser tool to search.",
102 tools=[
103 {
104 "type": "mcp",
105 "server_label": "web_search_preview",
106 "server_url": "http://localhost:8888",
107 # Browser has tools: 'search', 'open', 'find'
108 # Only allow 'search' - blocks 'open' and 'find'
109 "allowed_tools": ["search"],
110 }
111 ],
112 )
113
114 print(f"Status: {response.status}")
115 print(f"Output: {response.output_text}")
116 print()
117
118
119 def example_object_format():
120 """Example using object format for allowed_tools with browser tools."""
121 print("=" * 60)
122 print("Example 4: allowed_tools with object format")
123 print("=" * 60)
124
125 base_url = "http://0.0.0.0:8000/v1"
126 client = OpenAI(base_url=base_url, api_key="empty")
127 model = client.models.list().data[0].id
128
129 response = client.responses.create(
130 model=model,
131 input="Search for 'machine learning' and open the first result",
132 instructions="Use the browser tool.",
133 tools=[
134 {
135 "type": "mcp",
136 "server_label": "web_search_preview",
137 "server_url": "http://localhost:8888",
138 # Object format with tool_names field
139 # Can also include read_only and other fields
140 # Browser has tools: 'search', 'open', 'find'
141 "allowed_tools": {
142 "tool_names": [
143 "search",
144 "open",
145 ], # Allow search and open, block find
146 "read_only": False,
147 },
148 }
149 ],
150 )
151
152 print(f"Status: {response.status}")
153 print(f"Output: {response.output_text}")
154 print()
155
156
157 def main():
158 """Run all examples."""
159 print("\n" + "=" * 60)
160 print("MCP Tools with allowed_tools Examples")
161 print("=" * 60 + "\n")
162
163 # Run all examples
164 example_no_filter()
165 example_wildcard()
166 example_specific_tools()
167 example_object_format()
168
169 print("=" * 60)
170 print("Summary:")
171 print(" - No filter or '*' → All tools available from server")
172 print(" - Specific list → Only those sub-tools available")
173 print(" - Object format → More control with tool_names field")
174 print("")
175 print("Note: allowed_tools filters SUB-TOOLS within an MCP server:")
176 print(" - code_interpreter (python): No sub-tools to filter")
177 print(" - web_search_preview (browser): Has 'search', 'open', 'find'")
178 print("=" * 60)
179
180
181 if __name__ == "__main__":
182 main()