Skip to content
This repository was archived by the owner on Oct 17, 2025. It is now read-only.

Commit c6f9475

Browse files
committed
/register api and mcp tool now works
1 parent 5fae952 commit c6f9475

File tree

3 files changed

+248
-69
lines changed

3 files changed

+248
-69
lines changed

registry/main.py

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,19 +1038,34 @@ async def register_service(
10381038
license_str: Annotated[str, Form(alias="license")] = "N/A",
10391039
username: Annotated[str, Depends(api_auth)] = None,
10401040
):
1041+
print(f"[DEBUG] register_service() called with parameters:")
1042+
print(f"[DEBUG] - name: {name}")
1043+
print(f"[DEBUG] - description: {description}")
1044+
print(f"[DEBUG] - path: {path}")
1045+
print(f"[DEBUG] - proxy_pass_url: {proxy_pass_url}")
1046+
print(f"[DEBUG] - tags: {tags}")
1047+
print(f"[DEBUG] - num_tools: {num_tools}")
1048+
print(f"[DEBUG] - num_stars: {num_stars}")
1049+
print(f"[DEBUG] - is_python: {is_python}")
1050+
print(f"[DEBUG] - license_str: {license_str}")
1051+
print(f"[DEBUG] - username: {username}")
1052+
10411053
# Ensure path starts with a slash
10421054
if not path.startswith("/"):
10431055
path = "/" + path
1056+
print(f"[DEBUG] Path adjusted to start with slash: {path}")
10441057

10451058
# Check if path already exists
10461059
if path in REGISTERED_SERVERS:
1060+
print(f"[ERROR] Service registration failed: path '{path}' already exists")
10471061
return JSONResponse(
10481062
status_code=400,
10491063
content={"error": f"Service with path '{path}' already exists"},
10501064
)
10511065

10521066
# Process tags: split string, strip whitespace, filter empty
10531067
tag_list = [tag.strip() for tag in tags.split(",") if tag.strip()]
1068+
print(f"[DEBUG] Processed tags: {tag_list}")
10541069

