mcp-proxy-adapter 6.4.12__py3-none-any.whl → 6.4.14__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/core/app_factory.py +105 -32
- mcp_proxy_adapter/core/mtls_server.py +314 -0
- mcp_proxy_adapter/core/server_engine.py +1 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +1 -1
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/RECORD +10 -22
- mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +0 -9
- mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +0 -4
- mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +0 -4
- mcp_proxy_adapter/examples/examples/basic_framework/main.py +0 -52
- mcp_proxy_adapter/examples/examples/full_application/__init__.py +0 -13
- mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +0 -7
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +0 -92
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +0 -97
- mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +0 -7
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +0 -88
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +0 -81
- mcp_proxy_adapter/examples/examples/full_application/main.py +0 -61
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +0 -188
- {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/top_level.txt +0 -0
@@ -1,188 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Proxy Registration Endpoints
|
3
|
-
This module provides proxy registration endpoints for testing.
|
4
|
-
Author: Vasiliy Zdanovskiy
|
5
|
-
email: vasilyvz@gmail.com
|
6
|
-
"""
|
7
|
-
|
8
|
-
from fastapi import APIRouter, HTTPException
|
9
|
-
from pydantic import BaseModel
|
10
|
-
from typing import Dict, List, Optional
|
11
|
-
import time
|
12
|
-
import uuid
|
13
|
-
|
14
|
-
# In-memory registry for testing
|
15
|
-
_registry: Dict[str, Dict] = {}
|
16
|
-
router = APIRouter(prefix="/proxy", tags=["proxy"])
|
17
|
-
|
18
|
-
|
19
|
-
class ServerRegistration(BaseModel):
|
20
|
-
"""Server registration request model."""
|
21
|
-
|
22
|
-
server_id: str
|
23
|
-
server_url: str
|
24
|
-
server_name: str
|
25
|
-
description: Optional[str] = None
|
26
|
-
version: Optional[str] = "1.0.0"
|
27
|
-
capabilities: Optional[List[str]] = None
|
28
|
-
endpoints: Optional[Dict[str, str]] = None
|
29
|
-
auth_method: Optional[str] = "none"
|
30
|
-
security_enabled: Optional[bool] = False
|
31
|
-
|
32
|
-
|
33
|
-
class ServerUnregistration(BaseModel):
|
34
|
-
"""Server unregistration request model."""
|
35
|
-
|
36
|
-
server_key: str # Use server_key directly
|
37
|
-
|
38
|
-
|
39
|
-
class HeartbeatData(BaseModel):
|
40
|
-
"""Heartbeat data model."""
|
41
|
-
|
42
|
-
server_id: str
|
43
|
-
server_key: str
|
44
|
-
timestamp: Optional[int] = None
|
45
|
-
status: Optional[str] = "healthy"
|
46
|
-
|
47
|
-
|
48
|
-
class RegistrationResponse(BaseModel):
|
49
|
-
"""Registration response model."""
|
50
|
-
|
51
|
-
success: bool
|
52
|
-
server_key: str
|
53
|
-
message: str
|
54
|
-
copy_number: int
|
55
|
-
|
56
|
-
|
57
|
-
class DiscoveryResponse(BaseModel):
|
58
|
-
"""Discovery response model."""
|
59
|
-
|
60
|
-
success: bool
|
61
|
-
servers: List[Dict]
|
62
|
-
total: int
|
63
|
-
active: int
|
64
|
-
|
65
|
-
|
66
|
-
@router.post("/register", response_model=RegistrationResponse)
|
67
|
-
async def register_server(registration: ServerRegistration):
|
68
|
-
"""Register a server with the proxy."""
|
69
|
-
try:
|
70
|
-
# Generate unique server key
|
71
|
-
server_key = f"{registration.server_id}_{uuid.uuid4().hex[:8]}"
|
72
|
-
copy_number = 1
|
73
|
-
# Store server information
|
74
|
-
_registry[server_key] = {
|
75
|
-
"server_id": registration.server_id,
|
76
|
-
"server_url": registration.server_url,
|
77
|
-
"server_name": registration.server_name,
|
78
|
-
"description": registration.description,
|
79
|
-
"version": registration.version,
|
80
|
-
"capabilities": registration.capabilities or [],
|
81
|
-
"endpoints": registration.endpoints or {},
|
82
|
-
"auth_method": registration.auth_method,
|
83
|
-
"security_enabled": registration.security_enabled,
|
84
|
-
"registered_at": int(time.time()),
|
85
|
-
"last_heartbeat": int(time.time()),
|
86
|
-
"status": "active",
|
87
|
-
}
|
88
|
-
return RegistrationResponse(
|
89
|
-
success=True,
|
90
|
-
server_key=server_key,
|
91
|
-
message=f"Server {registration.server_name} registered successfully",
|
92
|
-
copy_number=copy_number,
|
93
|
-
)
|
94
|
-
except Exception as e:
|
95
|
-
raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}")
|
96
|
-
|
97
|
-
|
98
|
-
@router.post("/unregister")
|
99
|
-
async def unregister_server(unregistration: ServerUnregistration):
|
100
|
-
"""Unregister a server from the proxy."""
|
101
|
-
try:
|
102
|
-
# Check if server exists in registry
|
103
|
-
if unregistration.server_key not in _registry:
|
104
|
-
raise HTTPException(status_code=404, detail="Server not found")
|
105
|
-
# Remove from registry
|
106
|
-
del _registry[unregistration.server_key]
|
107
|
-
return {"success": True, "message": "Server unregistered successfully"}
|
108
|
-
except HTTPException:
|
109
|
-
raise
|
110
|
-
except Exception as e:
|
111
|
-
raise HTTPException(status_code=500, detail=f"Unregistration failed: {str(e)}")
|
112
|
-
|
113
|
-
|
114
|
-
@router.post("/heartbeat")
|
115
|
-
async def send_heartbeat(heartbeat: HeartbeatData):
|
116
|
-
"""Send heartbeat for a registered server."""
|
117
|
-
try:
|
118
|
-
if heartbeat.server_key not in _registry:
|
119
|
-
raise HTTPException(status_code=404, detail="Server not found")
|
120
|
-
# Update heartbeat information
|
121
|
-
_registry[heartbeat.server_key]["last_heartbeat"] = heartbeat.timestamp or int(
|
122
|
-
time.time()
|
123
|
-
)
|
124
|
-
_registry[heartbeat.server_key]["status"] = heartbeat.status
|
125
|
-
return {"success": True, "message": "Heartbeat received"}
|
126
|
-
except HTTPException:
|
127
|
-
raise
|
128
|
-
except Exception as e:
|
129
|
-
raise HTTPException(status_code=500, detail=f"Heartbeat failed: {str(e)}")
|
130
|
-
|
131
|
-
|
132
|
-
@router.get("/discover", response_model=DiscoveryResponse)
|
133
|
-
async def discover_servers():
|
134
|
-
"""Discover active servers."""
|
135
|
-
try:
|
136
|
-
current_time = int(time.time())
|
137
|
-
active_servers = []
|
138
|
-
for server_key, server in _registry.items():
|
139
|
-
# Consider server active if heartbeat was within last 5 minutes
|
140
|
-
if current_time - server["last_heartbeat"] < 300:
|
141
|
-
active_servers.append(
|
142
|
-
{
|
143
|
-
"server_key": server_key,
|
144
|
-
"server_id": server["server_id"],
|
145
|
-
"server_name": server["server_name"],
|
146
|
-
"server_url": server["server_url"],
|
147
|
-
"status": server["status"],
|
148
|
-
"last_heartbeat": server["last_heartbeat"],
|
149
|
-
}
|
150
|
-
)
|
151
|
-
return DiscoveryResponse(
|
152
|
-
success=True,
|
153
|
-
servers=active_servers,
|
154
|
-
total=len(_registry),
|
155
|
-
active=len(active_servers),
|
156
|
-
)
|
157
|
-
except Exception as e:
|
158
|
-
raise HTTPException(status_code=500, detail=f"Discovery failed: {str(e)}")
|
159
|
-
|
160
|
-
|
161
|
-
@router.get("/status")
|
162
|
-
async def get_proxy_status():
|
163
|
-
"""Get proxy status."""
|
164
|
-
try:
|
165
|
-
current_time = int(time.time())
|
166
|
-
active_count = sum(
|
167
|
-
1
|
168
|
-
for server in _registry.values()
|
169
|
-
if current_time - server["last_heartbeat"] < 300
|
170
|
-
)
|
171
|
-
return {
|
172
|
-
"success": True,
|
173
|
-
"total_registered": len(_registry),
|
174
|
-
"active_servers": active_count,
|
175
|
-
"inactive_servers": len(_registry) - active_count,
|
176
|
-
}
|
177
|
-
except Exception as e:
|
178
|
-
raise HTTPException(status_code=500, detail=f"Status check failed: {str(e)}")
|
179
|
-
|
180
|
-
|
181
|
-
@router.delete("/clear")
|
182
|
-
async def clear_registry():
|
183
|
-
"""Clear the registry (for testing)."""
|
184
|
-
try:
|
185
|
-
_registry.clear()
|
186
|
-
return {"success": True, "message": "Registry cleared"}
|
187
|
-
except Exception as e:
|
188
|
-
raise HTTPException(status_code=500, detail=f"Clear failed: {str(e)}")
|
File without changes
|
File without changes
|
File without changes
|