├── .gitignore
├── LICENSE
├── README.md
├── build.sh
├── install.sh
├── pyproject.toml
├── setup.py
├── src
└── mcp_server_deep_research
│ ├── __init__.py
│ └── server.py
└── uv.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python specific
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | *.so
6 | .Python
7 | env/
8 | build/
9 | develop-eggs/
10 | dist/
11 | downloads/
12 | eggs/
13 | .eggs/
14 | lib/
15 | lib64/
16 | parts/
17 | sdist/
18 | var/
19 | *.egg-info/
20 | .installed.cfg
21 | *.egg
22 | .pytest_cache/
23 | .coverage
24 | htmlcov/
25 | .tox/
26 | .nox/
27 |
28 | # Virtual Environment
29 | venv/
30 | ENV/
31 | env/
32 | .env/
33 |
34 | # IDE specific files
35 | .idea/
36 | .vscode/
37 | *.swp
38 | *.swo
39 | .DS_Store
40 |
41 | # Project specific
42 | .cache/
43 | logs/
44 | *.log
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 ReadingPlus.AI LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MCP Server for Deep Research
2 |
3 | MCP Server for Deep Research is a tool designed for conducting comprehensive research on complex topics. It helps you explore questions in depth, find relevant sources, and generate structured research reports.
4 |
5 | Your personal Research Assistant, turning research questions into comprehensive, well-cited reports.
6 |
7 | ## 🚀 Try it Out
8 |
9 | []([VIDEO_URL](https://youtu.be/_a7sfo5yxoI))
10 | Youtube: https://youtu.be/_a7sfo5yxoI
11 |
12 | 1. **Download Claude Desktop**
13 | - Get it [here](https://claude.ai/download)
14 |
15 | 2. **Install and Set Up**
16 | - On macOS, run the following command in your terminal:
17 | ```bash
18 | python setup.py
19 | ```
20 |
21 | 3. **Start Researching**
22 | - Select the deep-research prompt template from MCP
23 | - Begin your research by providing a research question
24 |
25 | ## Features
26 |
27 | The Deep Research MCP Server offers a complete research workflow:
28 |
29 | 1. **Question Elaboration**
30 | - Expands and clarifies your research question
31 | - Identifies key terms and concepts
32 | - Defines scope and parameters
33 |
34 | 2. **Subquestion Generation**
35 | - Creates focused subquestions that address different aspects
36 | - Ensures comprehensive coverage of the main topic
37 | - Provides structure for systematic research
38 |
39 | 3. **Web Search Integration**
40 | - Uses Claude's built-in web search capabilities
41 | - Performs targeted searches for each subquestion
42 | - Identifies relevant and authoritative sources
43 | - Collects diverse perspectives on the topic
44 |
45 | 4. **Content Analysis**
46 | - Evaluates information quality and relevance
47 | - Synthesizes findings from multiple sources
48 | - Provides proper citations for all sources
49 |
50 | 5. **Report Generation**
51 | - Creates well-structured, comprehensive reports as artifacts
52 | - Properly cites all sources used
53 | - Presents a balanced view with evidence-based conclusions
54 | - Uses appropriate formatting for clarity and readability
55 |
56 | ## 📦 Components
57 |
58 | ### Prompts
59 | - **deep-research**: Tailored for comprehensive research tasks with a structured approach
60 |
61 | ## ⚙️ Modifying the Server
62 |
63 | ### Claude Desktop Configurations
64 | - macOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
65 | - Windows: `%APPDATA%/Claude/claude_desktop_config.json`
66 |
67 | ### Development (Unpublished Servers)
68 | ```json
69 | "mcpServers": {
70 | "mcp-server-deep-research": {
71 | "command": "uv",
72 | "args": [
73 | "--directory",
74 | "/Users/username/repos/mcp-server-application/mcp-server-deep-research",
75 | "run",
76 | "mcp-server-deep-research"
77 | ]
78 | }
79 | }
80 | ```
81 |
82 | ### Published Servers
83 | ```json
84 | "mcpServers": {
85 | "mcp-server-deep-research": {
86 | "command": "uvx",
87 | "args": [
88 | "mcp-server-deep-research"
89 | ]
90 | }
91 | }
92 | ```
93 |
94 | ## 🛠️ Development
95 |
96 | ### Building and Publishing
97 | 1. **Sync Dependencies**
98 | ```bash
99 | uv sync
100 | ```
101 |
102 | 2. **Build Distributions**
103 | ```bash
104 | uv build
105 | ```
106 | Generates source and wheel distributions in the dist/ directory.
107 |
108 | 3. **Publish to PyPI**
109 | ```bash
110 | uv publish
111 | ```
112 |
113 | ## 🤝 Contributing
114 |
115 | Contributions are welcome! Whether you're fixing bugs, adding features, or improving documentation, your help makes this project better.
116 |
117 | ## 📜 License
118 |
119 | This project is licensed under the MIT License.
120 | See the LICENSE file for details.
121 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Build script for the MCP server deep research package
3 |
4 | echo "Building mcp-server-deep-research package..."
5 | cd /Users/hezhang/repos/mcp-server-application/mcp-server-deep-research
6 | uv build
7 |
8 | echo "Done building. The wheel file should be in the dist/ directory."
9 | ls -la dist/
10 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Install script for the MCP server deep research package
3 |
4 | echo "Finding the latest wheel file..."
5 | WHEEL_FILE=$(ls -t /Users/hezhang/repos/mcp-server-application/mcp-server-deep-research/dist/*.whl | head -1)
6 |
7 | if [ -z "$WHEEL_FILE" ]; then
8 | echo "No wheel file found. Please run build.sh first."
9 | exit 1
10 | fi
11 |
12 | echo "Installing wheel file: $WHEEL_FILE"
13 | uv pip install --force-reinstall $WHEEL_FILE
14 |
15 | echo "Creating/updating Claude desktop config..."
16 | CONFIG_DIR="$HOME/Library/Application Support/Claude"
17 | CONFIG_FILE="$CONFIG_DIR/claude_desktop_config.json"
18 |
19 | # Create directory if it doesn't exist
20 | mkdir -p "$CONFIG_DIR"
21 |
22 | # Create or update config file
23 | if [ -f "$CONFIG_FILE" ]; then
24 | # Update existing config
25 | echo "Updating existing Claude config..."
26 |
27 | # Check if jq is installed
28 | if ! command -v jq &> /dev/null; then
29 | echo "jq is not installed. Creating a new config file..."
30 | cat > "$CONFIG_FILE" << EOF
31 | {
32 | "mcpServers": {
33 | "mcp-server-deep-research": {
34 | "command": "mcp-server-deep-research"
35 | }
36 | }
37 | }
38 | EOF
39 | else
40 | # Use jq to update config
41 | jq '.mcpServers."mcp-server-deep-research" = {"command": "mcp-server-deep-research"}' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
42 | fi
43 | else
44 | # Create new config file
45 | echo "Creating new Claude config file..."
46 | cat > "$CONFIG_FILE" << EOF
47 | {
48 | "mcpServers": {
49 | "mcp-server-deep-research": {
50 | "command": "mcp-server-deep-research"
51 | }
52 | }
53 | }
54 | EOF
55 | fi
56 |
57 | echo "Installation complete. Restart Claude to use the updated server."
58 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "mcp-server-deep-research"
3 | version = "0.1.1"
4 | description = "A MCP server for deep research and report generation"
5 | readme = "README.md"
6 | requires-python = ">=3.10"
7 | dependencies = [
8 | "mcp>=1.0.0",
9 | ]
10 |
11 | [[project.authors]]
12 | name = "Xing Xing"
13 | email = "xing@readingplus.ai"
14 |
15 | [build-system]
16 | requires = ["hatchling"]
17 | build-backend = "hatchling.build"
18 |
19 | [project.scripts]
20 | mcp-server-deep-research = "mcp_server_deep_research:main"
21 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """Setup script for MCP server deep research environment."""
3 |
4 | import json
5 | import subprocess
6 | import sys
7 | from pathlib import Path
8 | import re
9 | import time
10 |
11 |
12 | def run_command(cmd, check=True):
13 | """Run a shell command and return output."""
14 | try:
15 | result = subprocess.run(
16 | cmd, shell=True, check=check, capture_output=True, text=True
17 | )
18 | return result.stdout.strip()
19 | except subprocess.CalledProcessError as e:
20 | print(f"Error running command '{cmd}': {e}")
21 | return None
22 |
23 |
24 | def ask_permission(question):
25 | """Ask user for permission."""
26 | while True:
27 | response = input(f"{question} (y/n): ").lower()
28 | if response in ["y", "yes"]:
29 | return True
30 | if response in ["n", "no"]:
31 | return False
32 | print("Please answer 'y' or 'n'")
33 |
34 |
35 | def check_uv():
36 | """Check if uv is installed and install if needed."""
37 | if not run_command("which uv", check=False):
38 | if ask_permission("uv is not installed. Would you like to install it?"):
39 | print("Installing uv...")
40 | run_command("curl -LsSf https://astral.sh/uv/install.sh | sh")
41 | print("uv installed successfully")
42 | else:
43 | sys.exit("uv is required to continue")
44 |
45 |
46 | def setup_venv():
47 | """Create virtual environment if it doesn't exist."""
48 | if not Path(".venv").exists():
49 | if ask_permission("Virtual environment not found. Create one?"):
50 | print("Creating virtual environment...")
51 | run_command("uv venv")
52 | print("Virtual environment created successfully")
53 | else:
54 | sys.exit("Virtual environment is required to continue")
55 |
56 |
57 | def sync_dependencies():
58 | """Sync project dependencies."""
59 | print("Syncing dependencies...")
60 | run_command("uv sync")
61 | print("Dependencies synced successfully")
62 |
63 |
64 | def check_claude_desktop():
65 | """Check if Claude desktop app is installed."""
66 | app_path = "/Applications/Claude.app"
67 | if not Path(app_path).exists():
68 | print("Claude desktop app not found.")
69 | print("Please download and install from: https://claude.ai/download")
70 | if not ask_permission("Continue after installing Claude?"):
71 | sys.exit("Claude desktop app is required to continue")
72 |
73 |
74 | def setup_claude_config():
75 | """Setup Claude desktop config file."""
76 | config_path = Path(
77 | "~/Library/Application Support/Claude/claude_desktop_config.json"
78 | ).expanduser()
79 | config_dir = config_path.parent
80 |
81 | if not config_dir.exists():
82 | config_dir.mkdir(parents=True)
83 |
84 | config = (
85 | {"mcpServers": {}}
86 | if not config_path.exists()
87 | else json.loads(config_path.read_text())
88 | )
89 | return config_path, config
90 |
91 |
92 | def build_package():
93 | """Build package and get wheel path."""
94 | print("Building package...")
95 | try:
96 | # Use Popen for real-time and complete output capture
97 | process = subprocess.Popen(
98 | "uv build",
99 | shell=True,
100 | stdout=subprocess.PIPE,
101 | stderr=subprocess.PIPE,
102 | text=True,
103 | )
104 | stdout, stderr = process.communicate() # Capture output
105 | output = stdout + stderr # Combine both streams
106 | print(f"Raw output: {output}") # Debug: check output
107 | except Exception as e:
108 | sys.exit(f"Error running build: {str(e)}")
109 |
110 | # Check if the command was successful
111 | if process.returncode != 0:
112 | sys.exit(f"Build failed with error code {process.returncode}")
113 |
114 | # Extract wheel file path from the combined output
115 | match = re.findall(r"dist/[^\s]+\.whl", output.strip())
116 | whl_file = match[-1] if match else None
117 | if not whl_file:
118 | sys.exit("Failed to find wheel file in build output")
119 |
120 | # Convert to absolute path
121 | path = Path(whl_file).absolute()
122 | return str(path)
123 |
124 |
125 | def update_config(config_path, config, wheel_path):
126 | """Update Claude config with MCP server settings."""
127 | config.setdefault("mcpServers", {})
128 | config["mcpServers"]["mcp-server-deep-research"] = {
129 | "command": "uvx",
130 | "args": ["--from", wheel_path, "mcp-server-deep-research"],
131 | }
132 |
133 | config_path.write_text(json.dumps(config, indent=2))
134 | print(f"Updated config at {config_path}")
135 |
136 |
137 | def restart_claude():
138 | """Restart Claude desktop app if running."""
139 | if run_command("pgrep -x Claude", check=False):
140 | if ask_permission("Claude is running. Restart it?"):
141 | print("Restarting Claude...")
142 | run_command("pkill -x Claude")
143 | time.sleep(2)
144 | run_command("open -a Claude")
145 | print("Claude restarted successfully")
146 | else:
147 | print("Starting Claude...")
148 | run_command("open -a Claude")
149 |
150 |
151 | def main():
152 | """Main setup function."""
153 | print("Starting setup...")
154 | check_uv()
155 | setup_venv()
156 | sync_dependencies()
157 | check_claude_desktop()
158 | config_path, config = setup_claude_config()
159 | wheel_path = build_package()
160 | update_config(config_path, config, wheel_path)
161 | restart_claude()
162 | print("Setup completed successfully!")
163 |
164 |
165 | if __name__ == "__main__":
166 | main()
167 |
--------------------------------------------------------------------------------
/src/mcp_server_deep_research/__init__.py:
--------------------------------------------------------------------------------
1 | from . import server
2 | import asyncio
3 |
4 | def main():
5 | """Main entry point for the package."""
6 | asyncio.run(server.main())
7 |
8 | # Optionally expose other important items at package level
9 | __all__ = ['main', 'server']
10 |
--------------------------------------------------------------------------------
/src/mcp_server_deep_research/server.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 | import logging
3 | from typing import Any
4 | import json
5 |
6 | # Import MCP server
7 | from mcp.server.models import InitializationOptions
8 | from mcp.types import (
9 | TextContent,
10 | Tool,
11 | Resource,
12 | Prompt,
13 | PromptArgument,
14 | GetPromptResult,
15 | PromptMessage,
16 | )
17 | from mcp.server import NotificationOptions, Server
18 | from pydantic import AnyUrl
19 | import mcp.server.stdio
20 |
21 | logger = logging.getLogger(__name__)
22 | logger.info("Starting deep research server")
23 |
24 |
25 | ### Prompt templates
26 | class DeepResearchPrompts(str, Enum):
27 | DEEP_RESEARCH = "deep-research"
28 |
29 |
30 | class PromptArgs(str, Enum):
31 | RESEARCH_QUESTION = "research_question"
32 |
33 |
34 | PROMPT_TEMPLATE = """
35 | You are a professional researcher tasked with conducting thorough research on a topic and producing a structured, comprehensive report. Your goal is to provide a detailed analysis that addresses the research question systematically.
36 |
37 | The research question is:
38 |
39 |
40 | {research_question}
41 |
42 |
43 | Follow these steps carefully:
44 |
45 | 1.
46 | Elaborate on the research question. Define key terms, clarify the scope, and identify the core issues that need to be addressed. Consider different angles and perspectives that are relevant to the question.
47 |
48 |
49 | 2.
50 | Based on your elaboration, generate 3-5 specific subquestions that will help structure your research. Each subquestion should:
51 | - Address a specific aspect of the main research question
52 | - Be focused and answerable through web research
53 | - Collectively provide comprehensive coverage of the main question
54 |
55 |
56 | 3. For each subquestion:
57 | a.
58 | Search for relevant information using web search. For each subquestion, perform searches with carefully formulated queries.
59 | Extract meaningful content from the search results, focusing on:
60 | - Authoritative sources
61 | - Recent information when relevant
62 | - Diverse perspectives
63 | - Factual data and evidence
64 |
65 | Be sure to properly cite all sources and avoid extensive quotations. Limit quotes to less than 25 words each and use no more than one quote per source.
66 |
67 |
68 | b. Analyze the collected information, evaluating:
69 | - Relevance to the subquestion
70 | - Credibility of sources
71 | - Consistency across sources
72 | - Comprehensiveness of coverage
73 |
74 | 4. Create a beautifully formatted research report as an artifact. Your report should:
75 | - Begin with an introduction framing the research question
76 | - Include separate sections for each subquestion with findings
77 | - Synthesize information across sections
78 | - Provide a conclusion answering the main research question
79 | - Include proper citations of all sources
80 | - Use tables, lists, and other formatting for clarity where appropriate
81 |
82 | The final report should be well-organized, carefully written, and properly cited. It should present a balanced view of the topic, acknowledge limitations and areas of uncertainty, and make clear, evidence-based conclusions.
83 |
84 | Remember these important guidelines:
85 | - Never provide extensive quotes from copyrighted content
86 | - Limit quotes to less than 25 words each
87 | - Use only one quote per source
88 | - Properly cite all sources
89 | - Do not reproduce song lyrics, poems, or other copyrighted creative works
90 | - Put everything in your own words except for properly quoted material
91 | - Keep summaries of copyrighted content to 2-3 sentences maximum
92 |
93 | Please begin your research process, documenting each step carefully.
94 | """
95 |
96 |
97 | ### Research Processor
98 | class ResearchProcessor:
99 | def __init__(self):
100 | self.research_data = {
101 | "question": "",
102 | "elaboration": "",
103 | "subquestions": [],
104 | "search_results": {},
105 | "extracted_content": {},
106 | "final_report": "",
107 | }
108 | self.notes: list[str] = []
109 |
110 | def add_note(self, note: str):
111 | """Add a note to the research process."""
112 | self.notes.append(note)
113 | logger.debug(f"Note added: {note}")
114 |
115 | def update_research_data(self, key: str, value: Any):
116 | """Update a specific key in the research data dictionary."""
117 | self.research_data[key] = value
118 | self.add_note(f"Updated research data: {key}")
119 |
120 | def get_research_notes(self) -> str:
121 | """Return all research notes as a newline-separated string."""
122 | return "\n".join(self.notes)
123 |
124 | def get_research_data(self) -> dict:
125 | """Return the current research data dictionary."""
126 | return self.research_data
127 |
128 |
129 | ### MCP Server Definition
130 | async def main():
131 | research_processor = ResearchProcessor()
132 | server = Server("deep-research-server")
133 |
134 | @server.list_resources()
135 | async def handle_list_resources() -> list[Resource]:
136 | logger.debug("Handling list_resources request")
137 | return [
138 | Resource(
139 | uri="research://notes",
140 | name="Research Process Notes",
141 | description="Notes generated during the research process",
142 | mimeType="text/plain",
143 | ),
144 | Resource(
145 | uri="research://data",
146 | name="Research Data",
147 | description="Structured data collected during the research process",
148 | mimeType="application/json",
149 | ),
150 | ]
151 |
152 | @server.read_resource()
153 | async def handle_read_resource(uri: AnyUrl) -> str:
154 | logger.debug(f"Handling read_resource request for URI: {uri}")
155 | if str(uri) == "research://notes":
156 | return research_processor.get_research_notes()
157 | elif str(uri) == "research://data":
158 | return json.dumps(research_processor.get_research_data(), indent=2)
159 | else:
160 | raise ValueError(f"Unknown resource: {uri}")
161 |
162 | @server.list_prompts()
163 | async def handle_list_prompts() -> list[Prompt]:
164 | logger.debug("Handling list_prompts request")
165 | return [
166 | Prompt(
167 | name=DeepResearchPrompts.DEEP_RESEARCH,
168 | description="A prompt to conduct deep research on a question",
169 | arguments=[
170 | PromptArgument(
171 | name=PromptArgs.RESEARCH_QUESTION,
172 | description="The research question to investigate",
173 | required=True,
174 | ),
175 | ],
176 | )
177 | ]
178 |
179 | @server.get_prompt()
180 | async def handle_get_prompt(
181 | name: str, arguments: dict[str, str] | None
182 | ) -> GetPromptResult:
183 | logger.debug(f"Handling get_prompt request for {name} with args {arguments}")
184 | if name != DeepResearchPrompts.DEEP_RESEARCH:
185 | logger.error(f"Unknown prompt: {name}")
186 | raise ValueError(f"Unknown prompt: {name}")
187 |
188 | if not arguments or PromptArgs.RESEARCH_QUESTION not in arguments:
189 | logger.error("Missing required argument: research_question")
190 | raise ValueError("Missing required argument: research_question")
191 |
192 | research_question = arguments[PromptArgs.RESEARCH_QUESTION]
193 | prompt = PROMPT_TEMPLATE.format(research_question=research_question)
194 |
195 | # Store the research question
196 | research_processor.update_research_data("question", research_question)
197 | research_processor.add_note(
198 | f"Research initiated on question: {research_question}"
199 | )
200 |
201 | logger.debug(
202 | f"Generated prompt template for research_question: {research_question}"
203 | )
204 | return GetPromptResult(
205 | description=f"Deep research template for: {research_question}",
206 | messages=[
207 | PromptMessage(
208 | role="user",
209 | content=TextContent(type="text", text=prompt.strip()),
210 | )
211 | ],
212 | )
213 |
214 | @server.list_tools()
215 | async def handle_list_tools() -> list[Tool]:
216 | logger.debug("Handling list_tools request")
217 | # We're not exposing any tools since we'll be using Claude's built-in web search
218 | return []
219 |
220 | async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
221 | logger.debug("Server running with stdio transport")
222 | await server.run(
223 | read_stream,
224 | write_stream,
225 | InitializationOptions(
226 | server_name="deep-research-server",
227 | server_version="0.1.0",
228 | capabilities=server.get_capabilities(
229 | notification_options=NotificationOptions(),
230 | experimental_capabilities={},
231 | ),
232 | ),
233 | )
234 |
--------------------------------------------------------------------------------
/uv.lock:
--------------------------------------------------------------------------------
1 | version = 1
2 | requires-python = ">=3.10"
3 |
4 | [[package]]
5 | name = "annotated-types"
6 | version = "0.7.0"
7 | source = { registry = "https://pypi.org/simple" }
8 | sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
9 | wheels = [
10 | { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
11 | ]
12 |
13 | [[package]]
14 | name = "anyio"
15 | version = "4.9.0"
16 | source = { registry = "https://pypi.org/simple" }
17 | dependencies = [
18 | { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
19 | { name = "idna" },
20 | { name = "sniffio" },
21 | { name = "typing-extensions", marker = "python_full_version < '3.13'" },
22 | ]
23 | sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 }
24 | wheels = [
25 | { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 },
26 | ]
27 |
28 | [[package]]
29 | name = "certifi"
30 | version = "2025.1.31"
31 | source = { registry = "https://pypi.org/simple" }
32 | sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
33 | wheels = [
34 | { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
35 | ]
36 |
37 | [[package]]
38 | name = "click"
39 | version = "8.1.8"
40 | source = { registry = "https://pypi.org/simple" }
41 | dependencies = [
42 | { name = "colorama", marker = "platform_system == 'Windows'" },
43 | ]
44 | sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
45 | wheels = [
46 | { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 },
47 | ]
48 |
49 | [[package]]
50 | name = "colorama"
51 | version = "0.4.6"
52 | source = { registry = "https://pypi.org/simple" }
53 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
54 | wheels = [
55 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
56 | ]
57 |
58 | [[package]]
59 | name = "exceptiongroup"
60 | version = "1.2.2"
61 | source = { registry = "https://pypi.org/simple" }
62 | sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
63 | wheels = [
64 | { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
65 | ]
66 |
67 | [[package]]
68 | name = "h11"
69 | version = "0.14.0"
70 | source = { registry = "https://pypi.org/simple" }
71 | sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
72 | wheels = [
73 | { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
74 | ]
75 |
76 | [[package]]
77 | name = "httpcore"
78 | version = "1.0.7"
79 | source = { registry = "https://pypi.org/simple" }
80 | dependencies = [
81 | { name = "certifi" },
82 | { name = "h11" },
83 | ]
84 | sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
85 | wheels = [
86 | { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
87 | ]
88 |
89 | [[package]]
90 | name = "httpx"
91 | version = "0.28.1"
92 | source = { registry = "https://pypi.org/simple" }
93 | dependencies = [
94 | { name = "anyio" },
95 | { name = "certifi" },
96 | { name = "httpcore" },
97 | { name = "idna" },
98 | ]
99 | sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
100 | wheels = [
101 | { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
102 | ]
103 |
104 | [[package]]
105 | name = "httpx-sse"
106 | version = "0.4.0"
107 | source = { registry = "https://pypi.org/simple" }
108 | sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
109 | wheels = [
110 | { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
111 | ]
112 |
113 | [[package]]
114 | name = "idna"
115 | version = "3.10"
116 | source = { registry = "https://pypi.org/simple" }
117 | sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
118 | wheels = [
119 | { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
120 | ]
121 |
122 | [[package]]
123 | name = "mcp"
124 | version = "1.5.0"
125 | source = { registry = "https://pypi.org/simple" }
126 | dependencies = [
127 | { name = "anyio" },
128 | { name = "httpx" },
129 | { name = "httpx-sse" },
130 | { name = "pydantic" },
131 | { name = "pydantic-settings" },
132 | { name = "sse-starlette" },
133 | { name = "starlette" },
134 | { name = "uvicorn" },
135 | ]
136 | sdist = { url = "https://files.pythonhosted.org/packages/6d/c9/c55764824e893fdebe777ac7223200986a275c3191dba9169f8eb6d7c978/mcp-1.5.0.tar.gz", hash = "sha256:5b2766c05e68e01a2034875e250139839498c61792163a7b221fc170c12f5aa9", size = 159128 }
137 | wheels = [
138 | { url = "https://files.pythonhosted.org/packages/c1/d1/3ff566ecf322077d861f1a68a1ff025cad337417bd66ad22a7c6f7dfcfaf/mcp-1.5.0-py3-none-any.whl", hash = "sha256:51c3f35ce93cb702f7513c12406bbea9665ef75a08db909200b07da9db641527", size = 73734 },
139 | ]
140 |
141 | [[package]]
142 | name = "mcp-server-deep-research"
143 | version = "0.1.1"
144 | source = { editable = "." }
145 | dependencies = [
146 | { name = "mcp" },
147 | ]
148 |
149 | [package.metadata]
150 | requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
151 |
152 | [[package]]
153 | name = "pydantic"
154 | version = "2.10.6"
155 | source = { registry = "https://pypi.org/simple" }
156 | dependencies = [
157 | { name = "annotated-types" },
158 | { name = "pydantic-core" },
159 | { name = "typing-extensions" },
160 | ]
161 | sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 }
162 | wheels = [
163 | { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 },
164 | ]
165 |
166 | [[package]]
167 | name = "pydantic-core"
168 | version = "2.27.2"
169 | source = { registry = "https://pypi.org/simple" }
170 | dependencies = [
171 | { name = "typing-extensions" },
172 | ]
173 | sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 }
174 | wheels = [
175 | { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 },
176 | { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 },
177 | { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 },
178 | { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 },
179 | { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 },
180 | { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 },
181 | { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 },
182 | { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 },
183 | { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 },
184 | { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 },
185 | { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 },
186 | { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 },
187 | { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 },
188 | { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 },
189 | { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 },
190 | { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 },
191 | { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 },
192 | { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 },
193 | { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 },
194 | { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 },
195 | { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 },
196 | { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 },
197 | { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 },
198 | { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 },
199 | { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 },
200 | { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 },
201 | { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 },
202 | { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 },
203 | { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 },
204 | { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 },
205 | { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 },
206 | { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 },
207 | { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 },
208 | { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 },
209 | { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 },
210 | { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 },
211 | { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 },
212 | { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 },
213 | { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 },
214 | { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 },
215 | { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 },
216 | { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 },
217 | { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 },
218 | { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 },
219 | { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 },
220 | { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 },
221 | { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 },
222 | { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 },
223 | { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 },
224 | { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 },
225 | { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 },
226 | { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 },
227 | { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 },
228 | { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 },
229 | { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
230 | { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 },
231 | { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 },
232 | { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 },
233 | { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 },
234 | { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 },
235 | { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 },
236 | { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 },
237 | { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 },
238 | { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 },
239 | ]
240 |
241 | [[package]]
242 | name = "pydantic-settings"
243 | version = "2.8.1"
244 | source = { registry = "https://pypi.org/simple" }
245 | dependencies = [
246 | { name = "pydantic" },
247 | { name = "python-dotenv" },
248 | ]
249 | sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550 }
250 | wheels = [
251 | { url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839 },
252 | ]
253 |
254 | [[package]]
255 | name = "python-dotenv"
256 | version = "1.0.1"
257 | source = { registry = "https://pypi.org/simple" }
258 | sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
259 | wheels = [
260 | { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
261 | ]
262 |
263 | [[package]]
264 | name = "sniffio"
265 | version = "1.3.1"
266 | source = { registry = "https://pypi.org/simple" }
267 | sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
268 | wheels = [
269 | { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
270 | ]
271 |
272 | [[package]]
273 | name = "sse-starlette"
274 | version = "2.2.1"
275 | source = { registry = "https://pypi.org/simple" }
276 | dependencies = [
277 | { name = "anyio" },
278 | { name = "starlette" },
279 | ]
280 | sdist = { url = "https://files.pythonhosted.org/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419", size = 17376 }
281 | wheels = [
282 | { url = "https://files.pythonhosted.org/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99", size = 10120 },
283 | ]
284 |
285 | [[package]]
286 | name = "starlette"
287 | version = "0.46.1"
288 | source = { registry = "https://pypi.org/simple" }
289 | dependencies = [
290 | { name = "anyio" },
291 | ]
292 | sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 }
293 | wheels = [
294 | { url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 },
295 | ]
296 |
297 | [[package]]
298 | name = "typing-extensions"
299 | version = "4.12.2"
300 | source = { registry = "https://pypi.org/simple" }
301 | sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
302 | wheels = [
303 | { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
304 | ]
305 |
306 | [[package]]
307 | name = "uvicorn"
308 | version = "0.34.0"
309 | source = { registry = "https://pypi.org/simple" }
310 | dependencies = [
311 | { name = "click" },
312 | { name = "h11" },
313 | { name = "typing-extensions", marker = "python_full_version < '3.11'" },
314 | ]
315 | sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 }
316 | wheels = [
317 | { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 },
318 | ]
319 |
--------------------------------------------------------------------------------