10551070
# Create new server entry with all fields
10561071
server_entry = {
@@ -1065,61 +1080,79 @@ async def register_service(
10651080
"license": license_str,
10661081
"tool_list": [] # Initialize tool list
10671082
}
1083+
print(f"[DEBUG] Created server entry: {json.dumps(server_entry, indent=2)}")
10681084

10691085
# Save to individual file
1086+
print(f"[DEBUG] Attempting to save server data to file...")
10701087
success = save_server_to_file(server_entry)
10711088
if not success:
1089+
print(f"[ERROR] Failed to save server data to file")
10721090
return JSONResponse(
10731091
status_code=500, content={"error": "Failed to save server data"}
10741092
)
1093+
print(f"[DEBUG] Successfully saved server data to file")
10751094

10761095
# Add to in-memory registry and default to disabled
1096+
print(f"[DEBUG] Adding server to in-memory registry...")
10771097
REGISTERED_SERVERS[path] = server_entry
1098+
print(f"[DEBUG] Setting initial service state to disabled")
10781099
MOCK_SERVICE_STATE[path] = False
10791100
# Set initial health status for the new service (always start disabled)
1101+
print(f"[DEBUG] Setting initial health status to 'disabled'")
10801102
SERVER_HEALTH_STATUS[path] = "disabled" # Start disabled
10811103
SERVER_LAST_CHECK_TIME[path] = None # No check time yet
10821104
# Ensure num_tools is present in the in-memory dict immediately
10831105
if "num_tools" not in REGISTERED_SERVERS[path]:
1106+
print(f"[DEBUG] Adding missing num_tools field to in-memory registry")
10841107
REGISTERED_SERVERS[path]["num_tools"] = 0
10851108

10861109
# Regenerate Nginx config after successful registration
1110+
print(f"[DEBUG] Attempting to regenerate Nginx configuration...")
10871111
if not regenerate_nginx_config():
1088-
print("ERROR: Failed to update Nginx configuration after registration.")
1112+
print(f"[ERROR] Failed to update Nginx configuration after registration")
1113+
else:
1114+
print(f"[DEBUG] Successfully regenerated Nginx configuration")
10891115

1090-
print(f"New service registered: '{name}' at path '{path}' by user '{username}'")
1116+
print(f"[INFO] New service registered: '{name}' at path '{path}' by user '{username}'")
10911117

10921118
# --- Persist the updated state after registration --- START
10931119
try:
1120+
print(f"[DEBUG] Attempting to persist state to {STATE_FILE_PATH}...")
10941121
with open(STATE_FILE_PATH, "w") as f:
10951122
json.dump(MOCK_SERVICE_STATE, f, indent=2)
1096-
print(f"Persisted state to {STATE_FILE_PATH} after registration")
1123+
print(f"[DEBUG] Successfully persisted state to {STATE_FILE_PATH}")
10971124
except Exception as e:
1098-
print(f"ERROR: Failed to persist state to {STATE_FILE_PATH} after registration: {e}")
1125+
print(f"[ERROR] Failed to persist state to {STATE_FILE_PATH}: {str(e)}")
10991126
# --- Persist the updated state after registration --- END
11001127

11011128
# Broadcast the updated status after registration
1129+
print(f"[DEBUG] Creating task to broadcast health status...")
11021130
asyncio.create_task(broadcast_health_status())
11031131

1132+
print(f"[DEBUG] Registration complete, returning success response")
11041133
return JSONResponse(
11051134
status_code=201,
11061135
content={
11071136
"message": "Service registered successfully",
11081137
"service": server_entry,
1109-
# Optional: Add a warning if config generation failed
1110-
# "warning": "Nginx configuration update failed, please check logs."
11111138
},
11121139
)
11131140

1114-
11151141
@app.get("/api/server_details/{service_path:path}")
11161142
async def get_server_details(
11171143
service_path: str,
11181144
username: Annotated[str, Depends(api_auth)]
11191145
):
1146+
# Normalize the path to ensure it starts with '/'
11201147
if not service_path.startswith('/'):
11211148
service_path = '/' + service_path
11221149

1150+
# Special case: if path is 'all' or '/all', return details for all servers
1151+
if service_path == '/all':
1152+
# Return a dictionary of all registered servers
1153+
return REGISTERED_SERVERS
1154+
1155+
# Regular case: return details for a specific server
11231156
server_info = REGISTERED_SERVERS.get(service_path)
11241157
if not server_info:
11251158
raise HTTPException(status_code=404, detail="Service path not registered")
@@ -1137,6 +1170,34 @@ async def get_service_tools(
11371170
if not service_path.startswith('/'):
11381171
service_path = '/' + service_path
11391172

1173+
# Handle special case for '/all' to return tools from all servers
1174+
if service_path == '/all':
1175+
all_tools = []
1176+
all_servers_tools = {}
1177+
1178+
for path, server_info in REGISTERED_SERVERS.items():
1179+
tool_list = server_info.get("tool_list")
1180+
1181+
if tool_list is not None and isinstance(tool_list, list):
1182+
# Add server information to each tool
1183+
server_tools = []
1184+
for tool in tool_list:
1185+
# Create a copy of the tool with server info added
1186+
tool_with_server = dict(tool)
1187+
tool_with_server["server_path"] = path
1188+
tool_with_server["server_name"] = server_info.get("server_name", "Unknown")
1189+
server_tools.append(tool_with_server)
1190+
1191+
all_tools.extend(server_tools)
1192+
all_servers_tools[path] = server_tools
1193+
1194+
return {
1195+
"service_path": "all",
1196+
"tools": all_tools,
1197+
"servers": all_servers_tools
1198+
}
1199+
1200+
# Handle specific server case (existing logic)
11401201
server_info = REGISTERED_SERVERS.get(service_path)
11411202
if not server_info:
11421203
raise HTTPException(status_code=404, detail="Service path not registered")

servers/mcpgw/client.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Example MCP client for the mcpgw server.
33
44
This client connects to the mcpgw MCP server, lists its capabilities,
5-
and demonstrates calling the 'get_server_details' tool.
5+
and demonstrates calling the 'get_server_details' and 'register_service' tools.
66
77
Usage:
88
python client.py [--host HOSTNAME] [--port PORT] [--server-name SERVER_NAME]
@@ -55,14 +55,17 @@ async def run(server_url, args):
5555

5656
# --- Example: Call the get_server_details tool ---
5757
# Let's try to get details for the '/current_time' server (assuming it's registered)
58-
target_service_path = "/currenttime"
58+
target_service_path = "/all"
5959
print(f"\nCalling 'get_server_details' tool for service_path='{target_service_path}'")
6060

6161
try:
62-
# The 'get_server_details' tool expects parameters nested under 'params'
63-
tool_params = {"service_path": target_service_path, "username": args.username, "password": args.password}
62+
# Pass parameters directly to the get_server_details tool
6463
result = await session.call_tool(
65-
"get_server_details", arguments={"params": tool_params}
64+
"get_server_details", arguments={
65+
"service_path": target_service_path,
66+
"username": args.username,
67+
"password": args.password
68+
}
6669
)
6770

6871
# Display the results (which should be the JSON response from the registry)
@@ -84,6 +87,46 @@ async def run(server_url, args):
8487
print(f"Error calling 'get_server_details': {e}")
8588
# --- End Example ---
8689

90+
# --- Example: Call the register_service tool ---
91+
print("\nCalling 'register_service' tool with hardcoded parameters")
92+
93+
try:
94+
# Pass hardcoded parameters to the register_service tool
95+
result = await session.call_tool(
96+
"register_service", arguments={
97+
"server_name": "Example Service",
98+
"path": "/example-service",
99+
"proxy_pass_url": "http://localhost:9000",
100+
"description": "An example MCP service for demonstration purposes",
101+
"tags": ["example", "demo", "test"],
102+
"num_tools": 3,
103+
"num_stars": 5,
104+
"is_python": True,
105+
"license": "MIT",
106+
"username": args.username,
107+
"password": args.password
108+
}
109+
)
110+
111+
# Display the results
112+
print("=" * 50)
113+
print("Result for register_service:")
114+
print("=" * 50)
115+
# The result content is usually a list of MessagePart objects
116+
full_response_text = "".join(part.text for part in result.content if hasattr(part, 'text'))
117+
try:
118+
# Attempt to parse and pretty-print if it's JSON
119+
parsed_json = json.loads(full_response_text)
120+
print(json.dumps(parsed_json, indent=2))
121+
except json.JSONDecodeError:
122+
# Otherwise, just print the raw text
123+
print(full_response_text)
124+
print("=" * 50)
125+
126+
except Exception as e:
127+
print(f"Error calling 'register_service': {e}")
128+
# --- End Example ---
129+
87130

88131
if __name__ == "__main__":
89132
# Set up command-line argument parsing

0 commit comments

Comments
 (0)