├── .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 | [![Watch the demo](https://img.youtube.com/vi/_a7sfo5yxoI/maxresdefault.jpg)]([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 | --------------------------------------------------------------------------------