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.
- mcp_proxy_adapter/analyzers/__init__.py +1 -14
- mcp_proxy_adapter/dispatchers/__init__.py +1 -14
- mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +76 -40
- mcp_proxy_adapter/examples/basic_integration.py +2 -8
- mcp_proxy_adapter/examples/help_usage.py +10 -10
- mcp_proxy_adapter/examples/openapi_server.py +9 -8
- mcp_proxy_adapter-2.1.13.dist-info/METADATA +341 -0
- mcp_proxy_adapter-2.1.13.dist-info/RECORD +19 -0
- {mcp_proxy_adapter-2.1.11.dist-info → mcp_proxy_adapter-2.1.13.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter/__init__.py +0 -17
- mcp_proxy_adapter/adapter.py +0 -697
- mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
- mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
- mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
- mcp_proxy_adapter/models.py +0 -47
- mcp_proxy_adapter/registry.py +0 -439
- mcp_proxy_adapter/schema.py +0 -257
- mcp_proxy_adapter/validators/docstring_validator.py +0 -75
- mcp_proxy_adapter/validators/metadata_validator.py +0 -76
- mcp_proxy_adapter-2.1.11.dist-info/METADATA +0 -402
- mcp_proxy_adapter-2.1.11.dist-info/RECORD +0 -29
- {mcp_proxy_adapter-2.1.11.dist-info → mcp_proxy_adapter-2.1.13.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-2.1.11.dist-info → mcp_proxy_adapter-2.1.13.dist-info}/top_level.txt +0 -0
@@ -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,,
|
File without changes
|
File without changes
|