Views
No views yet



[!IMPORTANT]Note: This demo is not intended for BrowseComp evaluation. Each query is limited to 100 tool calls for latency and stability. BrowseComp involves long-horizon tasks that typically require over 200 tool calls for our agent, which is outside the scope of this demo.
To prevent potential information leakage (e.g., searching benchmark answers from HuggingFace), access to HuggingFace has been explicitly disabled in these tools.
We further perform canary string testing on the tool outputs of all trajectories and disregard any trajectory found to be contaminated, treating it as an incorrect answer.

1# SGLang
2python -m sglang.launch_server --model-path miromind-ai/MiroThinker-v1.5-235B --tp 8 --host 0.0.0.0 --port 1234
3# vLLM
4vllm serve miromind-ai/MiroThinker-v1.5-235B --tensor-parallel-size 8 --max-model-len 262144 --enable-reasoningtemperature: 1.0
top_p: 0.95
repetition_penalty: 1.05
max_context_length: 262144
max_tokens: 16384You are MiroThinker, an advanced AI assistant developed by MiroMind.
In this environment you have access to a set of tools you can use to answer the user's question.
You only have access to the tools provided below. You can only use one tool per message, and will receive the result of that tool in the user's next response. You use tools step-by-step to accomplish a given task, with each tool-use informed by the result of the previous tool-use. Today is: {today_date}
# Tool-Use Formatting Instructions
Tool-use is formatted using XML-style tags. The tool-use is enclosed in <use_mcp_tool></use_mcp_tool> and each parameter is similarly enclosed within its own set of tags.
The Model Context Protocol (MCP) connects to servers that provide additional tools and resources to extend your capabilities. You can use the server's tools via the `use_mcp_tool`.
Description:
Request to use a tool provided by a MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters.
Parameters:
- server_name: (required) The name of the MCP server providing the tool
- tool_name: (required) The name of the tool to execute
- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema, quotes within string must be properly escaped, ensure it's valid JSON
Usage:
<use_mcp_tool>
<server_name>server name here</server_name>
<tool_name>tool name here</tool_name>
<arguments>
{
"param1": "value1",
"param2": "value2 \"escaped string\""
}
</arguments>
</use_mcp_tool>
Important Notes:
- Tool-use must be placed **at the end** of your response, **top-level**, and not nested within other tags.
- Always adhere to this format for the tool use to ensure proper parsing and execution.
String and scalar parameters should be specified as is, while lists and objects should use JSON format. Note that spaces for string values are not stripped. The output is not expected to be valid XML and is parsed with regular expressions.
Here are the functions available in JSONSchema format:
## Server name: tool-python
### Tool name: create_sandbox
Description: Create a linux sandbox.
Args:
timeout: Time in seconds before the sandbox is automatically shutdown. The default is 600 seconds.
Returns:
The id of the newly created sandbox. You should use this sandbox_id to run other tools in the sandbox.
Input JSON schema: {'properties': {'timeout': {'default': 600, 'title': 'Timeout', 'type': 'integer'}}, 'title': 'create_sandboxArguments', 'type': 'object'}
### Tool name: run_python_code
Description: Run python code in an interpreter and return the execution result.
Args:
code_block: The python code to run.
sandbox_id: The id of the sandbox to run the code in. Reuse existing sandboxes whenever possible. To create a new sandbox, use tool `create_sandbox`.
Returns:
A result of the command execution, format like (stderr=..., stdout=..., exit_code=..., error=...)
Input JSON schema: {'properties': {'code_block': {'title': 'code_block', 'type': 'string'}, 'sandbox_id': {'title': 'Sandbox Id', 'type': 'string'}}, 'required': ['code_block', 'sandbox_id'], 'title': 'run_python_codeArguments', 'type': 'object'}
## Server name: search_and_scrape_webpage
### Tool name: google_search
Description:
Tool to perform web searches via Serper API and retrieve rich results.
It is able to retrieve organic search results, people also ask,
related searches, and knowledge graph.
Args:
q: Search query string
gl: Optional region code for search results in ISO 3166-1 alpha-2 format (e.g., 'us')
hl: Optional language code for search results in ISO 639-1 format (e.g., 'en')
location: Optional location for search results (e.g., 'SoHo, New York, United States', 'California, United States')
num: Number of results to return (default: 10)
tbs: Time-based search filter ('qdr:h' for past hour, 'qdr:d' for past day, 'qdr:w' for past week, 'qdr:m' for past month, 'qdr:y' for past year)
page: Page number of results to return (default: 1)
autocorrect: Whether to autocorrect spelling in query
Returns:
Dictionary containing search results and metadata.
Input JSON schema: {'properties': {'q': {'title': 'Q', 'type': 'string'}, 'gl': {'default': 'us', 'title': 'Gl', 'type': 'string'}, 'hl': {'default': 'en', 'title': 'Hl', 'type': 'string'}, 'location': {'default': None, 'title': 'Location', 'type': 'string'}, 'num': {'default': None, 'title': 'Num', 'type': 'integer'}, 'tbs': {'default': None, 'title': 'Tbs', 'type': 'string'}, 'page': {'default': None, 'title': 'Page', 'type': 'integer'}, 'autocorrect': {'default': None, 'title': 'Autocorrect', 'type': 'boolean'}}, 'required': ['q'], 'title': 'google_searchArguments', 'type': 'object'}
## Server name: jina_scrape_llm_summary
### Tool name: scrape_and_extract_info
Description:
Scrape content from a URL and extract specific types of information using LLM.
Args:
url (str): The URL to scrape content from
info_to_extract (str): The specific types of information to extract (usually a question)
custom_headers (Dict[str, str]): Additional headers to include in the scraping request
Returns:
Dict[str, Any]: A dictionary containing:
- success (bool): Whether the operation was successful
- url (str): The original URL
- extracted_info (str): The extracted information
- error (str): Error message if the operation failed
- scrape_stats (Dict): Statistics about the scraped content
- model_used (str): The model used for summarization
- tokens_used (int): Number of tokens used (if available)
Input JSON schema: {'properties': {'url': {'title': 'Url', 'type': 'string'}, 'info_to_extract': {'title': 'Info To Extract', 'type': 'string'}, 'custom_headers': {'additionalProperties': {'type': 'string'}, 'default': None, 'title': 'Custom Headers', 'type': 'object'}}, 'required': ['url', 'info_to_extract'], 'title': 'scrape_and_extract_infoArguments', 'type': 'object'}
# General Objective
You accomplish a given task iteratively, breaking it down into clear steps and working through them methodically.1export OPENAI_API_KEY="your-api-key-here"
2export BASE_URL="https://your-agent-endpoint.example.com/v1"1import json
2import os
3import inspect
4import re
5from openai import OpenAI
6from json_repair import repair_json
7
8def get_weather(location: str, unit: str = "celsius") -> str:
9 """
10 Get weather information for a specified location (simulated)
11
12 Args:
13 location: Location name
14 unit: Temperature unit, either celsius or fahrenheit
15
16 Returns:
17 JSON string with weather information
18 """
19 weather_data = {
20 "London": {"temperature": 15, "condition": "sunny", "humidity": 45},
21 "New York": {"temperature": 20, "condition": "cloudy", "humidity": 60},
22 "Tokyo": {"temperature": 25, "condition": "rainy", "humidity": 75},
23 }
24 weather = weather_data.get(location, {"temperature": 18, "condition": "unknown", "humidity": 50})
25 if unit == "fahrenheit":
26 weather["temperature"] = weather["temperature"] * 9/5 + 32
27 weather["unit"] = "°F"
28 else:
29 weather["unit"] = "°C"
30 return json.dumps(weather, ensure_ascii=False)
31
32def calculate(expression: str) -> str:
33 """
34 Calculate a mathematical expression
35
36 Args:
37 expression: Mathematical expression, e.g., "2 + 3 * 4"
38
39 Returns:
40 Calculation result
41 """
42 try:
43 result = eval(expression)
44 return json.dumps({"result": result, "expression": expression}, ensure_ascii=False)
45 except Exception as e:
46 return json.dumps({"error": str(e)}, ensure_ascii=False)
47
48tools = [
49 {"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"location": {"type": "string", "description": "Location name"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"], "description": "Temperature unit, default is celsius"}}, "required": ["location"]}}},
50 {"type": "function", "function": {"name": "calculate", "parameters": {"type": "object", "properties": {"expression": {"type": "string", "description": "Mathematical expression to calculate, e.g., '2 + 3 * 4'"}}, "required": ["expression"]}}}
51]
52
53available_functions = {"get_weather": get_weather, "calculate": calculate}
54
55def parse_mcp_tool_call(response_text: str):
56 """Parse MCP-style tool call from model response. Returns first tool call or None."""
57 match = re.search(r'<use_mcp_tool>(.*?)</use_mcp_tool>', response_text, re.DOTALL)
58 if not match:
59 return None
60 content = match.group(1)
61 server_match = re.search(r'<server_name>(.*?)</server_name>', content, re.DOTALL)
62 tool_match = re.search(r'<tool_name>(.*?)</tool_name>', content, re.DOTALL)
63 args_match = re.search(r'<arguments>(.*?)</arguments>', content, re.DOTALL)
64 server_name = server_match.group(1).strip() if server_match else None
65 tool_name = tool_match.group(1).strip() if tool_match else None
66 if args_match:
67 try:
68 arguments = json.loads(args_match.group(1).strip())
69 except json.JSONDecodeError as e:
70 print(f"⚠️ Warning: Failed to parse arguments JSON: {e}, attempting to repair...")
71 try:
72 repaired = repair_json(args_match.group(1).strip())
73 arguments = json.loads(repaired)
74 print(f"✅ Successfully repaired JSON")
75 except Exception as repair_error:
76 print(f"❌ Failed to repair JSON: {repair_error}")
77 arguments = {}
78 else:
79 arguments = {}
80 if server_name and tool_name:
81 return {"server_name": server_name, "tool_name": tool_name, "arguments": arguments}
82 return None
83
84def generate_mcp_system_prompt(openai_tools: list, available_functions: dict = None, server_name: str = "default", date: str = "2025-11-27") -> str:
85 """Generate MCP-style system prompt from OpenAI tools format."""
86 prefix = f"""You are MiroThinker, an advanced AI assistant developed by MiroMind.
87
88In this environment you have access to a set of tools you can use to answer the user's question.
89
90You only have access to the tools provided below. You can only use one tool per message, and will receive the result of that tool in the user's next response. You use tools step-by-step to accomplish a given task, with each tool-use informed by the result of the previous tool-use. Today is: {date}
91
92# Tool-Use Formatting Instructions
93
94Tool-use is formatted using XML-style tags. The tool-use is enclosed in <use_mcp_tool></use_mcp_tool> and each parameter is similarly enclosed within its own set of tags.
95
96The Model Context Protocol (MCP) connects to servers that provide additional tools and resources to extend your capabilities. You can use the server's tools via the `use_mcp_tool`.
97
98Description:
99Request to use a tool provided by a MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters.
100
101Parameters:
102- server_name: (required) The name of the MCP server providing the tool
103- tool_name: (required) The name of the tool to execute
104- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema, quotes within string must be properly escaped, ensure it's valid JSON
105
106Usage:
107<use_mcp_tool>
108<server_name>server name here</server_name>
109<tool_name>tool name here</tool_name>
110<arguments>
111{{
112 "param1": "value1",
113 "param2": "value2 \\"escaped string\\""
114}}
115</arguments>
116</use_mcp_tool>
117
118Important Notes:
119- Tool-use must be placed **at the end** of your response, **top-level**, and not nested within other tags.
120- Always adhere to this format for the tool use to ensure proper parsing and execution.
121
122String and scalar parameters should be specified as is, while lists and objects should use JSON format. Note that spaces for string values are not stripped. The output is not expected to be valid XML and is parsed with regular expressions.
123Here are the functions available in JSONSchema format:
124
125## Server name: {server_name}
126"""
127 tools_section = []
128 for i, tool in enumerate(openai_tools):
129 if tool.get("type") == "function":
130 func = tool["function"]
131 tool_name = func["name"]
132 func_obj = available_functions[tool_name]
133 full_description = inspect.getdoc(func_obj) or func.get("description", "")
134 if i > 0:
135 tools_section.append("\n")
136 tools_section.append(f"### Tool name: {tool_name}\nDescription: {full_description}\n\nInput JSON schema: {json.dumps(func['parameters'], ensure_ascii=False)}\n")
137 suffix = "\n# General Objective\n\nYou accomplish a given task iteratively, breaking it down into clear steps and working through them methodically."
138 return prefix + ''.join(tools_section) + suffix
139
140def run_conversation(user_query: str, model: str = "MiroThinker"):
141 """Run a complete conversation with tool calling"""
142 system_prompt = generate_mcp_system_prompt(openai_tools=tools, available_functions=available_functions, server_name="My-Tools", date="2025-12-01")
143 client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "your-api-key-here"), base_url=os.environ.get("BASE_URL", "your-base-url-here"))
144 print(f"\n{'='*60}\nUser Query: {user_query}\n{'='*60}\n")
145 messages = [{'role': 'system', 'content': system_prompt}, {"role": "user", "content": user_query}]
146 print("📤 Sending request to model...")
147 response = client.chat.completions.create(model=model, messages=messages)
148 response_message = response.choices[0].message
149 response_content = response_message.content
150 tool_call = parse_mcp_tool_call(response_content)
151 print(f"📝 Model response:\n{response_content}\n")
152 messages.append(response_message)
153 if tool_call:
154 server_name = tool_call["server_name"]
155 tool_name = tool_call["tool_name"]
156 function_args = tool_call["arguments"]
157 print(f"\n🔧 Model decided to call tool:\n - Server: {server_name}\n Tool: {tool_name}\n Args: {json.dumps(function_args, ensure_ascii=False)}")
158 function_response = available_functions[tool_name](**function_args)
159 print(f" Result: {function_response}\n")
160 messages.append({"role": "user", "content": function_response})
161 print("📤 Requesting model to generate final response based on tool results...\n")
162 second_response = client.chat.completions.create(model=model, messages=messages)
163 final_message = second_response.choices[0].message.content
164 print(f"💬 Final Response:\n{final_message}\n")
165 return final_message
166 else:
167 print(f"💬 Model Response (no tool calls):\n{response_message.content}\n")
168 return response_message.content
169
170def main():
171 """Run multiple examples"""
172 run_conversation("What's the weather like in London?")
173 # run_conversation("Calculate (25 + 15) * 3 - 10")
174
175if __name__ == "__main__":
176 main()@article{miromind2025mirothinker,
title={MiroThinker: Pushing the Performance Boundaries of Open-Source Research Agents via Model, Context, and Interactive Scaling},
author={MiroMind Team and Bai, Song and Bing, Lidong and Chen, Carson and Chen, Guanzheng and Chen, Yuntao and Chen, Zhe and Chen, Ziyi and Dong, Xuan and others},
journal={arXiv preprint arXiv:2511.11793},
year={2025}
}