├── .gitignore ├── .python-version ├── Makefile ├── README.md ├── pyproject.toml ├── scripts ├── img.png ├── img_1.png ├── img_2.png ├── img_3.png ├── img_4.png ├── old.py ├── output.json └── run.sh ├── storm_mcp_server ├── __init__.py ├── core │ ├── __init__.py │ ├── file_manager.py │ └── internal_api.py ├── main.py └── tools │ ├── __init__.py │ ├── tool_definitions.py │ ├── tool_handlers.py │ └── tool_upload_file.py └── uv.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | storm_mcp_server/__pycache__/ 3 | storm_mcp_server/core/__pycache__/ 4 | storm_mcp_server/tools/__pycache__/ 5 | 6 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.12 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: format check 2 | 3 | format: 4 | ruff format storm_mcp_server 5 | 6 | check: 7 | ruff check storm_mcp_server 8 | 9 | run: 10 | sh ./scripts/run.sh 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Storm MCP Server with Sionic AI serverless RAG 2 | 3 | ## Korean (한국어) 4 | 5 | ### Storm MCP(Model Context Protocol) Server 6 | 7 | Storm MCP(Model Context Protocol) 서버는 LLM 애플리케이션과 RAG 데이터 소스 및 도구들 간의 원활한 통합을 가능하게 하는 개방형 프로토콜입니다. 8 | Anthropic의 [Model Context Protocol](https://modelcontextprotocol.io/introduction)을 구현하여 Claude Desktop에서 Storm Platform을 바로 이용합니다. 9 | 10 | Sionic AI 의 [Storm Platform](https://sionicstorm.ai) 를 통합해서 사용하여 나만의 강력한 임베딩 모델과 벡터DB 제품군을 연결하여 사용할 수 있습니다. 11 | https://sionicstorm.ai 에서 에이전트 단위로 가입하여서 API Token을 얻어서 RAG 솔루션을 바로 만드실 수 있습니다. 12 | 13 | #### 사용 예시 14 | ![example image](scripts/img.png) 15 | ![example image 2](scripts/img_3.png) 16 | ![example image 3](scripts/img_4.png) 17 | 18 | API Key는 `scripts/run.sh` 에 존재하는 `export STORM_API_KEY=''` 에 입력하세요. 19 | 20 | #### 주요 기능 21 | 22 | - **컨텍스트 공유**: LLM과 데이터 소스 간의 상호작용을 위한 표준 프로토콜을 제공합니다. 23 | - **도구 시스템**: 도구를 정의하고 호출하는 표준화된 방식을 제공합니다(send_nonstream_chat, list_agents, list_buckets, upload_document_by_file 등). 24 | - **파일 관리**: 파일 업로드, 읽기 및 관리를 위한 파일 시스템 작업을 구현합니다. 25 | - **API 통합**: Storm의 API 엔드포인트와 연결하여 다양한 기능을 제공합니다. 26 | 27 | #### 프로젝트 구조 28 | 29 | - **main.py**: MCP 서버를 초기화하고 이벤트 핸들러를 설정합니다. 30 | - **core/file_manager.py**: 파일 작업을 위한 `FileSystemManager` 클래스를 구현합니다. 31 | - **core/internal_api.py**: Storm의 REST API 엔드포인트와 상호 작용하기 위한 API 클라이언트 함수를 포함합니다. 32 | - **tools/tool_definitions.py**: MCP 서버에서 사용 가능한 도구를 정의합니다. 33 | - **tools/tool_handlers.py**: 도구 작업을 위한 핸들러를 구현합니다. 34 | - **tools/tool_upload_file.py**: 자체 MCP 핸들러가 있는 파일 작업을 위한 별도의 파일 서버를 구현합니다. 35 | 36 | #### 아키텍처 37 | 38 | MCP는 호스트(LLM 애플리케이션), 클라이언트(프로토콜 구현체), 서버(기능 제공자) 간의 3계층 구조로 설계되었습니다. Storm MCP 서버는 이 중 서버 부분을 구현하여 리소스와 도구를 LLM에 제공합니다. 39 | 40 | #### 시작하기 41 | **Claude Desktop** 환경에서 MCP 서버를 연결하려면, 아래와 같은 설정을 적용해야 합니다. 42 | 43 | ![example image](scripts/img_1.png) 44 | 45 | 1) 설정 파일 열기 46 | ```bash 47 | code ~/Library/Application\ Support/Claude/claude_desktop_config.json 48 | ``` 49 | 50 | 2) JSON 내부에 MCP 서버 설정 추가: 51 | ```json 52 | { 53 | "mcpServers": { 54 | "storm": { 55 | "command": "sh", 56 | "args": [ 57 | "/Users/sigridjineth/Desktop/work/storm-mcp-server/scripts/run.sh" 58 | ] 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | ## Japanese (日本語) 65 | 66 | ### Storm MCP(Model Context Protocol) Server 67 | 68 | Storm MCP(Model Context Protocol) サーバーは、LLMアプリケーションとRAGデータソースおよびツール間のシームレスな統合を可能にするオープンプロトコルです。 69 | Anthropicの[Model Context Protocol](https://modelcontextprotocol.io/introduction)を実装し、Claude DesktopでStorm Platformを直接利用できます。 70 | 71 | Sionic AI の [Storm Platform](https://sionicstorm.ai) を統合して使用することで、自分だけの強力な埋め込みモデルとベクターDB製品群を接続して利用できます。 72 | https://sionicstorm.ai でエージェント単位で登録してAPIトークンを取得し、すぐにRAGソリューションを作成できます。 73 | 74 | #### 使用例 75 | ![example image](scripts/img.png) 76 | ![example image 2](scripts/img_3.png) 77 | ![example image 3](scripts/img_4.png) 78 | 79 | APIキーは `scripts/run.sh` の `export STORM_API_KEY=''` に入力してください。 80 | 81 | #### 主な機能 82 | 83 | - **コンテキスト共有**: LLMとデータソース間の相互作用のための標準プロトコルを提供します。 84 | - **ツールシステム**: ツールを定義し呼び出すための標準化された方法を提供します(send_nonstream_chat、list_agents、list_buckets、upload_document_by_fileなど)。 85 | - **ファイル管理**: ファイルのアップロード、読み込み、管理のためのファイルシステム操作を実装します。 86 | - **API統合**: StormのAPIエンドポイントと接続し、様々な機能を提供します。 87 | 88 | #### プロジェクト構造 89 | 90 | - **main.py**: MCPサーバーを初期化し、イベントハンドラーを設定します。 91 | - **core/file_manager.py**: ファイル操作のための`FileSystemManager`クラスを実装します。 92 | - **core/internal_api.py**: StormのRESTAPIエンドポイントと相互作用するためのAPIクライアント関数を含みます。 93 | - **tools/tool_definitions.py**: MCPサーバーで利用可能なツールを定義します。 94 | - **tools/tool_handlers.py**: ツール操作のためのハンドラーを実装します。 95 | - **tools/tool_upload_file.py**: 独自のMCPハンドラーを持つファイル操作のための別個のファイルサーバーを実装します。 96 | 97 | #### アーキテクチャ 98 | 99 | MCPは、ホスト(LLMアプリケーション)、クライアント(プロトコル実装)、サーバー(機能提供者)間の3層構造で設計されています。Storm MCPサーバーはこのうちサーバー部分を実装し、リソースとツールをLLMに提供します。 100 | 101 | ### 始め方 102 | **Claude Desktop** 環境でMCPサーバーを接続するには、以下の設定を適用する必要があります。 103 | 104 | ![example image](scripts/img_1.png) 105 | 106 | 1) 設定ファイルを開く 107 | ```bash 108 | code ~/Library/Application\ Support/Claude/claude_desktop_config.json 109 | ``` 110 | 111 | 2) JSON内にMCPサーバー設定を追加: 112 | ```json 113 | { 114 | "mcpServers": { 115 | "storm": { 116 | "command": "sh", 117 | "args": [ 118 | "/Users/sigridjineth/Desktop/work/storm-mcp-server/scripts/run.sh" 119 | ] 120 | } 121 | } 122 | } 123 | ``` -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "storm-mcp-server" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.12" 7 | dependencies = [ 8 | "fastapi>=0.115.11", 9 | "mcp>=1.3.0", 10 | "requests>=2.32.3", 11 | "uvicorn>=0.34.0", 12 | ] 13 | -------------------------------------------------------------------------------- /scripts/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/scripts/img.png -------------------------------------------------------------------------------- /scripts/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/scripts/img_1.png -------------------------------------------------------------------------------- /scripts/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/scripts/img_2.png -------------------------------------------------------------------------------- /scripts/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/scripts/img_3.png -------------------------------------------------------------------------------- /scripts/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/scripts/img_4.png -------------------------------------------------------------------------------- /scripts/old.py: -------------------------------------------------------------------------------- 1 | import json 2 | import asyncio 3 | import requests 4 | from typing import Any, Dict, List 5 | from mcp.server import Server 6 | from mcp.server.stdio import stdio_server 7 | from mcp.types import Tool, TextContent 8 | 9 | # MCP 서버 인스턴스 생성 10 | server = Server("chat-api-v2-answer") 11 | 12 | #================================================================ 13 | # 1) Storm API 호출 헬퍼 함수 14 | #================================================================ 15 | def call_chat_api( 16 | api_key: str, 17 | question: str, 18 | bucket_ids: List[str] = None, 19 | thread_id: str = None, 20 | webhook_url: str = None, 21 | ) -> Dict[str, Any]: 22 | """ 23 | /api/v2/answer (non-stream) 호출 예시 24 | - header: storm-api-key: {api_key} 25 | - body: { "question": "...", "bucketIds": [...], "threadId": "...", "webhookUrl": "..." } 26 | """ 27 | url = "https://live-stargate.sionic.im/api/v2/answer" # 사용자 환경에 맞게 수정 가능 28 | headers = { 29 | "Content-Type": "application/json", 30 | "storm-api-key": api_key, # <-- 헤더 이름이 'storm-api-key' 31 | } 32 | 33 | body = { 34 | "question": question, 35 | } 36 | if bucket_ids: 37 | body["bucketIds"] = bucket_ids 38 | if thread_id: 39 | body["threadId"] = thread_id 40 | if webhook_url: 41 | body["webhookUrl"] = webhook_url 42 | 43 | response = requests.post(url, headers=headers, json=body, timeout=30) 44 | 45 | if response.status_code >= 400: 46 | raise Exception(f"API error: {response.status_code} - {response.text}") 47 | 48 | return response.json() 49 | 50 | #================================================================ 51 | # 2) MCP Tool 정의 52 | #================================================================ 53 | TOOLS_DEFINITION = [ 54 | { 55 | "name": "send_nonstream_chat", 56 | "description": ( 57 | "/api/v2/answer (non-stream)로 POST 요청을 보내어 질문(question)에 대한 " 58 | "답변을 받아옵니다. (storm-api-key 헤더 사용)" 59 | ), 60 | "inputSchema": { 61 | "type": "object", 62 | "properties": { 63 | "api_key": { 64 | "type": "string", 65 | "description": "storm-api-key 헤더로 보낼 API 키" 66 | }, 67 | "question": { 68 | "type": "string", 69 | "description": "채팅 질문 텍스트" 70 | }, 71 | "bucketIds": { 72 | "type": "array", 73 | "items": { 74 | "type": "string" 75 | }, 76 | "description": "질문 대상 버킷 ID 리스트 (옵션)" 77 | }, 78 | "threadId": { 79 | "type": "string", 80 | "description": "채팅을 전송할 스레드 ID (옵션)" 81 | }, 82 | "webhookUrl": { 83 | "type": "string", 84 | "description": "결과를 받을 웹훅 URL (옵션)" 85 | } 86 | }, 87 | "required": ["api_key", "question"] # 최소 필드는 api_key, question 88 | } 89 | } 90 | ] 91 | 92 | #================================================================ 93 | # 3) list_tools 핸들러 94 | #================================================================ 95 | @server.list_tools() 96 | async def handle_list_tools() -> List[Tool]: 97 | """MCP가 'tools/list'를 호출하면 이 핸들러가 실행됩니다.""" 98 | tool_objects: List[Tool] = [] 99 | for tdef in TOOLS_DEFINITION: 100 | tool_objects.append( 101 | Tool( 102 | name=tdef["name"], 103 | description=tdef["description"], 104 | inputSchema=tdef["inputSchema"] 105 | ) 106 | ) 107 | return tool_objects 108 | 109 | #================================================================ 110 | # 4) call_tool 핸들러 111 | #================================================================ 112 | @server.call_tool() 113 | async def handle_call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]: 114 | try: 115 | if name != "send_nonstream_chat": 116 | raise ValueError(f"Tool '{name}' not found.") 117 | 118 | # 파라미터 꺼내기 119 | api_key = arguments.get("api_key", "").strip() 120 | question = arguments.get("question", "").strip() 121 | bucket_ids = arguments.get("bucketIds", None) 122 | thread_id = arguments.get("threadId", None) 123 | webhook_url = arguments.get("webhookUrl", None) 124 | 125 | if not api_key: 126 | raise ValueError("api_key is required") 127 | if not question: 128 | raise ValueError("question is required") 129 | 130 | # 비동기로 동기 함수를 감싸기 131 | response_data = await asyncio.to_thread( 132 | call_chat_api, 133 | api_key=api_key, 134 | question=question, 135 | bucket_ids=bucket_ids, 136 | thread_id=thread_id, 137 | webhook_url=webhook_url 138 | ) 139 | 140 | # Storm API 응답을 JSON 텍스트로 변환해 MCP TextContent로 감싸기 141 | result_text = json.dumps(response_data, ensure_ascii=False, indent=2) 142 | return [TextContent(type="text", text=result_text)] 143 | 144 | except Exception as e: 145 | raise RuntimeError(f"Tool call error: {str(e)}") from e 146 | 147 | #================================================================ 148 | # 5) 서버 실행 진입점 149 | #================================================================ 150 | async def main(): 151 | async with stdio_server() as (read_stream, write_stream): 152 | await server.run(read_stream, write_stream, server.create_initialization_options()) 153 | 154 | if __name__ == "__main__": 155 | asyncio.run(main()) 156 | -------------------------------------------------------------------------------- /scripts/output.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.0", 3 | "info": { 4 | "title": "Storm API", 5 | "description": "Description", 6 | "version": "1.0.0" 7 | }, 8 | "servers": [ 9 | { 10 | "url": "http://localhost:3000/", 11 | "description": "Local server" 12 | }, 13 | { 14 | "url": "https://dev.sionicstorm.ai/api/", 15 | "description": "Development server" 16 | } 17 | ], 18 | "paths": { 19 | "/": { 20 | "get": { 21 | "description": "", 22 | "responses": { 23 | "default": { 24 | "description": "" 25 | } 26 | } 27 | } 28 | }, 29 | "/health": { 30 | "get": { 31 | "description": "", 32 | "responses": { 33 | "default": { 34 | "description": "" 35 | } 36 | } 37 | } 38 | }, 39 | "/auth/login": { 40 | "get": { 41 | "tags": [ 42 | "Auth" 43 | ], 44 | "description": "Email 로그인", 45 | "parameters": [ 46 | { 47 | "name": "email", 48 | "in": "query", 49 | "schema": { 50 | "type": "string" 51 | } 52 | }, 53 | { 54 | "name": "password", 55 | "in": "query", 56 | "schema": { 57 | "type": "string" 58 | } 59 | } 60 | ], 61 | "responses": { 62 | "default": { 63 | "description": "" 64 | } 65 | } 66 | }, 67 | "post": { 68 | "tags": [ 69 | "Auth" 70 | ], 71 | "description": "Email 로그인", 72 | "responses": { 73 | "default": { 74 | "description": "" 75 | } 76 | }, 77 | "requestBody": { 78 | "content": { 79 | "application/json": { 80 | "schema": { 81 | "type": "object", 82 | "properties": { 83 | "email": { 84 | "example": "any" 85 | }, 86 | "password": { 87 | "example": "any" 88 | } 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | }, 96 | "/auth/cipher-login": { 97 | "get": { 98 | "description": "", 99 | "parameters": [ 100 | { 101 | "name": "userId", 102 | "in": "query", 103 | "schema": { 104 | "type": "string" 105 | } 106 | }, 107 | { 108 | "name": "cipher", 109 | "in": "query", 110 | "schema": { 111 | "type": "string" 112 | } 113 | } 114 | ], 115 | "responses": { 116 | "default": { 117 | "description": "" 118 | } 119 | } 120 | } 121 | }, 122 | "/auth/signup": { 123 | "post": { 124 | "tags": [ 125 | "Auth" 126 | ], 127 | "description": "Email 회원가입", 128 | "responses": { 129 | "default": { 130 | "description": "" 131 | } 132 | }, 133 | "requestBody": { 134 | "content": { 135 | "application/json": { 136 | "schema": { 137 | "$ref": "#/components/schemas/postAuthSignup" 138 | } 139 | }, 140 | "application/xml": { 141 | "schema": { 142 | "$ref": "#/components/schemas/postAuthSignup" 143 | } 144 | } 145 | } 146 | } 147 | } 148 | }, 149 | "/auth/check": { 150 | "get": { 151 | "description": "", 152 | "responses": { 153 | "default": { 154 | "description": "" 155 | } 156 | }, 157 | "security": [ 158 | { 159 | "bearerAuth": [], 160 | "ApiKeyAuth": [] 161 | } 162 | ] 163 | } 164 | }, 165 | "/auth/sso/slack/": { 166 | "get": { 167 | "tags": [ 168 | "Auth" 169 | ], 170 | "description": "", 171 | "parameters": [ 172 | { 173 | "name": "state", 174 | "in": "query", 175 | "schema": { 176 | "type": "string" 177 | } 178 | } 179 | ], 180 | "responses": { 181 | "default": { 182 | "description": "" 183 | } 184 | } 185 | } 186 | }, 187 | "/auth/sso/slack/callback": { 188 | "get": { 189 | "tags": [ 190 | "Auth" 191 | ], 192 | "description": "", 193 | "parameters": [ 194 | { 195 | "name": "code", 196 | "in": "query", 197 | "schema": { 198 | "type": "string" 199 | } 200 | }, 201 | { 202 | "name": "state", 203 | "in": "query", 204 | "schema": { 205 | "type": "string" 206 | } 207 | } 208 | ], 209 | "responses": { 210 | "default": { 211 | "description": "" 212 | } 213 | } 214 | } 215 | }, 216 | "/auth/sso/google/": { 217 | "get": { 218 | "tags": [ 219 | "Auth" 220 | ], 221 | "description": "", 222 | "parameters": [ 223 | { 224 | "name": "state", 225 | "in": "query", 226 | "schema": { 227 | "type": "string" 228 | } 229 | } 230 | ], 231 | "responses": { 232 | "200": { 233 | "description": "OK" 234 | } 235 | } 236 | } 237 | }, 238 | "/auth/sso/google/callback": { 239 | "get": { 240 | "tags": [ 241 | "Auth" 242 | ], 243 | "description": "", 244 | "parameters": [ 245 | { 246 | "name": "code", 247 | "in": "query", 248 | "schema": { 249 | "type": "string" 250 | } 251 | }, 252 | { 253 | "name": "state", 254 | "in": "query", 255 | "schema": { 256 | "type": "string" 257 | } 258 | } 259 | ], 260 | "responses": { 261 | "default": { 262 | "description": "" 263 | } 264 | } 265 | } 266 | }, 267 | "/playground/clova": { 268 | "get": { 269 | "tags": [ 270 | "Playground" 271 | ], 272 | "description": "클로바 사용량 확인", 273 | "responses": { 274 | "default": { 275 | "description": "" 276 | } 277 | }, 278 | "security": [ 279 | { 280 | "bearerAuth": [], 281 | "ApiKeyAuth": [] 282 | } 283 | ] 284 | }, 285 | "post": { 286 | "tags": [ 287 | "Playground" 288 | ], 289 | "description": "클로바 사용", 290 | "responses": { 291 | "default": { 292 | "description": "" 293 | } 294 | }, 295 | "security": [ 296 | { 297 | "bearerAuth": [], 298 | "ApiKeyAuth": [] 299 | } 300 | ] 301 | } 302 | }, 303 | "/slack/install/": { 304 | "get": { 305 | "tags": [ 306 | "Slack" 307 | ], 308 | "description": "", 309 | "responses": { 310 | "default": { 311 | "description": "" 312 | } 313 | } 314 | } 315 | }, 316 | "/slack/install/callback": { 317 | "get": { 318 | "tags": [ 319 | "Slack" 320 | ], 321 | "description": "", 322 | "parameters": [ 323 | { 324 | "name": "code", 325 | "in": "query", 326 | "schema": { 327 | "type": "string" 328 | } 329 | } 330 | ], 331 | "responses": { 332 | "400": { 333 | "description": "Bad Request" 334 | } 335 | } 336 | } 337 | }, 338 | "/slack/event/": { 339 | "post": { 340 | "tags": [ 341 | "Slack" 342 | ], 343 | "description": "", 344 | "responses": { 345 | "200": { 346 | "description": "OK" 347 | }, 348 | "400": { 349 | "description": "Bad Request" 350 | } 351 | }, 352 | "requestBody": { 353 | "content": { 354 | "application/json": { 355 | "schema": { 356 | "type": "object", 357 | "properties": { 358 | "token": { 359 | "example": "any" 360 | }, 361 | "team_id": { 362 | "example": "any" 363 | }, 364 | "payload": { 365 | "example": "any" 366 | }, 367 | "challenge": { 368 | "example": "any" 369 | }, 370 | "type": { 371 | "example": "any" 372 | }, 373 | "api_app_id": { 374 | "example": "any" 375 | }, 376 | "event": { 377 | "example": "any" 378 | }, 379 | "event_id": { 380 | "example": "any" 381 | } 382 | } 383 | } 384 | } 385 | } 386 | } 387 | } 388 | }, 389 | "/slack/interactive/": { 390 | "post": { 391 | "tags": [ 392 | "Slack" 393 | ], 394 | "description": "", 395 | "responses": { 396 | "200": { 397 | "description": "OK" 398 | }, 399 | "400": { 400 | "description": "Bad Request" 401 | } 402 | }, 403 | "requestBody": { 404 | "content": { 405 | "application/json": { 406 | "schema": { 407 | "type": "object", 408 | "properties": { 409 | "token": { 410 | "example": "any" 411 | }, 412 | "team_id": { 413 | "example": "any" 414 | }, 415 | "payload": { 416 | "example": "any" 417 | } 418 | } 419 | } 420 | } 421 | } 422 | } 423 | } 424 | }, 425 | "/slack/command/": { 426 | "post": { 427 | "tags": [ 428 | "Slack" 429 | ], 430 | "description": "", 431 | "responses": { 432 | "200": { 433 | "description": "OK" 434 | }, 435 | "400": { 436 | "description": "Bad Request" 437 | } 438 | }, 439 | "requestBody": { 440 | "content": { 441 | "application/json": { 442 | "schema": { 443 | "type": "object", 444 | "properties": { 445 | "token": { 446 | "example": "any" 447 | }, 448 | "team_id": { 449 | "example": "any" 450 | }, 451 | "payload": { 452 | "example": "any" 453 | }, 454 | "user_id": { 455 | "example": "any" 456 | }, 457 | "channel_id": { 458 | "example": "any" 459 | }, 460 | "text": { 461 | "example": "any" 462 | } 463 | } 464 | } 465 | } 466 | } 467 | } 468 | } 469 | }, 470 | "/channeltalk/event/": { 471 | "post": { 472 | "tags": [ 473 | "ChannelTalk" 474 | ], 475 | "description": "", 476 | "responses": { 477 | "200": { 478 | "description": "OK" 479 | }, 480 | "400": { 481 | "description": "Bad Request" 482 | } 483 | }, 484 | "requestBody": { 485 | "content": { 486 | "application/json": { 487 | "schema": { 488 | "type": "object", 489 | "properties": { 490 | "refers": { 491 | "example": "any" 492 | }, 493 | "event": { 494 | "example": "any" 495 | }, 496 | "type": { 497 | "example": "any" 498 | }, 499 | "entity": { 500 | "example": "any" 501 | } 502 | } 503 | } 504 | } 505 | } 506 | } 507 | } 508 | }, 509 | "/kakaotalk/event/": { 510 | "post": { 511 | "tags": [ 512 | "KakaoTalk" 513 | ], 514 | "description": "", 515 | "responses": { 516 | "200": { 517 | "description": "OK" 518 | }, 519 | "400": { 520 | "description": "Bad Request" 521 | } 522 | }, 523 | "requestBody": { 524 | "content": { 525 | "application/json": { 526 | "schema": { 527 | "type": "object", 528 | "properties": { 529 | "bot": { 530 | "example": "any" 531 | }, 532 | "userRequest": { 533 | "example": "any" 534 | } 535 | } 536 | } 537 | } 538 | } 539 | } 540 | } 541 | }, 542 | "/pylon/callback/agents": { 543 | "post": { 544 | "description": "", 545 | "parameters": [ 546 | { 547 | "name": "c", 548 | "in": "query", 549 | "schema": { 550 | "type": "string" 551 | } 552 | } 553 | ], 554 | "responses": { 555 | "200": { 556 | "description": "OK" 557 | } 558 | }, 559 | "requestBody": { 560 | "content": { 561 | "application/json": { 562 | "schema": { 563 | "type": "object", 564 | "properties": { 565 | "status": { 566 | "example": "any" 567 | } 568 | } 569 | } 570 | } 571 | } 572 | } 573 | } 574 | }, 575 | "/pylon/callback/buckets": { 576 | "post": { 577 | "description": "", 578 | "parameters": [ 579 | { 580 | "name": "c", 581 | "in": "query", 582 | "schema": { 583 | "type": "string" 584 | } 585 | } 586 | ], 587 | "responses": { 588 | "200": { 589 | "description": "OK" 590 | } 591 | }, 592 | "requestBody": { 593 | "content": { 594 | "application/json": { 595 | "schema": { 596 | "type": "object", 597 | "properties": { 598 | "status": { 599 | "example": "any" 600 | } 601 | } 602 | } 603 | } 604 | } 605 | } 606 | } 607 | }, 608 | "/pylon/callback/documents": { 609 | "post": { 610 | "tags": [ 611 | "Pylon" 612 | ], 613 | "description": "", 614 | "parameters": [ 615 | { 616 | "name": "c", 617 | "in": "query", 618 | "schema": { 619 | "type": "string" 620 | } 621 | } 622 | ], 623 | "responses": { 624 | "200": { 625 | "description": "OK" 626 | } 627 | }, 628 | "requestBody": { 629 | "content": { 630 | "application/json": { 631 | "schema": { 632 | "type": "object", 633 | "properties": { 634 | "status": { 635 | "example": "any" 636 | }, 637 | "result": { 638 | "example": "any" 639 | } 640 | } 641 | } 642 | } 643 | } 644 | } 645 | } 646 | }, 647 | "/pylon/callback/advices": { 648 | "post": { 649 | "tags": [ 650 | "Pylon" 651 | ], 652 | "description": "", 653 | "parameters": [ 654 | { 655 | "name": "c", 656 | "in": "query", 657 | "schema": { 658 | "type": "string" 659 | } 660 | } 661 | ], 662 | "responses": { 663 | "200": { 664 | "description": "OK" 665 | } 666 | }, 667 | "requestBody": { 668 | "content": { 669 | "application/json": { 670 | "schema": { 671 | "type": "object", 672 | "properties": { 673 | "status": { 674 | "example": "any" 675 | }, 676 | "result": { 677 | "example": "any" 678 | } 679 | } 680 | } 681 | } 682 | } 683 | } 684 | } 685 | }, 686 | "/pylon/callback/query": { 687 | "post": { 688 | "tags": [ 689 | "Pylon" 690 | ], 691 | "description": "", 692 | "parameters": [ 693 | { 694 | "name": "c", 695 | "in": "query", 696 | "schema": { 697 | "type": "string" 698 | } 699 | } 700 | ], 701 | "responses": { 702 | "200": { 703 | "description": "OK" 704 | } 705 | }, 706 | "requestBody": { 707 | "content": { 708 | "application/json": { 709 | "schema": { 710 | "type": "object", 711 | "properties": { 712 | "task_id": { 713 | "example": "any" 714 | }, 715 | "status": { 716 | "example": "any" 717 | } 718 | } 719 | } 720 | } 721 | } 722 | } 723 | } 724 | }, 725 | "/pylon/callback/deployments": { 726 | "post": { 727 | "tags": [ 728 | "Pylon" 729 | ], 730 | "description": "", 731 | "parameters": [ 732 | { 733 | "name": "c", 734 | "in": "query", 735 | "schema": { 736 | "type": "string" 737 | } 738 | } 739 | ], 740 | "responses": { 741 | "200": { 742 | "description": "OK" 743 | } 744 | }, 745 | "requestBody": { 746 | "content": { 747 | "application/json": { 748 | "schema": { 749 | "type": "object", 750 | "properties": { 751 | "status": { 752 | "example": "any" 753 | }, 754 | "result": { 755 | "example": "any" 756 | } 757 | } 758 | } 759 | } 760 | } 761 | } 762 | } 763 | }, 764 | "/pylon/callback/write": { 765 | "post": { 766 | "tags": [ 767 | "Pylon" 768 | ], 769 | "description": "", 770 | "parameters": [ 771 | { 772 | "name": "c", 773 | "in": "query", 774 | "schema": { 775 | "type": "string" 776 | } 777 | } 778 | ], 779 | "responses": { 780 | "200": { 781 | "description": "OK" 782 | } 783 | }, 784 | "requestBody": { 785 | "content": { 786 | "application/json": { 787 | "schema": { 788 | "type": "object", 789 | "properties": { 790 | "status": { 791 | "example": "any" 792 | }, 793 | "result": { 794 | "example": "any" 795 | } 796 | } 797 | } 798 | } 799 | } 800 | } 801 | } 802 | }, 803 | "/me/": { 804 | "get": { 805 | "tags": [ 806 | "Me" 807 | ], 808 | "description": "내 정보 확인", 809 | "responses": { 810 | "default": { 811 | "description": "" 812 | } 813 | }, 814 | "security": [ 815 | { 816 | "bearerAuth": [], 817 | "ApiKeyAuth": [] 818 | } 819 | ] 820 | } 821 | }, 822 | "/me/teams": { 823 | "get": { 824 | "tags": [ 825 | "Me" 826 | ], 827 | "description": "내가 속한 팀의 리스트 확인", 828 | "parameters": [ 829 | { 830 | "$ref": "#/components/parameters/search" 831 | }, 832 | { 833 | "$ref": "#/components/parameters/order" 834 | }, 835 | { 836 | "$ref": "#/components/parameters/cursor" 837 | }, 838 | { 839 | "$ref": "#/components/parameters/take" 840 | } 841 | ], 842 | "responses": { 843 | "default": { 844 | "description": "" 845 | } 846 | }, 847 | "security": [ 848 | { 849 | "bearerAuth": [], 850 | "ApiKeyAuth": [] 851 | } 852 | ] 853 | } 854 | }, 855 | "/me/teams/invite": { 856 | "post": { 857 | "tags": [ 858 | "Me" 859 | ], 860 | "description": "팀 초대 수락", 861 | "responses": { 862 | "default": { 863 | "description": "" 864 | } 865 | }, 866 | "security": [ 867 | { 868 | "bearerAuth": [], 869 | "ApiKeyAuth": [] 870 | } 871 | ], 872 | "requestBody": { 873 | "content": { 874 | "application/json": { 875 | "schema": { 876 | "$ref": "#/components/schemas/postMeTeamInvite" 877 | } 878 | }, 879 | "application/xml": { 880 | "schema": { 881 | "$ref": "#/components/schemas/postMeTeamInvite" 882 | } 883 | } 884 | } 885 | } 886 | } 887 | }, 888 | "/teams/": { 889 | "post": { 890 | "tags": [ 891 | "Team" 892 | ], 893 | "description": "팀 생성", 894 | "responses": { 895 | "default": { 896 | "description": "" 897 | } 898 | }, 899 | "security": [ 900 | { 901 | "bearerAuth": [], 902 | "ApiKeyAuth": [] 903 | } 904 | ], 905 | "requestBody": { 906 | "content": { 907 | "application/json": { 908 | "schema": { 909 | "$ref": "#/components/schemas/postTeam" 910 | } 911 | }, 912 | "application/xml": { 913 | "schema": { 914 | "$ref": "#/components/schemas/postTeam" 915 | } 916 | } 917 | } 918 | } 919 | } 920 | }, 921 | "/teams/{teamId}": { 922 | "get": { 923 | "tags": [ 924 | "Team" 925 | ], 926 | "description": "팀 정보 획득", 927 | "parameters": [ 928 | { 929 | "name": "teamId", 930 | "in": "path", 931 | "required": true, 932 | "schema": { 933 | "type": "string" 934 | } 935 | } 936 | ], 937 | "responses": { 938 | "default": { 939 | "description": "" 940 | } 941 | }, 942 | "security": [ 943 | { 944 | "bearerAuth": [], 945 | "ApiKeyAuth": [] 946 | } 947 | ] 948 | }, 949 | "patch": { 950 | "tags": [ 951 | "Team" 952 | ], 953 | "description": "팀 속성 변경", 954 | "parameters": [ 955 | { 956 | "name": "teamId", 957 | "in": "path", 958 | "required": true, 959 | "schema": { 960 | "type": "string" 961 | } 962 | } 963 | ], 964 | "responses": { 965 | "default": { 966 | "description": "" 967 | } 968 | }, 969 | "security": [ 970 | { 971 | "bearerAuth": [], 972 | "ApiKeyAuth": [] 973 | } 974 | ], 975 | "requestBody": { 976 | "content": { 977 | "application/json": { 978 | "schema": { 979 | "$ref": "#/components/schemas/patchTeam" 980 | } 981 | }, 982 | "application/xml": { 983 | "schema": { 984 | "$ref": "#/components/schemas/patchTeam" 985 | } 986 | } 987 | } 988 | } 989 | } 990 | }, 991 | "/teams/{teamId}/members": { 992 | "get": { 993 | "tags": [ 994 | "Team" 995 | ], 996 | "description": "팀 멤버 리스트 획득", 997 | "parameters": [ 998 | { 999 | "name": "teamId", 1000 | "in": "path", 1001 | "required": true, 1002 | "schema": { 1003 | "type": "string" 1004 | } 1005 | }, 1006 | { 1007 | "$ref": "#/components/parameters/search" 1008 | }, 1009 | { 1010 | "$ref": "#/components/parameters/order" 1011 | }, 1012 | { 1013 | "$ref": "#/components/parameters/cursor" 1014 | }, 1015 | { 1016 | "$ref": "#/components/parameters/take" 1017 | } 1018 | ], 1019 | "responses": { 1020 | "default": { 1021 | "description": "" 1022 | } 1023 | }, 1024 | "security": [ 1025 | { 1026 | "bearerAuth": [], 1027 | "ApiKeyAuth": [] 1028 | } 1029 | ] 1030 | } 1031 | }, 1032 | "/teams/{teamId}/members/{userId}": { 1033 | "patch": { 1034 | "tags": [ 1035 | "Team" 1036 | ], 1037 | "description": "팀 멤버의 속성 변경", 1038 | "parameters": [ 1039 | { 1040 | "name": "teamId", 1041 | "in": "path", 1042 | "required": true, 1043 | "schema": { 1044 | "type": "string" 1045 | } 1046 | }, 1047 | { 1048 | "name": "userId", 1049 | "in": "path", 1050 | "required": true, 1051 | "schema": { 1052 | "type": "string" 1053 | } 1054 | } 1055 | ], 1056 | "responses": { 1057 | "default": { 1058 | "description": "" 1059 | } 1060 | }, 1061 | "security": [ 1062 | { 1063 | "bearerAuth": [], 1064 | "ApiKeyAuth": [] 1065 | } 1066 | ], 1067 | "requestBody": { 1068 | "content": { 1069 | "application/json": { 1070 | "schema": { 1071 | "$ref": "#/components/schemas/patchTeamMembers" 1072 | } 1073 | }, 1074 | "application/xml": { 1075 | "schema": { 1076 | "$ref": "#/components/schemas/patchTeamMembers" 1077 | } 1078 | } 1079 | } 1080 | } 1081 | } 1082 | }, 1083 | "/teams/{teamId}/invites": { 1084 | "post": { 1085 | "tags": [ 1086 | "Team" 1087 | ], 1088 | "description": "팀 멤버 초대", 1089 | "parameters": [ 1090 | { 1091 | "name": "teamId", 1092 | "in": "path", 1093 | "required": true, 1094 | "schema": { 1095 | "type": "string" 1096 | } 1097 | } 1098 | ], 1099 | "responses": { 1100 | "default": { 1101 | "description": "" 1102 | } 1103 | }, 1104 | "security": [ 1105 | { 1106 | "bearerAuth": [], 1107 | "ApiKeyAuth": [] 1108 | } 1109 | ], 1110 | "requestBody": { 1111 | "content": { 1112 | "application/json": { 1113 | "schema": { 1114 | "$ref": "#/components/schemas/postTeamInvites" 1115 | } 1116 | }, 1117 | "application/xml": { 1118 | "schema": { 1119 | "$ref": "#/components/schemas/postTeamInvites" 1120 | } 1121 | } 1122 | } 1123 | } 1124 | } 1125 | }, 1126 | "/teams/{teamId}/agents": { 1127 | "get": { 1128 | "tags": [ 1129 | "Team" 1130 | ], 1131 | "description": "팀 에이전트 리스트 획득", 1132 | "parameters": [ 1133 | { 1134 | "name": "teamId", 1135 | "in": "path", 1136 | "required": true, 1137 | "schema": { 1138 | "type": "string" 1139 | } 1140 | }, 1141 | { 1142 | "$ref": "#/components/parameters/search" 1143 | }, 1144 | { 1145 | "$ref": "#/components/parameters/order" 1146 | }, 1147 | { 1148 | "$ref": "#/components/parameters/cursor" 1149 | }, 1150 | { 1151 | "$ref": "#/components/parameters/take" 1152 | } 1153 | ], 1154 | "responses": { 1155 | "default": { 1156 | "description": "" 1157 | } 1158 | }, 1159 | "security": [ 1160 | { 1161 | "bearerAuth": [], 1162 | "ApiKeyAuth": [] 1163 | } 1164 | ] 1165 | }, 1166 | "post": { 1167 | "tags": [ 1168 | "Team" 1169 | ], 1170 | "description": "팀 에이전트 등록", 1171 | "parameters": [ 1172 | { 1173 | "name": "teamId", 1174 | "in": "path", 1175 | "required": true, 1176 | "schema": { 1177 | "type": "string" 1178 | } 1179 | } 1180 | ], 1181 | "responses": { 1182 | "default": { 1183 | "description": "" 1184 | } 1185 | }, 1186 | "security": [ 1187 | { 1188 | "bearerAuth": [], 1189 | "ApiKeyAuth": [] 1190 | } 1191 | ], 1192 | "requestBody": { 1193 | "content": { 1194 | "application/json": { 1195 | "schema": { 1196 | "$ref": "#/components/schemas/postTeamAgents" 1197 | } 1198 | }, 1199 | "application/xml": { 1200 | "schema": { 1201 | "$ref": "#/components/schemas/postTeamAgents" 1202 | } 1203 | } 1204 | } 1205 | } 1206 | } 1207 | }, 1208 | "/agents/{agentId}": { 1209 | "get": { 1210 | "tags": [ 1211 | "Agent" 1212 | ], 1213 | "description": "에이전트 정보 획득", 1214 | "parameters": [ 1215 | { 1216 | "name": "agentId", 1217 | "in": "path", 1218 | "required": true, 1219 | "schema": { 1220 | "type": "string" 1221 | } 1222 | } 1223 | ], 1224 | "responses": { 1225 | "default": { 1226 | "description": "" 1227 | } 1228 | }, 1229 | "security": [ 1230 | { 1231 | "bearerAuth": [], 1232 | "ApiKeyAuth": [] 1233 | } 1234 | ] 1235 | }, 1236 | "patch": { 1237 | "tags": [ 1238 | "Agent" 1239 | ], 1240 | "description": "팀 에이전트 수정", 1241 | "parameters": [ 1242 | { 1243 | "name": "agentId", 1244 | "in": "path", 1245 | "required": true, 1246 | "schema": { 1247 | "type": "string" 1248 | } 1249 | } 1250 | ], 1251 | "responses": { 1252 | "default": { 1253 | "description": "" 1254 | } 1255 | }, 1256 | "security": [ 1257 | { 1258 | "bearerAuth": [], 1259 | "ApiKeyAuth": [] 1260 | } 1261 | ], 1262 | "requestBody": { 1263 | "content": { 1264 | "application/json": { 1265 | "schema": { 1266 | "$ref": "#/components/schemas/patchTeamAgents" 1267 | } 1268 | }, 1269 | "application/xml": { 1270 | "schema": { 1271 | "$ref": "#/components/schemas/patchTeamAgents" 1272 | } 1273 | } 1274 | } 1275 | } 1276 | }, 1277 | "delete": { 1278 | "tags": [ 1279 | "Agent" 1280 | ], 1281 | "description": "팀 에이전트 삭제", 1282 | "parameters": [ 1283 | { 1284 | "name": "agentId", 1285 | "in": "path", 1286 | "required": true, 1287 | "schema": { 1288 | "type": "string" 1289 | } 1290 | } 1291 | ], 1292 | "responses": { 1293 | "default": { 1294 | "description": "" 1295 | } 1296 | }, 1297 | "security": [ 1298 | { 1299 | "bearerAuth": [], 1300 | "ApiKeyAuth": [] 1301 | } 1302 | ] 1303 | } 1304 | }, 1305 | "/agents/{agentId}/knowledges": { 1306 | "get": { 1307 | "tags": [ 1308 | "Agent" 1309 | ], 1310 | "description": "에이전트의 Knowledges 리스트 획득", 1311 | "parameters": [ 1312 | { 1313 | "name": "agentId", 1314 | "in": "path", 1315 | "required": true, 1316 | "schema": { 1317 | "type": "string" 1318 | } 1319 | }, 1320 | { 1321 | "$ref": "#/components/parameters/search" 1322 | }, 1323 | { 1324 | "$ref": "#/components/parameters/order" 1325 | }, 1326 | { 1327 | "$ref": "#/components/parameters/cursor" 1328 | }, 1329 | { 1330 | "$ref": "#/components/parameters/take" 1331 | } 1332 | ], 1333 | "responses": { 1334 | "default": { 1335 | "description": "" 1336 | } 1337 | }, 1338 | "security": [ 1339 | { 1340 | "bearerAuth": [], 1341 | "ApiKeyAuth": [] 1342 | } 1343 | ] 1344 | } 1345 | }, 1346 | "/agents/{agentId}/instructions": { 1347 | "delete": { 1348 | "tags": [ 1349 | "Agent" 1350 | ], 1351 | "description": "에이전트의 Knowledges 삭제", 1352 | "parameters": [ 1353 | { 1354 | "name": "agentId", 1355 | "in": "path", 1356 | "required": true, 1357 | "schema": { 1358 | "type": "string" 1359 | } 1360 | } 1361 | ], 1362 | "responses": { 1363 | "default": { 1364 | "description": "" 1365 | } 1366 | }, 1367 | "security": [ 1368 | { 1369 | "bearerAuth": [], 1370 | "ApiKeyAuth": [] 1371 | } 1372 | ], 1373 | "requestBody": { 1374 | "content": { 1375 | "application/json": { 1376 | "schema": { 1377 | "$ref": "#/components/schemas/deleteAgentKnowledges" 1378 | } 1379 | }, 1380 | "application/xml": { 1381 | "schema": { 1382 | "$ref": "#/components/schemas/deleteAgentKnowledges" 1383 | } 1384 | } 1385 | } 1386 | } 1387 | } 1388 | }, 1389 | "/agents/{agentId}/documents/url": { 1390 | "post": { 1391 | "tags": [ 1392 | "Agent" 1393 | ], 1394 | "description": "에이전트에 문서 URL 등록", 1395 | "parameters": [ 1396 | { 1397 | "name": "agentId", 1398 | "in": "path", 1399 | "required": true, 1400 | "schema": { 1401 | "type": "string" 1402 | } 1403 | }, 1404 | { 1405 | "name": "sse-connection-key", 1406 | "in": "header", 1407 | "schema": { 1408 | "type": "string" 1409 | } 1410 | } 1411 | ], 1412 | "responses": { 1413 | "default": { 1414 | "description": "" 1415 | } 1416 | }, 1417 | "security": [ 1418 | { 1419 | "bearerAuth": [], 1420 | "ApiKeyAuth": [] 1421 | } 1422 | ], 1423 | "requestBody": { 1424 | "content": { 1425 | "application/json": { 1426 | "schema": { 1427 | "$ref": "#/components/schemas/postAgentDocumentsUrl" 1428 | } 1429 | }, 1430 | "application/xml": { 1431 | "schema": { 1432 | "$ref": "#/components/schemas/postAgentDocumentsUrl" 1433 | } 1434 | } 1435 | } 1436 | } 1437 | } 1438 | }, 1439 | "/agents/{agentId}/documents/file": { 1440 | "post": { 1441 | "tags": [ 1442 | "Agent" 1443 | ], 1444 | "description": "에이전트에 문서 File 등록", 1445 | "parameters": [ 1446 | { 1447 | "name": "agentId", 1448 | "in": "path", 1449 | "required": true, 1450 | "schema": { 1451 | "type": "string" 1452 | } 1453 | }, 1454 | { 1455 | "name": "sse-connection-key", 1456 | "in": "header", 1457 | "schema": { 1458 | "type": "string" 1459 | } 1460 | }, 1461 | { 1462 | "$ref": "#/components/parameters/files" 1463 | } 1464 | ], 1465 | "responses": { 1466 | "default": { 1467 | "description": "" 1468 | } 1469 | }, 1470 | "security": [ 1471 | { 1472 | "bearerAuth": [], 1473 | "ApiKeyAuth": [] 1474 | } 1475 | ] 1476 | } 1477 | }, 1478 | "/agents/{agentId}/deployments": { 1479 | "post": { 1480 | "description": "", 1481 | "parameters": [ 1482 | { 1483 | "name": "agentId", 1484 | "in": "path", 1485 | "required": true, 1486 | "schema": { 1487 | "type": "string" 1488 | } 1489 | }, 1490 | { 1491 | "name": "sse-connection-key", 1492 | "in": "header", 1493 | "schema": { 1494 | "type": "string" 1495 | } 1496 | } 1497 | ], 1498 | "responses": { 1499 | "default": { 1500 | "description": "" 1501 | } 1502 | }, 1503 | "security": [ 1504 | { 1505 | "bearerAuth": [], 1506 | "ApiKeyAuth": [] 1507 | } 1508 | ], 1509 | "requestBody": { 1510 | "content": { 1511 | "application/json": { 1512 | "schema": { 1513 | "type": "object", 1514 | "properties": { 1515 | "memo": { 1516 | "example": "any" 1517 | }, 1518 | "agentVersionId": { 1519 | "example": "any" 1520 | } 1521 | } 1522 | } 1523 | } 1524 | } 1525 | } 1526 | }, 1527 | "get": { 1528 | "tags": [ 1529 | "Agent" 1530 | ], 1531 | "description": "에이전트의 배포 히스토리 목록 조회", 1532 | "parameters": [ 1533 | { 1534 | "name": "agentId", 1535 | "in": "path", 1536 | "required": true, 1537 | "schema": { 1538 | "type": "string" 1539 | } 1540 | }, 1541 | { 1542 | "name": "agentVersionStatus", 1543 | "in": "query", 1544 | "schema": { 1545 | "type": "string" 1546 | } 1547 | } 1548 | ], 1549 | "responses": { 1550 | "default": { 1551 | "description": "" 1552 | } 1553 | }, 1554 | "security": [ 1555 | { 1556 | "bearerAuth": [], 1557 | "ApiKeyAuth": [] 1558 | } 1559 | ] 1560 | } 1561 | }, 1562 | "/agents/{agentId}/channels": { 1563 | "post": { 1564 | "description": "", 1565 | "parameters": [ 1566 | { 1567 | "name": "agentId", 1568 | "in": "path", 1569 | "required": true, 1570 | "schema": { 1571 | "type": "string" 1572 | } 1573 | } 1574 | ], 1575 | "responses": { 1576 | "default": { 1577 | "description": "" 1578 | } 1579 | }, 1580 | "security": [ 1581 | { 1582 | "bearerAuth": [], 1583 | "ApiKeyAuth": [] 1584 | } 1585 | ], 1586 | "requestBody": { 1587 | "content": { 1588 | "application/json": { 1589 | "schema": { 1590 | "type": "object", 1591 | "properties": { 1592 | "type": { 1593 | "example": "any" 1594 | }, 1595 | "name": { 1596 | "example": "any" 1597 | }, 1598 | "kakaoBotId": { 1599 | "example": "any" 1600 | } 1601 | } 1602 | } 1603 | } 1604 | } 1605 | } 1606 | }, 1607 | "get": { 1608 | "description": "", 1609 | "parameters": [ 1610 | { 1611 | "name": "agentId", 1612 | "in": "path", 1613 | "required": true, 1614 | "schema": { 1615 | "type": "string" 1616 | } 1617 | } 1618 | ], 1619 | "responses": { 1620 | "default": { 1621 | "description": "" 1622 | } 1623 | }, 1624 | "security": [ 1625 | { 1626 | "bearerAuth": [], 1627 | "ApiKeyAuth": [] 1628 | } 1629 | ] 1630 | } 1631 | }, 1632 | "/agents/{agentId}/buckets": { 1633 | "get": { 1634 | "tags": [ 1635 | "Agent" 1636 | ], 1637 | "description": "에이전트의 버킷 리스트 획득", 1638 | "parameters": [ 1639 | { 1640 | "name": "agentId", 1641 | "in": "path", 1642 | "required": true, 1643 | "schema": { 1644 | "type": "string" 1645 | } 1646 | }, 1647 | { 1648 | "$ref": "#/components/parameters/search" 1649 | }, 1650 | { 1651 | "$ref": "#/components/parameters/order" 1652 | }, 1653 | { 1654 | "$ref": "#/components/parameters/cursor" 1655 | }, 1656 | { 1657 | "$ref": "#/components/parameters/take" 1658 | } 1659 | ], 1660 | "responses": { 1661 | "default": { 1662 | "description": "" 1663 | } 1664 | }, 1665 | "security": [ 1666 | { 1667 | "bearerAuth": [], 1668 | "ApiKeyAuth": [] 1669 | } 1670 | ] 1671 | }, 1672 | "post": { 1673 | "tags": [ 1674 | "Agent" 1675 | ], 1676 | "description": "에이전트에 버킷 등록", 1677 | "parameters": [ 1678 | { 1679 | "name": "agentId", 1680 | "in": "path", 1681 | "required": true, 1682 | "schema": { 1683 | "type": "string" 1684 | } 1685 | } 1686 | ], 1687 | "responses": { 1688 | "default": { 1689 | "description": "" 1690 | } 1691 | }, 1692 | "security": [ 1693 | { 1694 | "bearerAuth": [], 1695 | "ApiKeyAuth": [] 1696 | } 1697 | ], 1698 | "requestBody": { 1699 | "content": { 1700 | "application/json": { 1701 | "schema": { 1702 | "$ref": "#/components/schemas/postAgentBuckets" 1703 | } 1704 | }, 1705 | "application/xml": { 1706 | "schema": { 1707 | "$ref": "#/components/schemas/postAgentBuckets" 1708 | } 1709 | } 1710 | } 1711 | } 1712 | }, 1713 | "put": { 1714 | "tags": [ 1715 | "Agent" 1716 | ], 1717 | "description": "에이전트의 버킷 일괄 변경", 1718 | "parameters": [ 1719 | { 1720 | "name": "agentId", 1721 | "in": "path", 1722 | "required": true, 1723 | "schema": { 1724 | "type": "string" 1725 | } 1726 | } 1727 | ], 1728 | "responses": { 1729 | "default": { 1730 | "description": "" 1731 | } 1732 | }, 1733 | "security": [ 1734 | { 1735 | "bearerAuth": [], 1736 | "ApiKeyAuth": [] 1737 | } 1738 | ], 1739 | "requestBody": { 1740 | "content": { 1741 | "application/json": { 1742 | "schema": { 1743 | "$ref": "#/components/schemas/postAgentBuckets" 1744 | } 1745 | }, 1746 | "application/xml": { 1747 | "schema": { 1748 | "$ref": "#/components/schemas/postAgentBuckets" 1749 | } 1750 | } 1751 | } 1752 | } 1753 | } 1754 | }, 1755 | "/agents/{agentId}/threads/report": { 1756 | "get": { 1757 | "tags": [ 1758 | "Agent" 1759 | ], 1760 | "description": "에이전트의 스레드 로그 임시!! 획득", 1761 | "parameters": [ 1762 | { 1763 | "name": "agentId", 1764 | "in": "path", 1765 | "required": true, 1766 | "schema": { 1767 | "type": "string" 1768 | } 1769 | }, 1770 | { 1771 | "name": "googleDriveFolderId", 1772 | "in": "query", 1773 | "schema": { 1774 | "type": "string" 1775 | } 1776 | }, 1777 | { 1778 | "name": "fileName", 1779 | "in": "query", 1780 | "schema": { 1781 | "type": "string" 1782 | } 1783 | } 1784 | ], 1785 | "responses": { 1786 | "default": { 1787 | "description": "" 1788 | } 1789 | }, 1790 | "security": [ 1791 | { 1792 | "bearerAuth": [], 1793 | "ApiKeyAuth": [] 1794 | } 1795 | ] 1796 | } 1797 | }, 1798 | "/agents/{agentId}/versions": { 1799 | "get": { 1800 | "tags": [ 1801 | "Agent" 1802 | ], 1803 | "description": "에이전트의 배포 히스토리 목록 조회", 1804 | "parameters": [ 1805 | { 1806 | "name": "agentId", 1807 | "in": "path", 1808 | "required": true, 1809 | "schema": { 1810 | "type": "string" 1811 | } 1812 | } 1813 | ], 1814 | "responses": { 1815 | "default": { 1816 | "description": "" 1817 | } 1818 | }, 1819 | "security": [ 1820 | { 1821 | "bearerAuth": [], 1822 | "ApiKeyAuth": [] 1823 | } 1824 | ] 1825 | } 1826 | }, 1827 | "/agents/{agentId}/threads": { 1828 | "post": { 1829 | "tags": [ 1830 | "Agent" 1831 | ], 1832 | "description": "에이전트에 스레드 등록", 1833 | "parameters": [ 1834 | { 1835 | "name": "agentId", 1836 | "in": "path", 1837 | "required": true, 1838 | "schema": { 1839 | "type": "string" 1840 | } 1841 | }, 1842 | { 1843 | "name": "sse-connection-key", 1844 | "in": "header", 1845 | "schema": { 1846 | "type": "string" 1847 | } 1848 | } 1849 | ], 1850 | "responses": { 1851 | "default": { 1852 | "description": "" 1853 | } 1854 | }, 1855 | "security": [ 1856 | { 1857 | "bearerAuth": [], 1858 | "ApiKeyAuth": [] 1859 | } 1860 | ] 1861 | } 1862 | }, 1863 | "/agents/{agentId}/basic-instructions": { 1864 | "get": { 1865 | "description": "", 1866 | "parameters": [ 1867 | { 1868 | "name": "agentId", 1869 | "in": "path", 1870 | "required": true, 1871 | "schema": { 1872 | "type": "string" 1873 | } 1874 | } 1875 | ], 1876 | "responses": { 1877 | "default": { 1878 | "description": "" 1879 | } 1880 | }, 1881 | "security": [ 1882 | { 1883 | "bearerAuth": [], 1884 | "ApiKeyAuth": [] 1885 | } 1886 | ] 1887 | }, 1888 | "post": { 1889 | "description": "", 1890 | "parameters": [ 1891 | { 1892 | "name": "agentId", 1893 | "in": "path", 1894 | "required": true, 1895 | "schema": { 1896 | "type": "string" 1897 | } 1898 | } 1899 | ], 1900 | "responses": { 1901 | "default": { 1902 | "description": "" 1903 | } 1904 | }, 1905 | "security": [ 1906 | { 1907 | "bearerAuth": [], 1908 | "ApiKeyAuth": [] 1909 | } 1910 | ] 1911 | }, 1912 | "patch": { 1913 | "description": "", 1914 | "parameters": [ 1915 | { 1916 | "name": "agentId", 1917 | "in": "path", 1918 | "required": true, 1919 | "schema": { 1920 | "type": "string" 1921 | } 1922 | } 1923 | ], 1924 | "responses": { 1925 | "default": { 1926 | "description": "" 1927 | } 1928 | }, 1929 | "security": [ 1930 | { 1931 | "bearerAuth": [], 1932 | "ApiKeyAuth": [] 1933 | } 1934 | ] 1935 | }, 1936 | "delete": { 1937 | "description": "", 1938 | "parameters": [ 1939 | { 1940 | "name": "agentId", 1941 | "in": "path", 1942 | "required": true, 1943 | "schema": { 1944 | "type": "string" 1945 | } 1946 | } 1947 | ], 1948 | "responses": { 1949 | "default": { 1950 | "description": "" 1951 | } 1952 | }, 1953 | "security": [ 1954 | { 1955 | "bearerAuth": [], 1956 | "ApiKeyAuth": [] 1957 | } 1958 | ] 1959 | } 1960 | }, 1961 | "/agents/{agentId}/advices": { 1962 | "post": { 1963 | "tags": [ 1964 | "Agent" 1965 | ], 1966 | "description": "에이전트에 피드백 등록", 1967 | "parameters": [ 1968 | { 1969 | "name": "agentId", 1970 | "in": "path", 1971 | "required": true, 1972 | "schema": { 1973 | "type": "string" 1974 | } 1975 | }, 1976 | { 1977 | "name": "sse-connection-key", 1978 | "in": "header", 1979 | "schema": { 1980 | "type": "string" 1981 | } 1982 | } 1983 | ], 1984 | "responses": { 1985 | "default": { 1986 | "description": "" 1987 | } 1988 | }, 1989 | "security": [ 1990 | { 1991 | "bearerAuth": [], 1992 | "ApiKeyAuth": [] 1993 | } 1994 | ], 1995 | "requestBody": { 1996 | "content": { 1997 | "application/json": { 1998 | "schema": { 1999 | "type": "object", 2000 | "properties": { 2001 | "qnas": { 2002 | "example": "any" 2003 | } 2004 | } 2005 | } 2006 | } 2007 | } 2008 | } 2009 | } 2010 | }, 2011 | "/agents/{agentId}/configs": { 2012 | "post": { 2013 | "description": "", 2014 | "parameters": [ 2015 | { 2016 | "name": "agentId", 2017 | "in": "path", 2018 | "required": true, 2019 | "schema": { 2020 | "type": "string" 2021 | } 2022 | } 2023 | ], 2024 | "responses": { 2025 | "default": { 2026 | "description": "" 2027 | } 2028 | }, 2029 | "security": [ 2030 | { 2031 | "bearerAuth": [], 2032 | "ApiKeyAuth": [] 2033 | } 2034 | ], 2035 | "requestBody": { 2036 | "content": { 2037 | "application/json": { 2038 | "schema": { 2039 | "type": "object", 2040 | "properties": { 2041 | "promptTemplateRecipe": { 2042 | "example": "any" 2043 | }, 2044 | "systemConfig": { 2045 | "example": "any" 2046 | } 2047 | } 2048 | } 2049 | } 2050 | } 2051 | } 2052 | }, 2053 | "get": { 2054 | "description": "", 2055 | "parameters": [ 2056 | { 2057 | "name": "agentId", 2058 | "in": "path", 2059 | "required": true, 2060 | "schema": { 2061 | "type": "string" 2062 | } 2063 | } 2064 | ], 2065 | "responses": { 2066 | "default": { 2067 | "description": "" 2068 | } 2069 | }, 2070 | "security": [ 2071 | { 2072 | "bearerAuth": [], 2073 | "ApiKeyAuth": [] 2074 | } 2075 | ] 2076 | } 2077 | }, 2078 | "/documents/{documentId}": { 2079 | "get": { 2080 | "tags": [ 2081 | "Document" 2082 | ], 2083 | "description": "문서 정보 획득", 2084 | "parameters": [ 2085 | { 2086 | "name": "documentId", 2087 | "in": "path", 2088 | "required": true, 2089 | "schema": { 2090 | "type": "string" 2091 | } 2092 | } 2093 | ], 2094 | "responses": { 2095 | "default": { 2096 | "description": "" 2097 | } 2098 | }, 2099 | "security": [ 2100 | { 2101 | "bearerAuth": [], 2102 | "ApiKeyAuth": [] 2103 | } 2104 | ] 2105 | }, 2106 | "put": { 2107 | "tags": [ 2108 | "Document" 2109 | ], 2110 | "description": "문서 내용 수정 (URL로 등록한 문서)", 2111 | "parameters": [ 2112 | { 2113 | "name": "documentId", 2114 | "in": "path", 2115 | "required": true, 2116 | "schema": { 2117 | "type": "string" 2118 | } 2119 | } 2120 | ], 2121 | "responses": { 2122 | "default": { 2123 | "description": "" 2124 | } 2125 | }, 2126 | "security": [ 2127 | { 2128 | "bearerAuth": [], 2129 | "ApiKeyAuth": [] 2130 | } 2131 | ] 2132 | }, 2133 | "patch": { 2134 | "tags": [ 2135 | "Document" 2136 | ], 2137 | "description": "문서 정보 수정", 2138 | "parameters": [ 2139 | { 2140 | "name": "documentId", 2141 | "in": "path", 2142 | "required": true, 2143 | "schema": { 2144 | "type": "string" 2145 | } 2146 | }, 2147 | { 2148 | "name": "sse-connection-key", 2149 | "in": "header", 2150 | "schema": { 2151 | "type": "string" 2152 | } 2153 | } 2154 | ], 2155 | "responses": { 2156 | "default": { 2157 | "description": "" 2158 | } 2159 | }, 2160 | "security": [ 2161 | { 2162 | "bearerAuth": [], 2163 | "ApiKeyAuth": [] 2164 | } 2165 | ], 2166 | "requestBody": { 2167 | "content": { 2168 | "application/json": { 2169 | "schema": { 2170 | "type": "object", 2171 | "properties": { 2172 | "description": { 2173 | "example": "any" 2174 | }, 2175 | "bucketIds": { 2176 | "example": "any" 2177 | } 2178 | } 2179 | } 2180 | } 2181 | } 2182 | } 2183 | } 2184 | }, 2185 | "/documents/{documentId}/download": { 2186 | "get": { 2187 | "description": "", 2188 | "parameters": [ 2189 | { 2190 | "name": "documentId", 2191 | "in": "path", 2192 | "required": true, 2193 | "schema": { 2194 | "type": "string" 2195 | } 2196 | } 2197 | ], 2198 | "responses": { 2199 | "default": { 2200 | "description": "" 2201 | } 2202 | }, 2203 | "security": [ 2204 | { 2205 | "bearerAuth": [], 2206 | "ApiKeyAuth": [] 2207 | } 2208 | ] 2209 | } 2210 | }, 2211 | "/documents/": { 2212 | "delete": { 2213 | "tags": [ 2214 | "Agent" 2215 | ], 2216 | "description": "여러 개의 document 삭제", 2217 | "responses": { 2218 | "default": { 2219 | "description": "" 2220 | } 2221 | }, 2222 | "security": [ 2223 | { 2224 | "bearerAuth": [], 2225 | "ApiKeyAuth": [] 2226 | } 2227 | ], 2228 | "requestBody": { 2229 | "content": { 2230 | "application/json": { 2231 | "schema": { 2232 | "$ref": "#/components/schemas/deleteAgentKnowledges" 2233 | } 2234 | }, 2235 | "application/xml": { 2236 | "schema": { 2237 | "$ref": "#/components/schemas/deleteAgentKnowledges" 2238 | } 2239 | } 2240 | } 2241 | } 2242 | } 2243 | }, 2244 | "/buckets/{bucketId}": { 2245 | "patch": { 2246 | "tags": [ 2247 | "Bucket" 2248 | ], 2249 | "description": "버킷 정보 수정", 2250 | "parameters": [ 2251 | { 2252 | "name": "bucketId", 2253 | "in": "path", 2254 | "required": true, 2255 | "schema": { 2256 | "type": "string" 2257 | } 2258 | } 2259 | ], 2260 | "responses": { 2261 | "default": { 2262 | "description": "" 2263 | } 2264 | }, 2265 | "security": [ 2266 | { 2267 | "bearerAuth": [], 2268 | "ApiKeyAuth": [] 2269 | } 2270 | ], 2271 | "requestBody": { 2272 | "content": { 2273 | "application/json": { 2274 | "schema": { 2275 | "$ref": "#/components/schemas/patchBucket" 2276 | } 2277 | }, 2278 | "application/xml": { 2279 | "schema": { 2280 | "$ref": "#/components/schemas/patchBucket" 2281 | } 2282 | } 2283 | } 2284 | } 2285 | }, 2286 | "delete": { 2287 | "tags": [ 2288 | "Bucket" 2289 | ], 2290 | "description": "버킷 삭제", 2291 | "parameters": [ 2292 | { 2293 | "name": "bucketId", 2294 | "in": "path", 2295 | "required": true, 2296 | "schema": { 2297 | "type": "string" 2298 | } 2299 | } 2300 | ], 2301 | "responses": { 2302 | "default": { 2303 | "description": "" 2304 | } 2305 | }, 2306 | "security": [ 2307 | { 2308 | "bearerAuth": [], 2309 | "ApiKeyAuth": [] 2310 | } 2311 | ] 2312 | } 2313 | }, 2314 | "/threads/{threadId}/chats": { 2315 | "post": { 2316 | "tags": [ 2317 | "Thread" 2318 | ], 2319 | "description": "스레드에 질문 등록", 2320 | "parameters": [ 2321 | { 2322 | "name": "threadId", 2323 | "in": "path", 2324 | "required": true, 2325 | "schema": { 2326 | "type": "string" 2327 | } 2328 | } 2329 | ], 2330 | "responses": { 2331 | "default": { 2332 | "description": "" 2333 | } 2334 | }, 2335 | "security": [ 2336 | { 2337 | "bearerAuth": [], 2338 | "ApiKeyAuth": [] 2339 | } 2340 | ], 2341 | "requestBody": { 2342 | "content": { 2343 | "application/json": { 2344 | "schema": { 2345 | "$ref": "#/components/schemas/postThreadReply" 2346 | } 2347 | }, 2348 | "application/xml": { 2349 | "schema": { 2350 | "$ref": "#/components/schemas/postThreadReply" 2351 | } 2352 | } 2353 | } 2354 | } 2355 | } 2356 | }, 2357 | "/chats/": { 2358 | "get": { 2359 | "description": "", 2360 | "responses": { 2361 | "default": { 2362 | "description": "" 2363 | } 2364 | }, 2365 | "security": [ 2366 | { 2367 | "bearerAuth": [], 2368 | "ApiKeyAuth": [] 2369 | } 2370 | ] 2371 | } 2372 | }, 2373 | "/chats/download": { 2374 | "post": { 2375 | "description": "", 2376 | "responses": { 2377 | "default": { 2378 | "description": "" 2379 | } 2380 | }, 2381 | "security": [ 2382 | { 2383 | "bearerAuth": [], 2384 | "ApiKeyAuth": [] 2385 | } 2386 | ] 2387 | } 2388 | }, 2389 | "/chats/{chatId}": { 2390 | "get": { 2391 | "tags": [ 2392 | "Chat" 2393 | ], 2394 | "description": "챗 조회", 2395 | "parameters": [ 2396 | { 2397 | "name": "chatId", 2398 | "in": "path", 2399 | "required": true, 2400 | "schema": { 2401 | "type": "string" 2402 | } 2403 | } 2404 | ], 2405 | "responses": { 2406 | "default": { 2407 | "description": "" 2408 | } 2409 | }, 2410 | "security": [ 2411 | { 2412 | "bearerAuth": [], 2413 | "ApiKeyAuth": [] 2414 | } 2415 | ] 2416 | }, 2417 | "patch": { 2418 | "description": "", 2419 | "parameters": [ 2420 | { 2421 | "name": "chatId", 2422 | "in": "path", 2423 | "required": true, 2424 | "schema": { 2425 | "type": "string" 2426 | } 2427 | } 2428 | ], 2429 | "responses": { 2430 | "default": { 2431 | "description": "" 2432 | } 2433 | }, 2434 | "security": [ 2435 | { 2436 | "bearerAuth": [], 2437 | "ApiKeyAuth": [] 2438 | } 2439 | ] 2440 | } 2441 | }, 2442 | "/chats/{chatId}/sources": { 2443 | "get": { 2444 | "tags": [ 2445 | "Chat" 2446 | ], 2447 | "description": "관련 소스 조회", 2448 | "parameters": [ 2449 | { 2450 | "name": "chatId", 2451 | "in": "path", 2452 | "required": true, 2453 | "schema": { 2454 | "type": "string" 2455 | } 2456 | } 2457 | ], 2458 | "responses": { 2459 | "default": { 2460 | "description": "" 2461 | } 2462 | }, 2463 | "security": [ 2464 | { 2465 | "bearerAuth": [], 2466 | "ApiKeyAuth": [] 2467 | } 2468 | ] 2469 | } 2470 | }, 2471 | "/chats/{chatId}/chat-advices": { 2472 | "post": { 2473 | "description": "", 2474 | "parameters": [ 2475 | { 2476 | "name": "chatId", 2477 | "in": "path", 2478 | "required": true, 2479 | "schema": { 2480 | "type": "string" 2481 | } 2482 | }, 2483 | { 2484 | "name": "sse-connection-key", 2485 | "in": "header", 2486 | "schema": { 2487 | "type": "string" 2488 | } 2489 | } 2490 | ], 2491 | "responses": { 2492 | "default": { 2493 | "description": "" 2494 | } 2495 | }, 2496 | "security": [ 2497 | { 2498 | "bearerAuth": [], 2499 | "ApiKeyAuth": [] 2500 | } 2501 | ], 2502 | "requestBody": { 2503 | "content": { 2504 | "application/json": { 2505 | "schema": { 2506 | "type": "object", 2507 | "properties": { 2508 | "type": { 2509 | "example": "any" 2510 | }, 2511 | "qna": { 2512 | "example": "any" 2513 | }, 2514 | "bucketId": { 2515 | "example": "any" 2516 | } 2517 | } 2518 | } 2519 | } 2520 | } 2521 | } 2522 | } 2523 | }, 2524 | "/chats/{chatId}/chat-advices/{chatAdviceId}": { 2525 | "patch": { 2526 | "description": "", 2527 | "parameters": [ 2528 | { 2529 | "name": "chatId", 2530 | "in": "path", 2531 | "required": true, 2532 | "schema": { 2533 | "type": "string" 2534 | } 2535 | }, 2536 | { 2537 | "name": "chatAdviceId", 2538 | "in": "path", 2539 | "required": true, 2540 | "schema": { 2541 | "type": "string" 2542 | } 2543 | }, 2544 | { 2545 | "name": "sse-connection-key", 2546 | "in": "header", 2547 | "schema": { 2548 | "type": "string" 2549 | } 2550 | } 2551 | ], 2552 | "responses": { 2553 | "default": { 2554 | "description": "" 2555 | } 2556 | }, 2557 | "security": [ 2558 | { 2559 | "bearerAuth": [], 2560 | "ApiKeyAuth": [] 2561 | } 2562 | ], 2563 | "requestBody": { 2564 | "content": { 2565 | "application/json": { 2566 | "schema": { 2567 | "type": "object", 2568 | "properties": { 2569 | "qna": { 2570 | "example": "any" 2571 | }, 2572 | "bucketId": { 2573 | "example": "any" 2574 | } 2575 | } 2576 | } 2577 | } 2578 | } 2579 | } 2580 | }, 2581 | "delete": { 2582 | "description": "", 2583 | "parameters": [ 2584 | { 2585 | "name": "chatId", 2586 | "in": "path", 2587 | "required": true, 2588 | "schema": { 2589 | "type": "string" 2590 | } 2591 | }, 2592 | { 2593 | "name": "chatAdviceId", 2594 | "in": "path", 2595 | "required": true, 2596 | "schema": { 2597 | "type": "string" 2598 | } 2599 | }, 2600 | { 2601 | "name": "sse-connection-key", 2602 | "in": "header", 2603 | "schema": { 2604 | "type": "string" 2605 | } 2606 | } 2607 | ], 2608 | "responses": { 2609 | "default": { 2610 | "description": "" 2611 | } 2612 | }, 2613 | "security": [ 2614 | { 2615 | "bearerAuth": [], 2616 | "ApiKeyAuth": [] 2617 | } 2618 | ] 2619 | } 2620 | }, 2621 | "/chat-advices/{chatAdviceId}": { 2622 | "get": { 2623 | "description": "", 2624 | "parameters": [ 2625 | { 2626 | "name": "chatAdviceId", 2627 | "in": "path", 2628 | "required": true, 2629 | "schema": { 2630 | "type": "string" 2631 | } 2632 | } 2633 | ], 2634 | "responses": { 2635 | "default": { 2636 | "description": "" 2637 | } 2638 | }, 2639 | "security": [ 2640 | { 2641 | "bearerAuth": [], 2642 | "ApiKeyAuth": [] 2643 | } 2644 | ] 2645 | } 2646 | }, 2647 | "/chat-advices/": { 2648 | "delete": { 2649 | "description": "", 2650 | "parameters": [ 2651 | { 2652 | "name": "sse-connection-key", 2653 | "in": "header", 2654 | "schema": { 2655 | "type": "string" 2656 | } 2657 | } 2658 | ], 2659 | "responses": { 2660 | "default": { 2661 | "description": "" 2662 | } 2663 | }, 2664 | "security": [ 2665 | { 2666 | "bearerAuth": [], 2667 | "ApiKeyAuth": [] 2668 | } 2669 | ], 2670 | "requestBody": { 2671 | "content": { 2672 | "application/json": { 2673 | "schema": { 2674 | "type": "object", 2675 | "properties": { 2676 | "chatAdviceIds": { 2677 | "example": "any" 2678 | } 2679 | } 2680 | } 2681 | } 2682 | } 2683 | } 2684 | } 2685 | }, 2686 | "/sse/": { 2687 | "post": { 2688 | "tags": [ 2689 | "SSE" 2690 | ], 2691 | "description": "테스트 페이지 접속시 SSE connection 생성", 2692 | "responses": { 2693 | "default": { 2694 | "description": "" 2695 | } 2696 | }, 2697 | "security": [ 2698 | { 2699 | "bearerAuth": [], 2700 | "ApiKeyAuth": [] 2701 | } 2702 | ] 2703 | }, 2704 | "delete": { 2705 | "tags": [ 2706 | "SSE" 2707 | ], 2708 | "description": "SSE connection 해제", 2709 | "parameters": [ 2710 | { 2711 | "name": "sse-connection-key", 2712 | "in": "header", 2713 | "schema": { 2714 | "type": "string" 2715 | } 2716 | } 2717 | ], 2718 | "responses": { 2719 | "default": { 2720 | "description": "" 2721 | } 2722 | }, 2723 | "security": [ 2724 | { 2725 | "bearerAuth": [], 2726 | "ApiKeyAuth": [] 2727 | } 2728 | ] 2729 | } 2730 | }, 2731 | "/admin/teams": { 2732 | "post": { 2733 | "description": "", 2734 | "responses": { 2735 | "default": { 2736 | "description": "" 2737 | } 2738 | }, 2739 | "requestBody": { 2740 | "content": { 2741 | "application/json": { 2742 | "schema": { 2743 | "type": "object", 2744 | "properties": { 2745 | "name": { 2746 | "example": "any" 2747 | }, 2748 | "users": { 2749 | "example": "any" 2750 | } 2751 | } 2752 | } 2753 | } 2754 | } 2755 | } 2756 | } 2757 | }, 2758 | "/admin/documents": { 2759 | "post": { 2760 | "description": "", 2761 | "responses": { 2762 | "default": { 2763 | "description": "" 2764 | } 2765 | }, 2766 | "requestBody": { 2767 | "content": { 2768 | "application/json": { 2769 | "schema": { 2770 | "type": "object", 2771 | "properties": { 2772 | "webhookUrl": { 2773 | "example": "any" 2774 | } 2775 | } 2776 | } 2777 | } 2778 | } 2779 | } 2780 | } 2781 | }, 2782 | "/advices/{adviceId}": { 2783 | "get": { 2784 | "tags": [ 2785 | "Advice" 2786 | ], 2787 | "description": "피드백 정보 조회", 2788 | "parameters": [ 2789 | { 2790 | "name": "adviceId", 2791 | "in": "path", 2792 | "required": true, 2793 | "schema": { 2794 | "type": "string" 2795 | } 2796 | } 2797 | ], 2798 | "responses": { 2799 | "default": { 2800 | "description": "" 2801 | } 2802 | }, 2803 | "security": [ 2804 | { 2805 | "bearerAuth": [], 2806 | "ApiKeyAuth": [] 2807 | } 2808 | ] 2809 | }, 2810 | "patch": { 2811 | "tags": [ 2812 | "Advice" 2813 | ], 2814 | "description": "피드백 정보 수정", 2815 | "parameters": [ 2816 | { 2817 | "name": "adviceId", 2818 | "in": "path", 2819 | "required": true, 2820 | "schema": { 2821 | "type": "string" 2822 | } 2823 | }, 2824 | { 2825 | "name": "sse-connection-key", 2826 | "in": "header", 2827 | "schema": { 2828 | "type": "string" 2829 | } 2830 | } 2831 | ], 2832 | "responses": { 2833 | "default": { 2834 | "description": "" 2835 | } 2836 | }, 2837 | "security": [ 2838 | { 2839 | "bearerAuth": [], 2840 | "ApiKeyAuth": [] 2841 | } 2842 | ] 2843 | } 2844 | }, 2845 | "/advices/": { 2846 | "delete": { 2847 | "tags": [ 2848 | "Advice" 2849 | ], 2850 | "description": "여러 개의 피드백 삭제", 2851 | "parameters": [ 2852 | { 2853 | "name": "sse-connection-key", 2854 | "in": "header", 2855 | "schema": { 2856 | "type": "string" 2857 | } 2858 | } 2859 | ], 2860 | "responses": { 2861 | "default": { 2862 | "description": "" 2863 | } 2864 | }, 2865 | "security": [ 2866 | { 2867 | "bearerAuth": [], 2868 | "ApiKeyAuth": [] 2869 | } 2870 | ], 2871 | "requestBody": { 2872 | "content": { 2873 | "application/json": { 2874 | "schema": { 2875 | "type": "object", 2876 | "properties": { 2877 | "adviceIds": { 2878 | "example": "any" 2879 | } 2880 | } 2881 | } 2882 | } 2883 | } 2884 | } 2885 | } 2886 | }, 2887 | "/api-keys/": { 2888 | "post": { 2889 | "description": "", 2890 | "responses": { 2891 | "default": { 2892 | "description": "" 2893 | } 2894 | }, 2895 | "security": [ 2896 | { 2897 | "bearerAuth": [], 2898 | "ApiKeyAuth": [] 2899 | } 2900 | ], 2901 | "requestBody": { 2902 | "content": { 2903 | "application/json": { 2904 | "schema": { 2905 | "type": "object", 2906 | "properties": { 2907 | "name": { 2908 | "example": "any" 2909 | } 2910 | } 2911 | } 2912 | } 2913 | } 2914 | } 2915 | } 2916 | }, 2917 | "/deployments/{deploymentId}": { 2918 | "delete": { 2919 | "description": "", 2920 | "parameters": [ 2921 | { 2922 | "name": "deploymentId", 2923 | "in": "path", 2924 | "required": true, 2925 | "schema": { 2926 | "type": "string" 2927 | } 2928 | }, 2929 | { 2930 | "name": "sse-connection-key", 2931 | "in": "header", 2932 | "schema": { 2933 | "type": "string" 2934 | } 2935 | } 2936 | ], 2937 | "responses": { 2938 | "default": { 2939 | "description": "" 2940 | } 2941 | }, 2942 | "security": [ 2943 | { 2944 | "bearerAuth": [], 2945 | "ApiKeyAuth": [] 2946 | } 2947 | ] 2948 | } 2949 | }, 2950 | "/api/guest/test/": { 2951 | "post": { 2952 | "description": "", 2953 | "responses": { 2954 | "default": { 2955 | "description": "" 2956 | } 2957 | } 2958 | } 2959 | }, 2960 | "/api/guest/sessions/": { 2961 | "post": { 2962 | "description": "", 2963 | "parameters": [ 2964 | { 2965 | "name": "x-storm-guest-id", 2966 | "in": "header", 2967 | "schema": { 2968 | "type": "string" 2969 | } 2970 | } 2971 | ], 2972 | "responses": { 2973 | "default": { 2974 | "description": "" 2975 | } 2976 | } 2977 | }, 2978 | "delete": { 2979 | "description": "", 2980 | "parameters": [ 2981 | { 2982 | "name": "agentId", 2983 | "in": "query", 2984 | "schema": { 2985 | "type": "string" 2986 | } 2987 | }, 2988 | { 2989 | "name": "ttl", 2990 | "in": "query", 2991 | "schema": { 2992 | "type": "string" 2993 | } 2994 | } 2995 | ], 2996 | "responses": { 2997 | "default": { 2998 | "description": "" 2999 | } 3000 | } 3001 | } 3002 | }, 3003 | "/api/guest/documents/": { 3004 | "post": { 3005 | "tags": [ 3006 | "API v1" 3007 | ], 3008 | "description": "학습 요청", 3009 | "responses": { 3010 | "default": { 3011 | "description": "" 3012 | } 3013 | }, 3014 | "requestBody": { 3015 | "content": { 3016 | "application/json": { 3017 | "schema": { 3018 | "type": "object", 3019 | "properties": { 3020 | "webhookUrl": { 3021 | "example": "any" 3022 | }, 3023 | "urls": { 3024 | "example": "any" 3025 | }, 3026 | "postActions": { 3027 | "example": "any" 3028 | } 3029 | } 3030 | } 3031 | } 3032 | } 3033 | } 3034 | } 3035 | }, 3036 | "/api/guest/documents/{documentId}": { 3037 | "get": { 3038 | "tags": [ 3039 | "API v1" 3040 | ], 3041 | "description": "문서 정보 획득", 3042 | "parameters": [ 3043 | { 3044 | "name": "documentId", 3045 | "in": "path", 3046 | "required": true, 3047 | "schema": { 3048 | "type": "string" 3049 | } 3050 | } 3051 | ], 3052 | "responses": { 3053 | "default": { 3054 | "description": "" 3055 | } 3056 | } 3057 | } 3058 | }, 3059 | "/api/guest/contexts/": { 3060 | "post": { 3061 | "description": "", 3062 | "responses": { 3063 | "default": { 3064 | "description": "" 3065 | } 3066 | }, 3067 | "requestBody": { 3068 | "content": { 3069 | "application/json": { 3070 | "schema": { 3071 | "type": "object", 3072 | "properties": { 3073 | "question": { 3074 | "example": "any" 3075 | } 3076 | } 3077 | } 3078 | } 3079 | } 3080 | } 3081 | } 3082 | }, 3083 | "/api/{version}/buckets/": { 3084 | "post": { 3085 | "tags": [ 3086 | "API v1" 3087 | ], 3088 | "description": "에이전트에 버킷 등록", 3089 | "parameters": [ 3090 | { 3091 | "name": "version", 3092 | "in": "path", 3093 | "required": true, 3094 | "schema": { 3095 | "type": "string" 3096 | } 3097 | } 3098 | ], 3099 | "responses": { 3100 | "default": { 3101 | "description": "" 3102 | } 3103 | } 3104 | } 3105 | }, 3106 | "/api/{version}/buckets/{bucketId}": { 3107 | "patch": { 3108 | "tags": [ 3109 | "API v1" 3110 | ], 3111 | "description": "버킷 정보 수정", 3112 | "parameters": [ 3113 | { 3114 | "name": "version", 3115 | "in": "path", 3116 | "required": true, 3117 | "schema": { 3118 | "type": "string" 3119 | } 3120 | }, 3121 | { 3122 | "name": "bucketId", 3123 | "in": "path", 3124 | "required": true, 3125 | "schema": { 3126 | "type": "string" 3127 | } 3128 | } 3129 | ], 3130 | "responses": { 3131 | "default": { 3132 | "description": "" 3133 | } 3134 | } 3135 | } 3136 | }, 3137 | "/api/{version}/documents/": { 3138 | "post": { 3139 | "tags": [ 3140 | "API v1" 3141 | ], 3142 | "description": "학습 요청", 3143 | "parameters": [ 3144 | { 3145 | "name": "version", 3146 | "in": "path", 3147 | "required": true, 3148 | "schema": { 3149 | "type": "string" 3150 | } 3151 | } 3152 | ], 3153 | "responses": { 3154 | "default": { 3155 | "description": "" 3156 | } 3157 | }, 3158 | "requestBody": { 3159 | "content": { 3160 | "application/json": { 3161 | "schema": { 3162 | "type": "object", 3163 | "properties": { 3164 | "webhookUrl": { 3165 | "example": "any" 3166 | }, 3167 | "urls": { 3168 | "example": "any" 3169 | }, 3170 | "postActions": { 3171 | "example": "any" 3172 | } 3173 | } 3174 | } 3175 | } 3176 | } 3177 | } 3178 | } 3179 | }, 3180 | "/api/{version}/documents/{documentId}": { 3181 | "get": { 3182 | "tags": [ 3183 | "API v1" 3184 | ], 3185 | "description": "문서 정보 획득", 3186 | "parameters": [ 3187 | { 3188 | "name": "version", 3189 | "in": "path", 3190 | "required": true, 3191 | "schema": { 3192 | "type": "string" 3193 | } 3194 | }, 3195 | { 3196 | "name": "documentId", 3197 | "in": "path", 3198 | "required": true, 3199 | "schema": { 3200 | "type": "string" 3201 | } 3202 | } 3203 | ], 3204 | "responses": { 3205 | "default": { 3206 | "description": "" 3207 | } 3208 | } 3209 | } 3210 | }, 3211 | "/api/{version}/threads/": { 3212 | "post": { 3213 | "tags": [ 3214 | "API v1" 3215 | ], 3216 | "description": "스레드 등록", 3217 | "parameters": [ 3218 | { 3219 | "name": "version", 3220 | "in": "path", 3221 | "required": true, 3222 | "schema": { 3223 | "type": "string" 3224 | } 3225 | } 3226 | ], 3227 | "responses": { 3228 | "default": { 3229 | "description": "" 3230 | } 3231 | } 3232 | } 3233 | }, 3234 | "/api/{version}/threads/{threadId}/chats": { 3235 | "post": { 3236 | "tags": [ 3237 | "API v1" 3238 | ], 3239 | "description": "채팅 전송", 3240 | "parameters": [ 3241 | { 3242 | "name": "version", 3243 | "in": "path", 3244 | "required": true, 3245 | "schema": { 3246 | "type": "string" 3247 | } 3248 | }, 3249 | { 3250 | "name": "threadId", 3251 | "in": "path", 3252 | "required": true, 3253 | "schema": { 3254 | "type": "string" 3255 | } 3256 | } 3257 | ], 3258 | "responses": { 3259 | "default": { 3260 | "description": "" 3261 | } 3262 | }, 3263 | "requestBody": { 3264 | "content": { 3265 | "application/json": { 3266 | "schema": { 3267 | "type": "object", 3268 | "properties": { 3269 | "question": { 3270 | "example": "any" 3271 | }, 3272 | "bucketIds": { 3273 | "example": "any" 3274 | }, 3275 | "isStreaming": { 3276 | "example": "any" 3277 | }, 3278 | "isContextOnly": { 3279 | "example": "any" 3280 | }, 3281 | "webhookUrl": { 3282 | "example": "any" 3283 | }, 3284 | "engine": { 3285 | "example": "any" 3286 | } 3287 | } 3288 | } 3289 | } 3290 | } 3291 | } 3292 | } 3293 | }, 3294 | "/api/{version}/answer/": { 3295 | "post": { 3296 | "tags": [ 3297 | "API v1" 3298 | ], 3299 | "description": "채널 API 연동으로 질문 등록", 3300 | "parameters": [ 3301 | { 3302 | "name": "version", 3303 | "in": "path", 3304 | "required": true, 3305 | "schema": { 3306 | "type": "string" 3307 | } 3308 | } 3309 | ], 3310 | "responses": { 3311 | "default": { 3312 | "description": "" 3313 | } 3314 | }, 3315 | "requestBody": { 3316 | "content": { 3317 | "application/json": { 3318 | "schema": { 3319 | "type": "object", 3320 | "properties": { 3321 | "question": { 3322 | "example": "any" 3323 | }, 3324 | "bucketIds": { 3325 | "example": "any" 3326 | }, 3327 | "isStreaming": { 3328 | "example": "any" 3329 | }, 3330 | "isContextOnly": { 3331 | "example": "any" 3332 | }, 3333 | "webhookUrl": { 3334 | "example": "any" 3335 | }, 3336 | "engine": { 3337 | "example": "any" 3338 | } 3339 | } 3340 | } 3341 | } 3342 | } 3343 | } 3344 | } 3345 | }, 3346 | "/api/{version}/agents/{agentId}/deployments": { 3347 | "post": { 3348 | "description": "", 3349 | "parameters": [ 3350 | { 3351 | "name": "version", 3352 | "in": "path", 3353 | "required": true, 3354 | "schema": { 3355 | "type": "string" 3356 | } 3357 | }, 3358 | { 3359 | "name": "agentId", 3360 | "in": "path", 3361 | "required": true, 3362 | "schema": { 3363 | "type": "string" 3364 | } 3365 | } 3366 | ], 3367 | "responses": { 3368 | "default": { 3369 | "description": "" 3370 | } 3371 | }, 3372 | "requestBody": { 3373 | "content": { 3374 | "application/json": { 3375 | "schema": { 3376 | "type": "object", 3377 | "properties": { 3378 | "memo": { 3379 | "example": "any" 3380 | }, 3381 | "agentVersionId": { 3382 | "example": "any" 3383 | } 3384 | } 3385 | } 3386 | } 3387 | } 3388 | } 3389 | } 3390 | }, 3391 | "/channels/{channelId}": { 3392 | "get": { 3393 | "description": "", 3394 | "parameters": [ 3395 | { 3396 | "name": "channelId", 3397 | "in": "path", 3398 | "required": true, 3399 | "schema": { 3400 | "type": "string" 3401 | } 3402 | } 3403 | ], 3404 | "responses": { 3405 | "default": { 3406 | "description": "" 3407 | } 3408 | }, 3409 | "security": [ 3410 | { 3411 | "bearerAuth": [], 3412 | "ApiKeyAuth": [] 3413 | } 3414 | ] 3415 | }, 3416 | "patch": { 3417 | "description": "", 3418 | "parameters": [ 3419 | { 3420 | "name": "channelId", 3421 | "in": "path", 3422 | "required": true, 3423 | "schema": { 3424 | "type": "string" 3425 | } 3426 | } 3427 | ], 3428 | "responses": { 3429 | "default": { 3430 | "description": "" 3431 | } 3432 | }, 3433 | "security": [ 3434 | { 3435 | "bearerAuth": [], 3436 | "ApiKeyAuth": [] 3437 | } 3438 | ], 3439 | "requestBody": { 3440 | "content": { 3441 | "application/json": { 3442 | "schema": { 3443 | "type": "object", 3444 | "properties": { 3445 | "type": { 3446 | "example": "any" 3447 | }, 3448 | "name": { 3449 | "example": "any" 3450 | }, 3451 | "kakaoBotId": { 3452 | "example": "any" 3453 | } 3454 | } 3455 | } 3456 | } 3457 | } 3458 | } 3459 | }, 3460 | "delete": { 3461 | "description": "", 3462 | "parameters": [ 3463 | { 3464 | "name": "channelId", 3465 | "in": "path", 3466 | "required": true, 3467 | "schema": { 3468 | "type": "string" 3469 | } 3470 | } 3471 | ], 3472 | "responses": { 3473 | "default": { 3474 | "description": "" 3475 | } 3476 | }, 3477 | "security": [ 3478 | { 3479 | "bearerAuth": [], 3480 | "ApiKeyAuth": [] 3481 | } 3482 | ] 3483 | } 3484 | }, 3485 | "/channels/{channelId}/renew-token": { 3486 | "post": { 3487 | "description": "", 3488 | "parameters": [ 3489 | { 3490 | "name": "channelId", 3491 | "in": "path", 3492 | "required": true, 3493 | "schema": { 3494 | "type": "string" 3495 | } 3496 | } 3497 | ], 3498 | "responses": { 3499 | "default": { 3500 | "description": "" 3501 | } 3502 | }, 3503 | "security": [ 3504 | { 3505 | "bearerAuth": [], 3506 | "ApiKeyAuth": [] 3507 | } 3508 | ] 3509 | } 3510 | }, 3511 | "/write/": { 3512 | "post": { 3513 | "tags": [ 3514 | "Write" 3515 | ], 3516 | "description": "기사 생성", 3517 | "parameters": [ 3518 | { 3519 | "name": "sse-connection-key", 3520 | "in": "header", 3521 | "schema": { 3522 | "type": "string" 3523 | } 3524 | } 3525 | ], 3526 | "responses": { 3527 | "default": { 3528 | "description": "" 3529 | } 3530 | }, 3531 | "security": [ 3532 | { 3533 | "bearerAuth": [], 3534 | "ApiKeyAuth": [] 3535 | } 3536 | ], 3537 | "requestBody": { 3538 | "content": { 3539 | "application/json": { 3540 | "schema": { 3541 | "type": "object", 3542 | "properties": { 3543 | "testId": { 3544 | "example": "any" 3545 | }, 3546 | "text": { 3547 | "example": "any" 3548 | }, 3549 | "metadata": { 3550 | "example": "any" 3551 | } 3552 | } 3553 | } 3554 | } 3555 | } 3556 | } 3557 | } 3558 | }, 3559 | "/write/refine/title": { 3560 | "post": { 3561 | "tags": [ 3562 | "Write" 3563 | ], 3564 | "description": "기사 제목 정제", 3565 | "parameters": [ 3566 | { 3567 | "name": "sse-connection-key", 3568 | "in": "header", 3569 | "schema": { 3570 | "type": "string" 3571 | } 3572 | } 3573 | ], 3574 | "responses": { 3575 | "default": { 3576 | "description": "" 3577 | } 3578 | }, 3579 | "security": [ 3580 | { 3581 | "bearerAuth": [], 3582 | "ApiKeyAuth": [] 3583 | } 3584 | ], 3585 | "requestBody": { 3586 | "content": { 3587 | "application/json": { 3588 | "schema": { 3589 | "type": "object", 3590 | "properties": { 3591 | "testId": { 3592 | "example": "any" 3593 | }, 3594 | "text": { 3595 | "example": "any" 3596 | }, 3597 | "metadata": { 3598 | "example": "any" 3599 | } 3600 | } 3601 | } 3602 | } 3603 | } 3604 | } 3605 | } 3606 | }, 3607 | "/write/refine/subtitle": { 3608 | "post": { 3609 | "tags": [ 3610 | "Write" 3611 | ], 3612 | "description": "기사 부제목 정제", 3613 | "parameters": [ 3614 | { 3615 | "name": "sse-connection-key", 3616 | "in": "header", 3617 | "schema": { 3618 | "type": "string" 3619 | } 3620 | } 3621 | ], 3622 | "responses": { 3623 | "default": { 3624 | "description": "" 3625 | } 3626 | }, 3627 | "security": [ 3628 | { 3629 | "bearerAuth": [], 3630 | "ApiKeyAuth": [] 3631 | } 3632 | ], 3633 | "requestBody": { 3634 | "content": { 3635 | "application/json": { 3636 | "schema": { 3637 | "type": "object", 3638 | "properties": { 3639 | "testId": { 3640 | "example": "any" 3641 | }, 3642 | "text": { 3643 | "example": "any" 3644 | }, 3645 | "title": { 3646 | "example": "any" 3647 | }, 3648 | "metadata": { 3649 | "example": "any" 3650 | } 3651 | } 3652 | } 3653 | } 3654 | } 3655 | } 3656 | } 3657 | }, 3658 | "/write/refine/lead": { 3659 | "post": { 3660 | "tags": [ 3661 | "Write" 3662 | ], 3663 | "description": "기사 리드문 정제", 3664 | "parameters": [ 3665 | { 3666 | "name": "sse-connection-key", 3667 | "in": "header", 3668 | "schema": { 3669 | "type": "string" 3670 | } 3671 | } 3672 | ], 3673 | "responses": { 3674 | "default": { 3675 | "description": "" 3676 | } 3677 | }, 3678 | "security": [ 3679 | { 3680 | "bearerAuth": [], 3681 | "ApiKeyAuth": [] 3682 | } 3683 | ], 3684 | "requestBody": { 3685 | "content": { 3686 | "application/json": { 3687 | "schema": { 3688 | "type": "object", 3689 | "properties": { 3690 | "testId": { 3691 | "example": "any" 3692 | }, 3693 | "text": { 3694 | "example": "any" 3695 | }, 3696 | "title": { 3697 | "example": "any" 3698 | }, 3699 | "subtitle": { 3700 | "example": "any" 3701 | }, 3702 | "metadata": { 3703 | "example": "any" 3704 | } 3705 | } 3706 | } 3707 | } 3708 | } 3709 | } 3710 | } 3711 | }, 3712 | "/write/refine/body": { 3713 | "post": { 3714 | "tags": [ 3715 | "Write" 3716 | ], 3717 | "description": "기사 바디문 정제", 3718 | "parameters": [ 3719 | { 3720 | "name": "sse-connection-key", 3721 | "in": "header", 3722 | "schema": { 3723 | "type": "string" 3724 | } 3725 | } 3726 | ], 3727 | "responses": { 3728 | "default": { 3729 | "description": "" 3730 | } 3731 | }, 3732 | "security": [ 3733 | { 3734 | "bearerAuth": [], 3735 | "ApiKeyAuth": [] 3736 | } 3737 | ], 3738 | "requestBody": { 3739 | "content": { 3740 | "application/json": { 3741 | "schema": { 3742 | "type": "object", 3743 | "properties": { 3744 | "testId": { 3745 | "example": "any" 3746 | }, 3747 | "text": { 3748 | "example": "any" 3749 | }, 3750 | "title": { 3751 | "example": "any" 3752 | }, 3753 | "subtitle": { 3754 | "example": "any" 3755 | }, 3756 | "metadata": { 3757 | "example": "any" 3758 | } 3759 | } 3760 | } 3761 | } 3762 | } 3763 | } 3764 | } 3765 | }, 3766 | "/write/report": { 3767 | "get": { 3768 | "tags": [ 3769 | "Agent" 3770 | ], 3771 | "description": "write report 생성", 3772 | "parameters": [ 3773 | { 3774 | "name": "testId", 3775 | "in": "query", 3776 | "schema": { 3777 | "type": "string" 3778 | } 3779 | }, 3780 | { 3781 | "name": "googleDriveFolderId", 3782 | "in": "query", 3783 | "schema": { 3784 | "type": "string" 3785 | } 3786 | }, 3787 | { 3788 | "name": "fileName", 3789 | "in": "query", 3790 | "schema": { 3791 | "type": "string" 3792 | } 3793 | } 3794 | ], 3795 | "responses": { 3796 | "default": { 3797 | "description": "" 3798 | } 3799 | }, 3800 | "security": [ 3801 | { 3802 | "bearerAuth": [], 3803 | "ApiKeyAuth": [] 3804 | } 3805 | ] 3806 | } 3807 | }, 3808 | "/models/": { 3809 | "get": { 3810 | "description": "", 3811 | "responses": { 3812 | "default": { 3813 | "description": "" 3814 | } 3815 | }, 3816 | "security": [ 3817 | { 3818 | "bearerAuth": [], 3819 | "ApiKeyAuth": [] 3820 | } 3821 | ] 3822 | } 3823 | } 3824 | }, 3825 | "components": { 3826 | "parameters": { 3827 | "search": { 3828 | "in": "query", 3829 | "name": "search", 3830 | "schema": { 3831 | "type": "string" 3832 | } 3833 | }, 3834 | "order": { 3835 | "in": "query", 3836 | "name": "order", 3837 | "schema": { 3838 | "type": "string" 3839 | } 3840 | }, 3841 | "cursor": { 3842 | "in": "query", 3843 | "name": "cursor", 3844 | "schema": { 3845 | "type": "string" 3846 | } 3847 | }, 3848 | "take": { 3849 | "in": "query", 3850 | "name": "take", 3851 | "schema": { 3852 | "type": "integer", 3853 | "minimun": 1 3854 | } 3855 | }, 3856 | "files": { 3857 | "in": "formData", 3858 | "name": "files", 3859 | "schema": { 3860 | "type": "array", 3861 | "items": { 3862 | "type": "string", 3863 | "format": "binary" 3864 | } 3865 | } 3866 | } 3867 | }, 3868 | "schemas": { 3869 | "postAuthSignup": { 3870 | "type": "object", 3871 | "properties": { 3872 | "email": { 3873 | "type": "string", 3874 | "example": "" 3875 | }, 3876 | "name": { 3877 | "type": "string", 3878 | "example": "" 3879 | }, 3880 | "password": { 3881 | "type": "string", 3882 | "example": "" 3883 | }, 3884 | "code": { 3885 | "type": "string", 3886 | "example": "" 3887 | } 3888 | }, 3889 | "xml": { 3890 | "name": "postAuthSignup" 3891 | } 3892 | }, 3893 | "postTeam": { 3894 | "type": "object", 3895 | "properties": { 3896 | "name": { 3897 | "type": "string", 3898 | "example": "newTeamName" 3899 | } 3900 | }, 3901 | "xml": { 3902 | "name": "postTeam" 3903 | } 3904 | }, 3905 | "patchTeam": { 3906 | "type": "object", 3907 | "properties": { 3908 | "name": { 3909 | "type": "string", 3910 | "example": "newTeamName" 3911 | } 3912 | }, 3913 | "xml": { 3914 | "name": "patchTeam" 3915 | } 3916 | }, 3917 | "patchTeamMembers": { 3918 | "type": "object", 3919 | "properties": { 3920 | "role": { 3921 | "type": "string", 3922 | "example": "member" 3923 | } 3924 | }, 3925 | "xml": { 3926 | "name": "patchTeamMembers" 3927 | } 3928 | }, 3929 | "postTeamInvites": { 3930 | "type": "array", 3931 | "items": { 3932 | "type": "object", 3933 | "properties": { 3934 | "email": { 3935 | "type": "string", 3936 | "example": "test@test.com" 3937 | }, 3938 | "role": { 3939 | "type": "string", 3940 | "example": "member" 3941 | } 3942 | } 3943 | }, 3944 | "xml": { 3945 | "name": "postTeamInvites" 3946 | } 3947 | }, 3948 | "postTeamAgents": { 3949 | "type": "object", 3950 | "properties": { 3951 | "name": { 3952 | "type": "string", 3953 | "example": "newAgentName" 3954 | }, 3955 | "language": { 3956 | "type": "string", 3957 | "example": "ko" 3958 | } 3959 | }, 3960 | "xml": { 3961 | "name": "postTeamAgents" 3962 | } 3963 | }, 3964 | "patchTeamAgents": { 3965 | "type": "object", 3966 | "properties": { 3967 | "name": { 3968 | "type": "string", 3969 | "example": "newAgentName" 3970 | }, 3971 | "language": { 3972 | "type": "string", 3973 | "example": "ko" 3974 | } 3975 | }, 3976 | "xml": { 3977 | "name": "patchTeamAgents" 3978 | } 3979 | }, 3980 | "postTeamWorkspaceIntegrations": { 3981 | "type": "object", 3982 | "properties": { 3983 | "workspaceType": { 3984 | "type": "string", 3985 | "example": "channeltalk" 3986 | }, 3987 | "workspaceId": { 3988 | "type": "string", 3989 | "example": "123456" 3990 | }, 3991 | "accessToken": { 3992 | "type": "string", 3993 | "example": "651xx3f16d1a110a3c11" 3994 | }, 3995 | "accessKey": { 3996 | "type": "string", 3997 | "example": "123123" 3998 | }, 3999 | "accessSecret": { 4000 | "type": "string", 4001 | "example": "7d607xxxxxxxxxxxxxxxxxxxx" 4002 | } 4003 | }, 4004 | "xml": { 4005 | "name": "postTeamWorkspaceIntegrations" 4006 | } 4007 | }, 4008 | "postMeTeamInvite": { 4009 | "type": "object", 4010 | "properties": { 4011 | "code": { 4012 | "type": "string", 4013 | "example": "" 4014 | } 4015 | }, 4016 | "xml": { 4017 | "name": "postMeTeamInvite" 4018 | } 4019 | }, 4020 | "deleteAgentKnowledges": { 4021 | "type": "object", 4022 | "properties": { 4023 | "documentIds": { 4024 | "type": "array", 4025 | "example": [ 4026 | "123456" 4027 | ], 4028 | "items": { 4029 | "type": "string" 4030 | } 4031 | }, 4032 | "adviceIds": { 4033 | "type": "array", 4034 | "example": [ 4035 | "123456" 4036 | ], 4037 | "items": { 4038 | "type": "string" 4039 | } 4040 | } 4041 | }, 4042 | "xml": { 4043 | "name": "deleteAgentKnowledges" 4044 | } 4045 | }, 4046 | "postAgentDocumentsUrl": { 4047 | "type": "object", 4048 | "properties": { 4049 | "documentUrls": { 4050 | "type": "array", 4051 | "example": [ 4052 | "https://examples.com" 4053 | ], 4054 | "items": { 4055 | "type": "string" 4056 | } 4057 | }, 4058 | "bucketIds": { 4059 | "type": "array", 4060 | "example": [ 4061 | "123456" 4062 | ], 4063 | "items": { 4064 | "type": "string" 4065 | } 4066 | } 4067 | }, 4068 | "xml": { 4069 | "name": "postAgentDocumentsUrl" 4070 | } 4071 | }, 4072 | "postAgentDocumentsFile": { 4073 | "type": "object", 4074 | "properties": { 4075 | "bucketIds": { 4076 | "type": "array", 4077 | "example": [ 4078 | "123456" 4079 | ], 4080 | "items": { 4081 | "type": "string" 4082 | } 4083 | } 4084 | }, 4085 | "xml": { 4086 | "name": "postAgentDocumentsFile" 4087 | } 4088 | }, 4089 | "postAgentBuckets": { 4090 | "type": "object", 4091 | "properties": { 4092 | "type": { 4093 | "type": "string", 4094 | "example": "default" 4095 | }, 4096 | "name": { 4097 | "type": "string", 4098 | "example": "newBucketName" 4099 | } 4100 | }, 4101 | "xml": { 4102 | "name": "postAgentBuckets" 4103 | } 4104 | }, 4105 | "putAgentBuckets": { 4106 | "type": "object", 4107 | "properties": { 4108 | "create": { 4109 | "type": "array", 4110 | "items": { 4111 | "type": "object", 4112 | "properties": { 4113 | "type": { 4114 | "type": "string", 4115 | "example": "default" 4116 | }, 4117 | "name": { 4118 | "type": "string", 4119 | "example": "newBucketName" 4120 | } 4121 | } 4122 | } 4123 | }, 4124 | "update": { 4125 | "type": "array", 4126 | "items": { 4127 | "type": "object", 4128 | "properties": { 4129 | "id": { 4130 | "type": "string", 4131 | "example": "123456" 4132 | }, 4133 | "type": { 4134 | "type": "string", 4135 | "example": "optional" 4136 | }, 4137 | "name": { 4138 | "type": "string", 4139 | "example": "newBucketName" 4140 | } 4141 | } 4142 | } 4143 | }, 4144 | "delete": { 4145 | "type": "array", 4146 | "items": { 4147 | "type": "object", 4148 | "properties": { 4149 | "id": { 4150 | "type": "string", 4151 | "example": "123456" 4152 | } 4153 | } 4154 | } 4155 | } 4156 | }, 4157 | "xml": { 4158 | "name": "putAgentBuckets" 4159 | } 4160 | }, 4161 | "patchBucket": { 4162 | "type": "object", 4163 | "properties": { 4164 | "type": { 4165 | "type": "string", 4166 | "example": "optional" 4167 | }, 4168 | "name": { 4169 | "type": "string", 4170 | "example": "newBucketName" 4171 | } 4172 | }, 4173 | "xml": { 4174 | "name": "patchBucket" 4175 | } 4176 | }, 4177 | "postThreadReply": { 4178 | "type": "object", 4179 | "properties": { 4180 | "question": { 4181 | "type": "string", 4182 | "example": "질문 텍스트" 4183 | } 4184 | }, 4185 | "xml": { 4186 | "name": "postThreadReply" 4187 | } 4188 | } 4189 | }, 4190 | "securitySchemes": { 4191 | "bearerAuth": { 4192 | "type": "http", 4193 | "scheme": "bearer", 4194 | "bearerFormat": "JWT" 4195 | }, 4196 | "ApiKeyAuth": { 4197 | "type": "apiKey", 4198 | "in": "header", 4199 | "name": "X-Storm-Token" 4200 | } 4201 | } 4202 | } 4203 | } -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 4 | ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" 5 | cd "$ROOT_DIR" 6 | 7 | echo "Current directory: $(pwd)" 1>&2 8 | ls -la 1>&2 9 | 10 | # 아래에 Storm API KEY를 입력하세요. 11 | export STORM_API_KEY='' 12 | 13 | # ★ 'uv run' 대신 'python -m' 사용: 14 | uv run -m storm_mcp_server.main 15 | -------------------------------------------------------------------------------- /storm_mcp_server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/storm_mcp_server/__init__.py -------------------------------------------------------------------------------- /storm_mcp_server/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/storm_mcp_server/core/__init__.py -------------------------------------------------------------------------------- /storm_mcp_server/core/file_manager.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import List 3 | import os 4 | import mimetypes 5 | import asyncio 6 | import base64 7 | 8 | 9 | class FileSystemManager: 10 | def __init__(self, base_path: str | Path): 11 | self.base_path = Path(base_path).resolve() 12 | if not self.base_path.exists(): 13 | self.base_path.mkdir(parents=True) 14 | 15 | def _validate_path(self, path: str | Path) -> Path: 16 | """주어진 경로가 base_path 내에 있는지 확인""" 17 | full_path = (self.base_path / path).resolve() 18 | if not str(full_path).startswith(str(self.base_path)): 19 | raise ValueError("Invalid path: Access denied") 20 | return full_path 21 | 22 | async def read_file(self, path: str) -> tuple[str, str]: 23 | """파일 읽기 (텍스트 파일 기준)""" 24 | full_path = self._validate_path(path) 25 | if not full_path.is_file(): 26 | raise FileNotFoundError(f"File not found: {path}") 27 | 28 | mime_type, _ = mimetypes.guess_type(str(full_path)) 29 | # 텍스트 파일(UTF-8) 가정 30 | content = await asyncio.to_thread(full_path.read_text) 31 | return content, mime_type or "text/plain" 32 | 33 | async def list_directory(self, path: str = "") -> List[dict]: 34 | """디렉토리 내용 나열""" 35 | full_path = self._validate_path(path) 36 | if not full_path.is_dir(): 37 | raise NotADirectoryError(f"Not a directory: {path}") 38 | 39 | items = [] 40 | for item in full_path.iterdir(): 41 | rel_path = str(item.relative_to(self.base_path)) 42 | items.append( 43 | { 44 | "name": item.name, 45 | "path": rel_path, 46 | "type": "directory" if item.is_dir() else "file", 47 | "size": item.stat().st_size if item.is_file() else None, 48 | } 49 | ) 50 | return items 51 | 52 | async def search_files(self, pattern: str) -> List[dict]: 53 | """파일 검색""" 54 | results = [] 55 | async for path in self._walk_async(self.base_path): 56 | if pattern.lower() in path.name.lower(): 57 | rel_path = str(path.relative_to(self.base_path)) 58 | results.append( 59 | { 60 | "name": path.name, 61 | "path": rel_path, 62 | "type": "directory" if path.is_dir() else "file", 63 | } 64 | ) 65 | return results 66 | 67 | async def _walk_async(self, path: Path): 68 | """비동기 파일 시스템 탐색""" 69 | dirs = [] 70 | files = [] 71 | async for entry in asyncio.to_thread(os.scandir, str(path)): 72 | if entry.is_dir(): 73 | dirs.append(entry) 74 | else: 75 | files.append(entry) 76 | 77 | for entry in files: 78 | yield Path(entry.path) 79 | 80 | for entry in dirs: 81 | async for x in self._walk_async(Path(entry.path)): 82 | yield x 83 | 84 | # ------------------------------------------------------------------------ 85 | # 새로 추가: 파일 업로드 로직 (Base64 컨텐츠 받기) 86 | # ------------------------------------------------------------------------ 87 | async def upload_file(self, path: str, b64_content: str) -> None: 88 | """ 89 | fileContent(Base64) 를 디코딩해서 로컬 파일로 저장. 90 | path: 저장될 파일 경로 (base_path 하위) 91 | b64_content: base64로 인코딩된 바이너리(또는 텍스트) 내용 92 | """ 93 | full_path = self._validate_path(path) 94 | 95 | # 디렉토리가 아닌, 상위 디렉토리가 존재하는지 확인 96 | parent_dir = full_path.parent 97 | if not parent_dir.exists(): 98 | parent_dir.mkdir(parents=True, exist_ok=True) 99 | 100 | # Base64 디코딩 101 | raw_data = base64.b64decode(b64_content) 102 | 103 | # 바이너리 쓰기 104 | # (만약 텍스트 파일만 취급한다면 `write_text`로 바꿔도 됨) 105 | await asyncio.to_thread(full_path.write_bytes, raw_data) 106 | -------------------------------------------------------------------------------- /storm_mcp_server/core/internal_api.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import requests 4 | from typing import Any, Dict, List 5 | 6 | 7 | def call_internal_api( 8 | method: str, 9 | endpoint: str, 10 | base_url: str = "https://live-stargate.sionic.im", 11 | params: Dict[str, Any] = None, 12 | data: Dict[str, Any] = None, 13 | files: Dict[str, Any] = None, 14 | ) -> Dict[str, Any]: 15 | storm_api_key = os.getenv("STORM_API_KEY") 16 | url = f"{base_url}{endpoint}" 17 | headers = {"Content-Type": "application/json", "storm-api-key": storm_api_key} 18 | 19 | if method.upper() == "GET": 20 | resp = requests.get(url, headers=headers, params=params, timeout=30) 21 | elif method.upper() == "POST": 22 | if files: 23 | # 멀티파트 24 | resp = requests.post( 25 | url, headers=headers, data=data, files=files, timeout=60 26 | ) 27 | else: 28 | resp = requests.post( 29 | url, headers=headers, json=data, params=params, timeout=30 30 | ) 31 | elif method.upper() == "DELETE": 32 | resp = requests.delete(url, headers=headers, params=params, timeout=30) 33 | else: 34 | raise ValueError(f"Unsupported HTTP method: {method}") 35 | 36 | if resp.status_code >= 400: 37 | raise Exception(f"API error: {resp.status_code} - {resp.text}") 38 | 39 | # text/plain 응답 대비 40 | try: 41 | return resp.json() 42 | except Exception: 43 | return {"status": "success", "data": resp.text} 44 | 45 | 46 | def call_chat_api( 47 | question: str, 48 | bucket_ids: List[str] = None, 49 | thread_id: str = None, 50 | webhook_url: str = None, 51 | base_url: str = "https://live-stargate.sionic.im", 52 | ) -> Dict[str, Any]: 53 | """ 54 | /api/v2/answer (non-stream) 호출 예시 55 | - header: storm-api-key: {api_key} 56 | - body: { "question": "...", "bucketIds": [...], "threadId": "...", "webhookUrl": "..." } 57 | """ 58 | url = f"{base_url}/api/v2/answer" 59 | storm_api_key = os.getenv("STORM_API_KEY") 60 | headers = { 61 | "Content-Type": "application/json", 62 | "storm-api-key": storm_api_key, 63 | } 64 | 65 | body = { 66 | "question": question, 67 | } 68 | if bucket_ids: 69 | body["bucketIds"] = bucket_ids 70 | if thread_id: 71 | body["threadId"] = thread_id 72 | if webhook_url: 73 | body["webhookUrl"] = webhook_url 74 | 75 | response = requests.post(url, headers=headers, json=body, timeout=30) 76 | if response.status_code >= 400: 77 | raise Exception(f"API error: {response.status_code} - {response.text}") 78 | 79 | return response.json() 80 | -------------------------------------------------------------------------------- /storm_mcp_server/main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from mcp.server.stdio import stdio_server 3 | from mcp.server import Server 4 | 5 | from storm_mcp_server.tools.tool_handlers import handle_list_tools, handle_call_tool 6 | 7 | # MCP 서버 인스턴스 생성 8 | server = Server("storm-platform") 9 | 10 | # -------------------------------------------------------------------------- 11 | # 1) MCP 쪽에서 'tools/list' 이벤트가 들어오면 12 | # handle_list_tools 함수를 호출하도록 등록 13 | # -------------------------------------------------------------------------- 14 | server.list_tools()(handle_list_tools) 15 | 16 | # -------------------------------------------------------------------------- 17 | # 2) MCP 쪽에서 'tool/call' 이벤트가 들어오면 18 | # handle_call_tool 함수를 호출하도록 등록 19 | # -------------------------------------------------------------------------- 20 | server.call_tool()(handle_call_tool) 21 | 22 | 23 | async def main(): 24 | async with stdio_server() as (read_stream, write_stream): 25 | await server.run( 26 | read_stream, write_stream, server.create_initialization_options() 27 | ) 28 | 29 | 30 | if __name__ == "__main__": 31 | print(f"Starting {__name__}") 32 | 33 | asyncio.run(main()) 34 | -------------------------------------------------------------------------------- /storm_mcp_server/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sionic-ai/serverless-rag-mcp-server/ed9392327a5dab9018304734cd4bd0521b6dca80/storm_mcp_server/tools/__init__.py -------------------------------------------------------------------------------- /storm_mcp_server/tools/tool_definitions.py: -------------------------------------------------------------------------------- 1 | # https://sionic-storm-openapi.apidog.io/api-10613460 2 | 3 | TOOLS_DEFINITION = [ 4 | { 5 | "name": "send_nonstream_chat", 6 | "description": ( 7 | "/api/v2/answer (non-stream)로 POST 요청을 보내어 질문(question)에 대한 " 8 | "답변을 받아옵니다. (storm-api-key 헤더 사용)" 9 | ), 10 | "inputSchema": { 11 | "type": "object", 12 | "properties": { 13 | "api_key": { 14 | "type": "string", 15 | "description": "storm-api-key 헤더로 보낼 API 키", 16 | }, 17 | "question": {"type": "string", "description": "채팅 질문 텍스트"}, 18 | "bucketIds": { 19 | "type": "array", 20 | "items": {"type": "string"}, 21 | "description": "질문 대상 버킷 ID 리스트 (옵션)", 22 | }, 23 | "threadId": { 24 | "type": "string", 25 | "description": "채팅을 전송할 스레드 ID (옵션)", 26 | }, 27 | "webhookUrl": { 28 | "type": "string", 29 | "description": "결과를 받을 웹훅 URL (옵션)", 30 | }, 31 | }, 32 | "required": ["api_key", "question"], # 필수: api_key, question 33 | }, 34 | }, 35 | { 36 | "name": "list_agents", 37 | "description": ( 38 | "Bearer 토큰을 사용해 /api/v2/agents GET으로 호출, " 39 | "현재 로그인 유저(=해당 bearer) 기준의 에이전트 목록을 가져옵니다. " 40 | "코드에서 환경변수 BEARER_TOKEN을 사용하므로, 인자로 받을 필요는 없습니다." 41 | ), 42 | "inputSchema": { 43 | "type": "object", 44 | "properties": { 45 | # bearer_token을 굳이 넣지 않고, page/size만 옵션 46 | "page": { 47 | "type": "integer", 48 | "description": "페이지 번호 (옵션)", 49 | }, 50 | "size": { 51 | "type": "integer", 52 | "description": "페이지 크기 (옵션)", 53 | }, 54 | }, 55 | "required": [], # 모두 옵션 56 | }, 57 | }, 58 | { 59 | "name": "list_buckets", 60 | "description": ( 61 | "Bearer 토큰을 사용해 /api/v2/buckets GET으로 호출, 특정 에이전트에 등록된 버킷 목록을 조회합니다." 62 | " 코드상에서는 환경변수 BEARER_TOKEN을 사용하며, 인자로 agent_id만 꼭 필요합니다." 63 | ), 64 | "inputSchema": { 65 | "type": "object", 66 | "properties": { 67 | # bearer_token도 빼거나, 혹은 남겨두되 필수는 아님 68 | "agent_id": {"type": "string", "description": "조회할 에이전트 ID"}, 69 | "page": {"type": "integer", "description": "페이지 번호 (옵션)"}, 70 | "size": {"type": "integer", "description": "페이지 크기 (옵션)"}, 71 | }, 72 | "required": ["agent_id"], # agent_id만 필수 73 | }, 74 | }, 75 | { 76 | "name": "upload_document_by_file", 77 | "description": "파일을 /api/v2/documents/by-file 엔드포인트에 업로드", 78 | "inputSchema": { 79 | "type": "object", 80 | "properties": { 81 | "bucket_id": { 82 | "type": "string", 83 | "description": "학습된 문서를 저장할 버킷 ID", 84 | }, 85 | "file_path": { 86 | "type": "string", 87 | "description": "업로드할 로컬 파일 경로 (옵션)", 88 | }, 89 | "file_base64": { 90 | "type": "string", 91 | "description": "Base64 인코딩된 파일 데이터 (옵션)", 92 | }, 93 | "file_name": { 94 | "type": "string", 95 | "description": "file_base64를 사용하는 경우, 업로드될 실제 파일 이름 (예: foo.pdf)", 96 | }, 97 | "webhook_url": { 98 | "type": "string", 99 | "description": "결과를 받을 웹훅 URL (옵션)", 100 | }, 101 | }, 102 | "required": [ 103 | "bucket_id" 104 | ], # bucket_id는 반드시 필요, file_path 또는 file_base64는 둘 중 하나 이상 있어야 함 105 | }, 106 | }, 107 | ] 108 | -------------------------------------------------------------------------------- /storm_mcp_server/tools/tool_handlers.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import base64 3 | import json 4 | from io import BytesIO 5 | from typing import List, Dict, Any 6 | from mcp.types import Tool, TextContent 7 | 8 | from storm_mcp_server.core.internal_api import call_internal_api, call_chat_api 9 | from storm_mcp_server.tools.tool_definitions import TOOLS_DEFINITION 10 | 11 | 12 | async def handle_list_tools() -> List[Tool]: 13 | """ 14 | MCP에서 'tools/list' 이벤트가 오면, 15 | 우리가 보유한 툴(TOOLS_DEFINITION)을 반환. 16 | """ 17 | tool_objects: List[Tool] = [] 18 | for tdef in TOOLS_DEFINITION: 19 | tool_objects.append( 20 | Tool( 21 | name=tdef["name"], 22 | description=tdef["description"], 23 | inputSchema=tdef["inputSchema"], 24 | ) 25 | ) 26 | return tool_objects 27 | 28 | 29 | async def handle_call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]: 30 | """ 31 | MCP에서 'tool/call' 이벤트로 특정 툴(name)을 호출하면, 32 | 여기서 그 이름에 맞게 실제 비즈니스 로직(call_chat_api, call_internal_api 등)을 실행. 33 | 34 | 반환값은 List[TextContent] 형태여야 하며, MCP에 문자열 형태로 전달된다. 35 | """ 36 | try: 37 | if name == "send_nonstream_chat": 38 | # -------------------------------------------------------- 39 | # (1) /api/v2/answer (non-stream) - Storm API Key 기반 40 | # -------------------------------------------------------- 41 | question = arguments.get("question", "").strip() 42 | bucket_ids = arguments.get("bucketIds", None) 43 | thread_id = arguments.get("threadId", None) 44 | webhook_url = arguments.get("webhookUrl", None) 45 | 46 | if not question: 47 | raise ValueError("question is required") 48 | 49 | # 실제 호출 50 | response_data = await asyncio.to_thread( 51 | call_chat_api, 52 | question=question, 53 | bucket_ids=bucket_ids, 54 | thread_id=thread_id, 55 | webhook_url=webhook_url, 56 | ) 57 | result_text = json.dumps(response_data, ensure_ascii=False, indent=2) 58 | return [TextContent(type="text", text=result_text)] 59 | 60 | elif name == "list_agents": 61 | page = arguments.get("page", None) 62 | size = arguments.get("size", None) 63 | 64 | params = {} 65 | if page is not None: 66 | params["page"] = page 67 | if size is not None: 68 | params["size"] = size 69 | 70 | response_data = await asyncio.to_thread( 71 | call_internal_api, 72 | method="GET", 73 | endpoint="/api/v2/agents", 74 | params=params, 75 | ) 76 | result_text = json.dumps(response_data, ensure_ascii=False, indent=2) 77 | return [TextContent(type="text", text=result_text)] 78 | 79 | elif name == "list_buckets": 80 | # -------------------------------------------------------- 81 | # (3) /api/v2/buckets (GET) - Storm API Key 82 | # -------------------------------------------------------- 83 | agent_id = arguments.get("agent_id", "").strip() 84 | if not agent_id: 85 | raise ValueError("agent_id is required") 86 | 87 | page = arguments.get("page", None) 88 | size = arguments.get("size", None) 89 | 90 | params = {"agentId": agent_id} 91 | if page is not None: 92 | params["page"] = page 93 | if size is not None: 94 | params["size"] = size 95 | 96 | response_data = await asyncio.to_thread( 97 | call_internal_api, 98 | method="GET", 99 | endpoint="/api/v2/buckets", 100 | params=params, 101 | ) 102 | result_text = json.dumps(response_data, ensure_ascii=False, indent=2) 103 | return [TextContent(type="text", text=result_text)] 104 | 105 | elif name == "upload_document_by_file": 106 | # -------------------------------------------------------- 107 | 108 | # /api/v2/documents/by-file (POST) 109 | 110 | # - file_path (로컬 경로) 111 | 112 | # - file_base64 (Base64) 113 | 114 | # - file_name (Base64 시 파일명) 115 | 116 | # -------------------------------------------------------- 117 | 118 | bucket_id = arguments.get("bucket_id", "").strip() 119 | 120 | file_path = arguments.get("file_path", "").strip() 121 | 122 | file_base64 = arguments.get("file_base64", None) 123 | 124 | file_name = arguments.get("file_name", None) 125 | 126 | webhook_url = arguments.get("webhook_url", None) 127 | 128 | if not bucket_id: 129 | raise ValueError("bucket_id is required") 130 | 131 | # file_path, file_base64 둘 다 없으면 에러 132 | 133 | if not file_path and not file_base64: 134 | raise ValueError("Either file_path or file_base64 must be provided") 135 | 136 | data = {"bucketId": bucket_id} 137 | 138 | if webhook_url: 139 | data["webhookUrl"] = webhook_url 140 | 141 | # --------------------------- 142 | 143 | # 1) file_path 있는 경우 → 로컬 파일 열기 144 | 145 | # --------------------------- 146 | 147 | if file_path: 148 | # 로컬 파일 읽어 multipart 전송 149 | 150 | with open(file_path, "rb") as f: 151 | # MIME 타입은 일단 "application/octet-stream"으로 가정 152 | 153 | files = {"file": (file_path, f, "application/octet-stream")} 154 | 155 | response_data = await asyncio.to_thread( 156 | call_internal_api, 157 | method="POST", 158 | endpoint="/api/v2/documents/by-file", 159 | data=data, 160 | files=files, 161 | ) 162 | 163 | # --------------------------- 164 | 165 | # 2) file_base64 있는 경우 → 메모리에서 BytesIO 166 | 167 | # --------------------------- 168 | 169 | else: 170 | # file_name이 없으면 기본 이름 "uploaded_file" 171 | 172 | if not file_name: 173 | file_name = "uploaded_file" 174 | 175 | raw_data = base64.b64decode(file_base64) 176 | 177 | file_obj = BytesIO(raw_data) 178 | 179 | # 마찬가지로 MIME 타입은 "application/octet-stream" 기본 180 | 181 | files = {"file": (file_name, file_obj, "application/octet-stream")} 182 | 183 | response_data = await asyncio.to_thread( 184 | call_internal_api, 185 | method="POST", 186 | endpoint="/api/v2/documents/by-file", 187 | data=data, 188 | files=files, 189 | ) 190 | 191 | result_text = json.dumps(response_data, ensure_ascii=False, indent=2) 192 | 193 | return [TextContent(type="text", text=result_text)] 194 | 195 | else: 196 | raise ValueError(f"Tool '{name}' not found.") 197 | 198 | except Exception as e: 199 | # 에러 발생 시 MCP 쪽에 오류 메시지를 전달하기 위해 RuntimeError로 래핑 200 | raise RuntimeError(f"Tool call error: {str(e)}") from e 201 | -------------------------------------------------------------------------------- /storm_mcp_server/tools/tool_upload_file.py: -------------------------------------------------------------------------------- 1 | import mimetypes 2 | from mcp.server import Server 3 | from mcp.types import Resource, Tool, TextContent 4 | from typing import List, Dict 5 | 6 | from storm_mcp_server.core.file_manager import FileSystemManager 7 | 8 | 9 | class FileServer: 10 | def __init__(self, base_path): 11 | self.fs = FileSystemManager(base_path) 12 | self.server = Server("file-server") 13 | 14 | def setup_handlers(self): 15 | """MCP 핸들러 설정""" 16 | 17 | @self.server.list_resources() 18 | async def list_resources() -> List[Resource]: 19 | items = await self.fs.list_directory() 20 | return [ 21 | Resource( 22 | uri=f"file:///{item['path']}", 23 | name=item["name"], 24 | mimeType=( 25 | "inode/directory" 26 | if item["type"] == "directory" 27 | else mimetypes.guess_type(item["name"])[0] or "text/plain" 28 | ), 29 | description=f"{'Directory' if item['type'] == 'directory' else 'File'}: {item['path']}", 30 | ) 31 | for item in items 32 | ] 33 | 34 | @self.server.read_resource() 35 | async def read_resource(uri: str) -> str: 36 | path = uri.replace("file:///", "") 37 | content, _ = await self.fs.read_file(path) 38 | return content 39 | 40 | @self.server.list_tools() 41 | async def list_tools() -> List[Tool]: 42 | return [ 43 | Tool( 44 | name="upload_file", 45 | description="파일 업로드(Base64 인코딩된 컨텐츠)", 46 | inputSchema={ 47 | "type": "object", 48 | "properties": { 49 | "path": { 50 | "type": "string", 51 | "description": "업로드할 파일 경로(서버 내)", 52 | }, 53 | "fileContent": { 54 | "type": "string", 55 | "description": "Base64 인코딩된 파일 내용", 56 | }, 57 | }, 58 | "required": ["path", "fileContent"], 59 | }, 60 | ), 61 | Tool( 62 | name="search_files", 63 | description="파일 검색", 64 | inputSchema={ 65 | "type": "object", 66 | "properties": { 67 | "pattern": { 68 | "type": "string", 69 | "description": "검색할 키워드", 70 | } 71 | }, 72 | "required": ["pattern"], 73 | }, 74 | ), 75 | ] 76 | 77 | @self.server.call_tool() 78 | async def call_tool(name: str, arguments: Dict) -> List[TextContent]: 79 | if name == "upload_file": 80 | # 파일 업로드 81 | path = arguments["path"] 82 | b64_content = arguments["fileContent"] 83 | 84 | await self.fs.upload_file(path, b64_content) 85 | return [ 86 | TextContent(type="text", text=f"File uploaded successfully: {path}") 87 | ] 88 | 89 | elif name == "search_files": 90 | # 파일 검색 91 | pattern = arguments["pattern"] 92 | results = await self.fs.search_files(pattern) 93 | if not results: 94 | return [TextContent(type="text", text="No files found")] 95 | 96 | text_output = "\n".join(f"[{r['type']}] {r['path']}" for r in results) 97 | return [TextContent(type="text", text=text_output)] 98 | 99 | raise ValueError(f"Unknown tool: {name}") 100 | -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | requires-python = ">=3.12" 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.8.0" 16 | source = { registry = "https://pypi.org/simple" } 17 | dependencies = [ 18 | { name = "idna" }, 19 | { name = "sniffio" }, 20 | { name = "typing-extensions", marker = "python_full_version < '3.13'" }, 21 | ] 22 | sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } 23 | wheels = [ 24 | { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, 25 | ] 26 | 27 | [[package]] 28 | name = "certifi" 29 | version = "2025.1.31" 30 | source = { registry = "https://pypi.org/simple" } 31 | sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } 32 | wheels = [ 33 | { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, 34 | ] 35 | 36 | [[package]] 37 | name = "charset-normalizer" 38 | version = "3.4.1" 39 | source = { registry = "https://pypi.org/simple" } 40 | sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } 41 | wheels = [ 42 | { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, 43 | { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, 44 | { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, 45 | { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, 46 | { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, 47 | { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, 48 | { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, 49 | { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, 50 | { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, 51 | { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, 52 | { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, 53 | { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, 54 | { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, 55 | { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, 56 | { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, 57 | { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, 58 | { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, 59 | { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, 60 | { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, 61 | { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, 62 | { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, 63 | { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, 64 | { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, 65 | { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, 66 | { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, 67 | { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, 68 | { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, 69 | ] 70 | 71 | [[package]] 72 | name = "click" 73 | version = "8.1.8" 74 | source = { registry = "https://pypi.org/simple" } 75 | dependencies = [ 76 | { name = "colorama", marker = "sys_platform == 'win32'" }, 77 | ] 78 | sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } 79 | wheels = [ 80 | { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, 81 | ] 82 | 83 | [[package]] 84 | name = "colorama" 85 | version = "0.4.6" 86 | source = { registry = "https://pypi.org/simple" } 87 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } 88 | wheels = [ 89 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, 90 | ] 91 | 92 | [[package]] 93 | name = "fastapi" 94 | version = "0.115.11" 95 | source = { registry = "https://pypi.org/simple" } 96 | dependencies = [ 97 | { name = "pydantic" }, 98 | { name = "starlette" }, 99 | { name = "typing-extensions" }, 100 | ] 101 | sdist = { url = "https://files.pythonhosted.org/packages/b5/28/c5d26e5860df807241909a961a37d45e10533acef95fc368066c7dd186cd/fastapi-0.115.11.tar.gz", hash = "sha256:cc81f03f688678b92600a65a5e618b93592c65005db37157147204d8924bf94f", size = 294441 } 102 | wheels = [ 103 | { url = "https://files.pythonhosted.org/packages/b3/5d/4d8bbb94f0dbc22732350c06965e40740f4a92ca560e90bb566f4f73af41/fastapi-0.115.11-py3-none-any.whl", hash = "sha256:32e1541b7b74602e4ef4a0260ecaf3aadf9d4f19590bba3e1bf2ac4666aa2c64", size = 94926 }, 104 | ] 105 | 106 | [[package]] 107 | name = "h11" 108 | version = "0.14.0" 109 | source = { registry = "https://pypi.org/simple" } 110 | sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } 111 | wheels = [ 112 | { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, 113 | ] 114 | 115 | [[package]] 116 | name = "httpcore" 117 | version = "1.0.7" 118 | source = { registry = "https://pypi.org/simple" } 119 | dependencies = [ 120 | { name = "certifi" }, 121 | { name = "h11" }, 122 | ] 123 | sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } 124 | wheels = [ 125 | { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, 126 | ] 127 | 128 | [[package]] 129 | name = "httpx" 130 | version = "0.28.1" 131 | source = { registry = "https://pypi.org/simple" } 132 | dependencies = [ 133 | { name = "anyio" }, 134 | { name = "certifi" }, 135 | { name = "httpcore" }, 136 | { name = "idna" }, 137 | ] 138 | sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } 139 | wheels = [ 140 | { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, 141 | ] 142 | 143 | [[package]] 144 | name = "httpx-sse" 145 | version = "0.4.0" 146 | source = { registry = "https://pypi.org/simple" } 147 | sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } 148 | wheels = [ 149 | { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, 150 | ] 151 | 152 | [[package]] 153 | name = "idna" 154 | version = "3.10" 155 | source = { registry = "https://pypi.org/simple" } 156 | sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } 157 | wheels = [ 158 | { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, 159 | ] 160 | 161 | [[package]] 162 | name = "mcp" 163 | version = "1.3.0" 164 | source = { registry = "https://pypi.org/simple" } 165 | dependencies = [ 166 | { name = "anyio" }, 167 | { name = "httpx" }, 168 | { name = "httpx-sse" }, 169 | { name = "pydantic" }, 170 | { name = "pydantic-settings" }, 171 | { name = "sse-starlette" }, 172 | { name = "starlette" }, 173 | { name = "uvicorn" }, 174 | ] 175 | sdist = { url = "https://files.pythonhosted.org/packages/6b/b6/81e5f2490290351fc97bf46c24ff935128cb7d34d68e3987b522f26f7ada/mcp-1.3.0.tar.gz", hash = "sha256:f409ae4482ce9d53e7ac03f3f7808bcab735bdfc0fba937453782efb43882d45", size = 150235 } 176 | wheels = [ 177 | { url = "https://files.pythonhosted.org/packages/d0/d2/a9e87b506b2094f5aa9becc1af5178842701b27217fa43877353da2577e3/mcp-1.3.0-py3-none-any.whl", hash = "sha256:2829d67ce339a249f803f22eba5e90385eafcac45c94b00cab6cef7e8f217211", size = 70672 }, 178 | ] 179 | 180 | [[package]] 181 | name = "pydantic" 182 | version = "2.10.6" 183 | source = { registry = "https://pypi.org/simple" } 184 | dependencies = [ 185 | { name = "annotated-types" }, 186 | { name = "pydantic-core" }, 187 | { name = "typing-extensions" }, 188 | ] 189 | sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } 190 | wheels = [ 191 | { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, 192 | ] 193 | 194 | [[package]] 195 | name = "pydantic-core" 196 | version = "2.27.2" 197 | source = { registry = "https://pypi.org/simple" } 198 | dependencies = [ 199 | { name = "typing-extensions" }, 200 | ] 201 | sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } 202 | wheels = [ 203 | { 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 }, 204 | { 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 }, 205 | { 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 }, 206 | { 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 }, 207 | { 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 }, 208 | { 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 }, 209 | { 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 }, 210 | { 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 }, 211 | { 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 }, 212 | { 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 }, 213 | { 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 }, 214 | { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, 215 | { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, 216 | { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, 217 | { 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 }, 218 | { 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 }, 219 | { 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 }, 220 | { 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 }, 221 | { 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 }, 222 | { 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 }, 223 | { 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 }, 224 | { 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 }, 225 | { 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 }, 226 | { 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 }, 227 | { 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 }, 228 | { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, 229 | { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, 230 | { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, 231 | ] 232 | 233 | [[package]] 234 | name = "pydantic-settings" 235 | version = "2.8.1" 236 | source = { registry = "https://pypi.org/simple" } 237 | dependencies = [ 238 | { name = "pydantic" }, 239 | { name = "python-dotenv" }, 240 | ] 241 | sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550 } 242 | wheels = [ 243 | { url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839 }, 244 | ] 245 | 246 | [[package]] 247 | name = "python-dotenv" 248 | version = "1.0.1" 249 | source = { registry = "https://pypi.org/simple" } 250 | sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } 251 | wheels = [ 252 | { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, 253 | ] 254 | 255 | [[package]] 256 | name = "requests" 257 | version = "2.32.3" 258 | source = { registry = "https://pypi.org/simple" } 259 | dependencies = [ 260 | { name = "certifi" }, 261 | { name = "charset-normalizer" }, 262 | { name = "idna" }, 263 | { name = "urllib3" }, 264 | ] 265 | sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } 266 | wheels = [ 267 | { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, 268 | ] 269 | 270 | [[package]] 271 | name = "sniffio" 272 | version = "1.3.1" 273 | source = { registry = "https://pypi.org/simple" } 274 | sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } 275 | wheels = [ 276 | { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, 277 | ] 278 | 279 | [[package]] 280 | name = "sse-starlette" 281 | version = "2.2.1" 282 | source = { registry = "https://pypi.org/simple" } 283 | dependencies = [ 284 | { name = "anyio" }, 285 | { name = "starlette" }, 286 | ] 287 | sdist = { url = "https://files.pythonhosted.org/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419", size = 17376 } 288 | wheels = [ 289 | { url = "https://files.pythonhosted.org/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99", size = 10120 }, 290 | ] 291 | 292 | [[package]] 293 | name = "starlette" 294 | version = "0.46.1" 295 | source = { registry = "https://pypi.org/simple" } 296 | dependencies = [ 297 | { name = "anyio" }, 298 | ] 299 | sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 } 300 | wheels = [ 301 | { url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 }, 302 | ] 303 | 304 | [[package]] 305 | name = "storm-mcp-server" 306 | version = "0.1.0" 307 | source = { virtual = "." } 308 | dependencies = [ 309 | { name = "fastapi" }, 310 | { name = "mcp" }, 311 | { name = "requests" }, 312 | { name = "uvicorn" }, 313 | ] 314 | 315 | [package.metadata] 316 | requires-dist = [ 317 | { name = "fastapi", specifier = ">=0.115.11" }, 318 | { name = "mcp", specifier = ">=1.3.0" }, 319 | { name = "requests", specifier = ">=2.32.3" }, 320 | { name = "uvicorn", specifier = ">=0.34.0" }, 321 | ] 322 | 323 | [[package]] 324 | name = "typing-extensions" 325 | version = "4.12.2" 326 | source = { registry = "https://pypi.org/simple" } 327 | sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } 328 | wheels = [ 329 | { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, 330 | ] 331 | 332 | [[package]] 333 | name = "urllib3" 334 | version = "2.3.0" 335 | source = { registry = "https://pypi.org/simple" } 336 | sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } 337 | wheels = [ 338 | { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, 339 | ] 340 | 341 | [[package]] 342 | name = "uvicorn" 343 | version = "0.34.0" 344 | source = { registry = "https://pypi.org/simple" } 345 | dependencies = [ 346 | { name = "click" }, 347 | { name = "h11" }, 348 | ] 349 | sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } 350 | wheels = [ 351 | { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, 352 | ] 353 | --------------------------------------------------------------------------------