mcp-proxy-adapter 2.1.11__py3-none-any.whl → 2.1.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,75 +0,0 @@
1
- """
2
- Validator for checking the correspondence between docstrings and function signatures.
3
- """
4
- import inspect
5
- from typing import Dict, Any, Optional, Callable, List, Tuple, get_type_hints
6
- import docstring_parser
7
-
8
- class DocstringValidator:
9
- """
10
- Validator for checking the correspondence between docstrings and handler functions.
11
-
12
- This class verifies that function docstrings match their signatures,
13
- contain all necessary sections, and describe all parameters.
14
- """
15
-
16
- def validate(self, handler: Callable, command_name: str, metadata: Dict[str, Any]) -> Tuple[bool, List[str]]:
17
- """
18
- Validates the function's docstring against its formal parameters.
19
-
20
- Args:
21
- handler: Command handler function
22
- command_name: Command name
23
- metadata: Command metadata
24
-
25
- Returns:
26
- Tuple[bool, List[str]]: Validity flag and list of errors
27
- """
28
- errors = []
29
-
30
- # Get formal parameters of the function
31
- sig = inspect.signature(handler)
32
- formal_params = list(sig.parameters.keys())
33
-
34
- # Skip self parameter for methods
35
- if formal_params and formal_params[0] == 'self':
36
- formal_params = formal_params[1:]
37
-
38
- # Parse docstring
39
- docstring = handler.__doc__ or ""
40
- parsed_doc = docstring_parser.parse(docstring)
41
-
42
- # Check for function description
43
- if not parsed_doc.short_description and not parsed_doc.long_description:
44
- errors.append(f"Missing function description")
45
-
46
- # Get parameters from docstring
47
- doc_params = {param.arg_name: param for param in parsed_doc.params}
48
-
49
- # Check that all formal parameters are described in the docstring
50
- for param in formal_params:
51
- # Skip special parameters
52
- if param in ('params', 'kwargs'):
53
- continue
54
-
55
- if param not in doc_params:
56
- errors.append(f"Parameter '{param}' is not described in the function docstring")
57
-
58
- # Check for returns in docstring
59
- if not parsed_doc.returns and not any(t.type_name == 'Returns' for t in parsed_doc.meta):
60
- errors.append(f"Missing return value description in the function docstring")
61
-
62
- # Check for type annotations
63
- try:
64
- type_hints = get_type_hints(handler)
65
- for param in formal_params:
66
- # Skip special parameters
67
- if param in ('params', 'kwargs'):
68
- continue
69
-
70
- if param not in type_hints:
71
- errors.append(f"Missing type annotation for parameter '{param}' in function {command_name}")
72
- except Exception as e:
73
- errors.append(f"Error getting type hints: {str(e)}")
74
-
75
- return len(errors) == 0, errors
@@ -1,76 +0,0 @@
1
- """
2
- Validator for checking command metadata against function signatures.
3
- """
4
- import inspect
5
- from typing import Dict, Any, Optional, Callable, List, Tuple
6
-
7
- class MetadataValidator:
8
- """
9
- Validator for checking handler function metadata.
10
-
11
- This class verifies that command metadata matches function signatures,
12
- and all parameters are correctly described.
13
- """
14
-
15
- def validate(self, handler: Callable, command_name: str, metadata: Dict[str, Any]) -> Tuple[bool, List[str]]:
16
- """
17
- Checks if metadata matches function's formal parameters.
18
-
19
- Args:
20
- handler: Command handler function
21
- command_name: Command name
22
- metadata: Command metadata
23
-
24
- Returns:
25
- Tuple[bool, List[str]]: Validity flag and list of errors
26
- """
27
- errors = []
28
-
29
- # Check presence of main fields in metadata
30
- if not metadata.get('description'):
31
- errors.append(f"Missing description for command '{command_name}'")
32
-
33
- # Get function's formal parameters
34
- sig = inspect.signature(handler)
35
- formal_params = list(sig.parameters.keys())
36
-
37
- # Skip self parameter for methods
38
- if formal_params and formal_params[0] == 'self':
39
- formal_params = formal_params[1:]
40
-
41
- # Check presence of parameters in metadata
42
- if 'parameters' not in metadata or not isinstance(metadata['parameters'], dict):
43
- errors.append(f"Parameters are missing or incorrectly defined in metadata for command '{command_name}'")
44
- return False, errors
45
-
46
- meta_params = metadata['parameters']
47
-
48
- # Check that all formal parameters are in metadata
49
- for param in formal_params:
50
- # Skip special parameters
51
- if param in ('params', 'kwargs'):
52
- continue
53
-
54
- if param not in meta_params:
55
- errors.append(f"Parameter '{param}' is not described in metadata for command '{command_name}'")
56
- continue
57
-
58
- param_info = meta_params[param]
59
-
60
- # Check presence of required fields for parameter
61
- if not isinstance(param_info, dict):
62
- errors.append(f"Incorrect format for parameter '{param}' description in metadata for command '{command_name}'")
63
- continue
64
-
65
- if 'type' not in param_info:
66
- errors.append(f"Type is not specified for parameter '{param}' in metadata for command '{command_name}'")
67
-
68
- if 'description' not in param_info:
69
- errors.append(f"Description is not specified for parameter '{param}' in metadata for command '{command_name}'")
70
-
71
- # Check that there are no extra parameters in metadata
72
- for param in meta_params:
73
- if param not in formal_params and param not in ('params', 'kwargs'):
74
- errors.append(f"Extra parameter '{param}' in metadata for command '{command_name}'")
75
-
76
- return len(errors) == 0, errors
@@ -1,402 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mcp-proxy-adapter
3
- Version: 2.1.11
4
- Summary: Adapter for exposing Command Registry commands as tools for AI models via MCP Proxy.
5
- Home-page: https://github.com/vasilyvz/mcp-proxy-adapter
6
- Author: Vasiliy VZ
7
- Author-email: Vasiliy VZ <vasilyvz@example.com>
8
- License: MIT
9
- Project-URL: Homepage, https://github.com/vasilyvz/mcp-proxy-adapter
10
- Project-URL: Bug Tracker, https://github.com/vasilyvz/mcp-proxy-adapter/issues
11
- Project-URL: Documentation, https://github.com/vasilyvz/mcp-proxy-adapter/tree/main/docs
12
- Classifier: Development Status :: 4 - Beta
13
- Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Requires-Python: >=3.9, <4
21
- Description-Content-Type: text/markdown
22
- License-File: LICENSE
23
- Requires-Dist: fastapi<1.0.0,>=0.95.0
24
- Requires-Dist: pydantic>=2.0.0
25
- Requires-Dist: uvicorn<1.0.0,>=0.22.0
26
- Requires-Dist: docstring-parser<1.0.0,>=0.15
27
- Requires-Dist: typing-extensions<5.0.0,>=4.5.0
28
- Dynamic: author
29
- Dynamic: home-page
30
- Dynamic: license-file
31
- Dynamic: requires-python
32
-
33
- # MCP Proxy Adapter
34
-
35
- Adapter for integrating [Command Registry](docs/README.md) with MCP Proxy, allowing you to use commands as tools for AI models.
36
-
37
- ## Overview
38
-
39
- MCP Proxy Adapter transforms commands registered in the Command Registry into a format compatible with MCP Proxy. This enables:
40
-
41
- 1. Using existing commands as tools for AI models
42
- 2. Creating a hybrid REST/JSON-RPC API for command execution
43
- 3. Automatic generation of OpenAPI schemas optimized for MCP Proxy
44
- 4. Managing tool metadata for better AI system integration
45
-
46
- ## Installation
47
-
48
- ```bash
49
- pip install mcp-proxy-adapter
50
- ```
51
-
52
- ## Quick Start
53
-
54
- ```python
55
- from mcp_proxy_adapter import MCPProxyAdapter, CommandRegistry
56
- from fastapi import FastAPI
57
-
58
- # Create a command registry instance
59
- registry = CommandRegistry()
60
-
61
- # Register commands
62
- @registry.command
63
- def calculate_total(prices: list[float], discount: float = 0.0) -> float:
64
- """
65
- Calculates the total price with discount.
66
- Args:
67
- prices: List of item prices
68
- discount: Discount percentage (0-100)
69
- Returns:
70
- Total price with discount
71
- """
72
- subtotal = sum(prices)
73
- return subtotal * (1 - discount / 100)
74
-
75
- # Create FastAPI app
76
- app = FastAPI()
77
-
78
- # Create and configure MCP Proxy adapter
79
- adapter = MCPProxyAdapter(registry)
80
-
81
- # Register endpoints in FastAPI app
82
- adapter.register_endpoints(app)
83
-
84
- # Generate and save MCP Proxy config
85
- adapter.save_config_to_file("mcp_proxy_config.json")
86
- ```
87
-
88
- ## Supported Request Formats
89
-
90
- The adapter supports three request formats for command execution:
91
-
92
- ### 1. JSON-RPC format
93
-
94
- ```json
95
- {
96
- "jsonrpc": "2.0",
97
- "method": "command_name",
98
- "params": {
99
- "param1": "value1",
100
- "param2": "value2"
101
- },
102
- "id": 1
103
- }
104
- ```
105
-
106
- Example request to `/cmd` endpoint:
107
-
108
- ```bash
109
- curl -X POST -H "Content-Type: application/json" -d '{
110
- "jsonrpc": "2.0",
111
- "method": "calculate_total",
112
- "params": {
113
- "prices": [100, 200, 300],
114
- "discount": 10
115
- },
116
- "id": 1
117
- }' http://localhost:8000/cmd
118
- ```
119
-
120
- Response:
121
-
122
- ```json
123
- {
124
- "jsonrpc": "2.0",
125
- "result": 540.0,
126
- "id": 1
127
- }
128
- ```
129
-
130
- ### 2. MCP Proxy format
131
-
132
- ```json
133
- {
134
- "command": "command_name",
135
- "params": {
136
- "param1": "value1",
137
- "param2": "value2"
138
- }
139
- }
140
- ```
141
-
142
- Example request:
143
-
144
- ```bash
145
- curl -X POST -H "Content-Type: application/json" -d '{
146
- "command": "calculate_total",
147
- "params": {
148
- "prices": [100, 200, 300],
149
- "discount": 10
150
- }
151
- }' http://localhost:8000/cmd
152
- ```
153
-
154
- Response:
155
-
156
- ```json
157
- {
158
- "result": 540.0
159
- }
160
- ```
161
-
162
- ### 3. Params-only format
163
-
164
- ```json
165
- {
166
- "params": {
167
- "command": "command_name",
168
- "param1": "value1",
169
- "param2": "value2"
170
- }
171
- }
172
- ```
173
-
174
- or
175
-
176
- ```json
177
- {
178
- "params": {
179
- "query": "command_name",
180
- "param1": "value1",
181
- "param2": "value2"
182
- }
183
- }
184
- ```
185
-
186
- Example request:
187
-
188
- ```bash
189
- curl -X POST -H "Content-Type: application/json" -d '{
190
- "params": {
191
- "command": "calculate_total",
192
- "prices": [100, 200, 300],
193
- "discount": 10
194
- }
195
- }' http://localhost:8000/cmd
196
- ```
197
-
198
- Response:
199
-
200
- ```json
201
- {
202
- "result": 540.0
203
- }
204
- ```
205
-
206
- ## Full Example: Integration with FastAPI
207
-
208
- ```python
209
- import logging
210
- from fastapi import FastAPI, APIRouter
211
- from mcp_proxy_adapter import CommandRegistry, MCPProxyAdapter, configure_logger
212
-
213
- # Configure logging
214
- logging.basicConfig(level=logging.INFO)
215
- project_logger = logging.getLogger("my_project")
216
-
217
- # Create FastAPI app
218
- app = FastAPI(title="My API with MCP Proxy Integration")
219
-
220
- # Create existing API router
221
- router = APIRouter()
222
-
223
- @router.get("/items")
224
- async def get_items():
225
- """Returns a list of items."""
226
- return [
227
- {"id": 1, "name": "Smartphone X", "price": 999.99},
228
- {"id": 2, "name": "Laptop Y", "price": 1499.99},
229
- ]
230
-
231
- app.include_router(router)
232
-
233
- # Register commands
234
- registry = CommandRegistry()
235
-
236
- @registry.command
237
- def get_discounted_price(price: float, discount: float = 0.0) -> float:
238
- """
239
- Returns the price after applying a discount.
240
- """
241
- return price * (1 - discount / 100)
242
-
243
- # Create and register MCP Proxy adapter
244
- adapter = MCPProxyAdapter(registry)
245
- adapter.register_endpoints(app)
246
-
247
- # Save MCP Proxy config
248
- adapter.save_config_to_file("mcp_proxy_config.json")
249
- ```
250
-
251
- ## Features
252
- - Universal JSON-RPC endpoint for command execution
253
- - Automatic OpenAPI schema generation and optimization for MCP Proxy
254
- - Tool metadata for AI models
255
- - Customizable endpoints and logging
256
- - Full test coverage and examples
257
-
258
- ## License
259
- MIT
260
-
261
- ## Documentation
262
- See [docs/](docs/) for detailed guides, architecture, and examples.
263
-
264
- ## 📦 Примеры (examples/)
265
-
266
- - `help_usage.py` — базовое использование help-команды
267
- - `help_best_practices.py` — best practices для help
268
- - `project_structure_example.py` — структура проекта с MCPProxyAdapter
269
- - `docstring_and_schema_example.py` — как документировать команды для схемы
270
- - `testing_example.py` — как тестировать команды и интеграцию
271
- - `extension_example.py` — как расширять и кастомизировать команды и help
272
-
273
- ## ✅ Чеклист для добавления новой команды
274
-
275
- 1. **Реализовать функцию-команду** с подробным docstring (EN)
276
- 2. **Добавить описание параметров** (type, description, required)
277
- 3. **Добавить описание возврата** (docstring, тип)
278
- 4. **Зарегистрировать команду** в registry/dispatcher
279
- 5. **Добавить описание в get_commands_info** (использовать docstring)
280
- 6. **Покрыть тестами** (unit/integration, edge-cases, ошибки)
281
- 7. **Добавить пример использования** в examples/
282
- 8. **Проверить интеграцию с help** (и с параметром, и без)
283
- 9. **Проверить генерацию схемы/OpenAPI**
284
- 10. **Документировать в README.md** (EN/RU)
285
-
286
- ## 📦 Examples (EN)
287
-
288
- - `help_usage.py` — basic help command usage
289
- - `help_best_practices.py` — best practices for help
290
- - `project_structure_example.py` — project structure with MCPProxyAdapter
291
- - `docstring_and_schema_example.py` — how to document commands for schema
292
- - `testing_example.py` — how to test commands and integration
293
- - `extension_example.py` — how to extend/customize commands and help
294
-
295
- ## ✅ Checklist for adding a new command
296
-
297
- 1. **Implement the command function** with detailed docstring (EN)
298
- 2. **Describe parameters** (type, description, required)
299
- 3. **Describe return value** (docstring, type)
300
- 4. **Register the command** in registry/dispatcher
301
- 5. **Add description to get_commands_info** (use docstring)
302
- 6. **Cover with tests** (unit/integration, edge-cases, errors)
303
- 7. **Add usage example** to examples/
304
- 8. **Check help integration** (with/without param)
305
- 9. **Check schema/OpenAPI generation**
306
- 10. **Document in README.md** (EN/RU)
307
-
308
- ## ❓ FAQ
309
-
310
- ### Ошибка: got multiple values for argument 'command' при вызове команды help
311
-
312
- **Проблема:**
313
-
314
- Если в JSON-RPC запросе к endpoint `/cmd` используется команда `help` с параметром `command`, может возникнуть ошибка:
315
-
316
- ```
317
- TypeError: help_command() got multiple values for argument 'command'
318
- ```
319
-
320
- **Причина:**
321
-
322
- В Python, если метод `execute(self, command, **params)` получает параметр `command` и в `params` также есть ключ `command`, возникает конфликт имён.
323
-
324
- **Решение:**
325
-
326
- Переименуйте первый аргумент метода `execute` в классе `MockDispatcher` (и аналогичных) с `command` на `command_name`:
327
-
328
- ```python
329
- def execute(self, command_name, **params):
330
- if command_name not in self.commands:
331
- raise KeyError(f"Unknown command: {command_name}")
332
- return self.commands[command_name](**params)
333
- ```
334
-
335
- Это устранит конфликт и позволит корректно вызывать команду help с параметром `command` через JSON-RPC.
336
-
337
- ## 🚀 Deployment & Packaging FAQ
338
-
339
- ### Как собрать, проверить и опубликовать пакет (wheel/sdist) с примерами и документацией
340
-
341
- 1. **Перенесите каталоги `examples` и `docs` внутрь основного пакета** (например, `mcp_proxy_adapter/examples`, `mcp_proxy_adapter/docs`).
342
- 2. **Обновите `setup.py`:**
343
- - Укажите `include_package_data=True`.
344
- - В `package_data` добавьте:
345
- ```python
346
- package_data={
347
- 'mcp_proxy_adapter': ['examples/*.py', 'examples/*.json', 'docs/*.md', '../README.md'],
348
- },
349
- ```
350
- 3. **Обновите `MANIFEST.in`:**
351
- - Убедитесь, что включены нужные файлы:
352
- ```
353
- include README.md
354
- include LICENSE
355
- include requirements.txt
356
- include pyproject.toml
357
- include code_index.yaml
358
- recursive-include mcp_proxy_adapter/examples *.py *.json
359
- recursive-include mcp_proxy_adapter/docs *.md
360
- ```
361
- 4. **Соберите пакет:**
362
- ```bash
363
- rm -rf dist build mcp_proxy_adapter.egg-info
364
- python3 -m build
365
- ```
366
- 5. **Создайте новое виртуальное окружение и установите пакет:**
367
- ```bash
368
- python3 -m venv ../mcp_proxy_adapter_test_env
369
- source ../mcp_proxy_adapter_test_env/bin/activate
370
- pip install --upgrade pip
371
- pip install dist/mcp_proxy_adapter-*.whl
372
- ```
373
- 6. **Проверьте, что примеры и документация попали в пакет:**
374
- ```bash
375
- ls -l ../mcp_proxy_adapter_test_env/lib/python*/site-packages/mcp_proxy_adapter/examples
376
- ls -l ../mcp_proxy_adapter_test_env/lib/python*/site-packages/mcp_proxy_adapter/docs
377
- ```
378
- 7. **Запустите пример сервера:**
379
- ```bash
380
- python ../mcp_proxy_adapter_test_env/lib/python*/site-packages/mcp_proxy_adapter/examples/openapi_server.py
381
- ```
382
- 8. **Проверьте работоспособность через curl:**
383
- ```bash
384
- curl http://localhost:8000/openapi.json | jq .
385
- ```
386
- 9. **Публикация на PyPI:**
387
- - Проверьте, что у вас настроен `~/.pypirc` и установлен twine:
388
- ```bash
389
- pip install twine
390
- twine upload dist/*
391
- ```
392
-
393
- ### Типовые проблемы и решения
394
- - **Примеры или документация не попадают в пакет:**
395
- - Убедитесь, что они находятся внутри основного пакета и правильно указаны в `package_data` и `MANIFEST.in`.
396
- - **Каталог docs не виден в wheel:**
397
- - Проверьте расширения файлов и шаблоны в `package_data`/`MANIFEST.in`.
398
- - **Проверяйте установку только через wheel, а не через sdist!**
399
-
400
- **Best practice:**
401
- - Для публикации документации используйте GitHub и PyPI project page (README.md).
402
- - Для примеров — всегда размещайте их внутри пакета, если хотите распространять с wheel.
@@ -1,29 +0,0 @@
1
- mcp_proxy_adapter/__init__.py,sha256=_6D-TfANWp9zc550M5LUeGPvioFqG1bAl3tZj-gNmJU,463
2
- mcp_proxy_adapter/adapter.py,sha256=76dkVeDuqLsJ5AhuftzLlwy2M6yr_PfNbmNfo9dXVhc,28844
3
- mcp_proxy_adapter/models.py,sha256=acqVQBYAojHXeJ1MJyvpMyT6-J6aMxWuZMszn_-RsOU,2338
4
- mcp_proxy_adapter/registry.py,sha256=jgC4TKaPbMbAsoxvGp2ToaOE4drD-VfZug7WJbm4IW4,15853
5
- mcp_proxy_adapter/schema.py,sha256=HZM0TTQTSi8ha1TEeVevdCyGZOUPoT1soB7Nex0hV50,10947
6
- mcp_proxy_adapter/testing_utils.py,sha256=RWjQFNSUtVkeP0qNzp6_jrT6_tub3w_052DrRmvxVk0,4243
7
- mcp_proxy_adapter/analyzers/__init__.py,sha256=2rcYZDP-bXq078MQpxP32lAwYYyRhOwAQGBcefBfBzY,368
8
- mcp_proxy_adapter/analyzers/docstring_analyzer.py,sha256=T3FLJEo_uChShfiEKRl8GpVoHvh5HiudZkxnj4KixfA,7541
9
- mcp_proxy_adapter/analyzers/type_analyzer.py,sha256=6Wac7osKwF03waFSwQ8ZM0Wqn_zAP2D-I4WMEpR0hQM,5230
10
- mcp_proxy_adapter/dispatchers/__init__.py,sha256=FWgimgInGphIjCEnvA3-ZExiapUzYAVis2H9C5IWivU,365
11
- mcp_proxy_adapter/dispatchers/base_dispatcher.py,sha256=S5_Xri058jAmOWeit1tedB_GMZQ9RLcNcYabA83ZF6k,2288
12
- mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py,sha256=S98qSj0p3glfiPcRirqCZaoiD9PrVVM3t7Lrgd6S8kM,6461
13
- mcp_proxy_adapter/examples/analyze_config.py,sha256=vog7TNHDw5ZoYhQLbAvZvEoufmQwH54KJzQBJrSq5w4,4283
14
- mcp_proxy_adapter/examples/basic_integration.py,sha256=w_oA777YiQt36gzI113KPQ6k45caXbMCqW9hD8sy8zo,4657
15
- mcp_proxy_adapter/examples/docstring_and_schema_example.py,sha256=c96L4KF_7yWzffmvd4hyeQuXSdYyYkv7Uvuy0QxgMcQ,1929
16
- mcp_proxy_adapter/examples/extension_example.py,sha256=vnatnFdNTapMpPcQ79Ugitk92ZiUfpLTs7Dvsodf1og,2277
17
- mcp_proxy_adapter/examples/help_best_practices.py,sha256=Bit9Ywl9vGvM_kuV8DJ6pIDK4mY4mF2Gia9rLc56RpI,2646
18
- mcp_proxy_adapter/examples/help_usage.py,sha256=9-65TyECtQYqPJLG3tlOWctI1zoCh6dEewh_i8mCdus,2577
19
- mcp_proxy_adapter/examples/mcp_proxy_client.py,sha256=z4IzFlGigVTQSb8TpcrQ_a0migsmC58LnNwc8wZmTfw,3811
20
- mcp_proxy_adapter/examples/openapi_server.py,sha256=KjUkXnGMnCxiRd71b1NFoHf40y9REXFqnmaxAgK4FB8,13229
21
- mcp_proxy_adapter/examples/project_structure_example.py,sha256=sswTo6FZb1F5juHa0FYG3cgvrh3wfgGfJu2bBy5tCm4,1460
22
- mcp_proxy_adapter/examples/testing_example.py,sha256=AB13c4C1bjs1145O-yriwyreeVXtMOlQLzs2BCGmprk,1719
23
- mcp_proxy_adapter/validators/docstring_validator.py,sha256=Onpq2iNJ1qF4ejkJJIlBkLROuSNIVALHVmXIgkCpaFI,2934
24
- mcp_proxy_adapter/validators/metadata_validator.py,sha256=uCrn38-VYYn89l6f5CC_GoTAHAweaOW2Z6Esro1rtGw,3155
25
- mcp_proxy_adapter-2.1.11.dist-info/licenses/LICENSE,sha256=OkApFEwdgMCt_mbvUI-eIwKMSTe38K3XnU2DT5ub-wI,1072
26
- mcp_proxy_adapter-2.1.11.dist-info/METADATA,sha256=2Z-WGz0AwAtHoUkUDhvQ1B_3enFmOj7epWGpm4C7UZo,12579
27
- mcp_proxy_adapter-2.1.11.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
28
- mcp_proxy_adapter-2.1.11.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
29
- mcp_proxy_adapter-2.1.11.dist-info/RECORD,,