Skip to content

Commit 372b2e6

Browse files
committed
fix(vefaas): fix mcp mount a2a
1 parent a4da6cc commit 372b2e6

File tree

6 files changed

+119
-210
lines changed

6 files changed

+119
-210
lines changed

veadk/cli/main.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,36 +118,13 @@ def init():
118118
print("Invalid deploy mode, set default to A2A Server")
119119
deploy_mode = deploy_mode_options["1"]
120120

121-
# Sub-choice for A2A/MCP Server
122-
server_type = None
123-
if deploy_mode == deploy_mode_options["1"]: # A2A/MCP Server
124-
server_type_options = {
125-
"1": "A2A Server",
126-
"2": "MCP Server",
127-
}
128-
129-
server_type_choice = Prompt.ask(
130-
"""Choose server type:
131-
1. A2A Server
132-
2. MCP Server
133-
""",
134-
default="1",
135-
)
136-
137-
if server_type_choice in server_type_options:
138-
server_type = server_type_options[server_type_choice]
139-
else:
140-
print("Invalid server type, set default to A2A Server")
141-
server_type = server_type_options["1"]
142-
143121
setting_values = {
144122
"VEFAAS_APPLICATION_NAME": vefaas_application_name,
145123
"GATEWAY_NAME": gateway_name,
146124
"GATEWAY_SERVICE_NAME": gateway_service_name,
147125
"GATEWAY_UPSTREAM_NAME": gateway_upstream_name,
148126
"USE_STUDIO": deploy_mode == deploy_mode_options["2"],
149127
"USE_ADK_WEB": deploy_mode == deploy_mode_options["3"],
150-
"USE_MCP": server_type == "MCP Server" if server_type else False,
151128
}
152129

153130
shutil.copytree(template_dir, target_dir)

veadk/cli/services/vefaas/template/deploy.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import asyncio
1616
from pathlib import Path
1717

18+
1819
from veadk.cloud.cloud_agent_engine import CloudAgentEngine
1920
from fastmcp.client import Client
2021

@@ -27,7 +28,6 @@
2728
GATEWAY_UPSTREAMNAME = ""
2829
USE_STUDIO = False
2930
USE_ADK_WEB = False
30-
USE_MCP = False
3131

3232

3333
async def main():
@@ -40,42 +40,42 @@ async def main():
4040
gateway_upstream_name=GATEWAY_UPSTREAMNAME,
4141
use_studio=USE_STUDIO,
4242
use_adk_web=USE_ADK_WEB,
43-
use_mcp=USE_MCP,
4443
)
45-
44+
query_example = "How is the weather like in Beijing?"
4645
if not USE_STUDIO and (not USE_ADK_WEB):
47-
if not USE_MCP:
48-
response_message = await cloud_app.message_send(
49-
"How is the weather like in Beijing?", SESSION_ID, USER_ID
50-
)
51-
print(f"VeFaaS application ID: {cloud_app.vefaas_application_id}")
52-
print(f"Message ID: {response_message.messageId}")
53-
print(
54-
f"Response from {cloud_app.vefaas_endpoint}: {response_message.parts[0].root.text}"
55-
)
56-
else:
57-
# cloud_app = CloudApp(vefaas_application_name=VEFAAS_APPLICATION_NAME)
58-
endpoint = cloud_app._get_vefaas_endpoint()
59-
print(f"endpoint:{endpoint}")
60-
# Connect to MCP server
61-
client = Client(f"{endpoint}/mcp")
46+
print("### A2A example ###")
47+
response_message = await cloud_app.message_send(
48+
query_example, SESSION_ID, USER_ID
49+
)
50+
print(f"VeFaaS application ID: {cloud_app.vefaas_application_id}")
51+
print(f"Message ID: {response_message.messageId}")
52+
print(
53+
f"Response from {cloud_app.vefaas_endpoint}: {response_message.parts[0].root.text}"
54+
)
55+
56+
print("### MCP example ###")
57+
# cloud_app = CloudApp(vefaas_application_name=VEFAAS_APPLICATION_NAME)
58+
endpoint = cloud_app._get_vefaas_endpoint()
59+
print(f"endpoint:{endpoint}")
60+
# Connect to MCP server
61+
client = Client(f"{endpoint}/mcp")
6262

63-
async with client:
64-
# List available tools
65-
tools = await client.list_tools()
66-
print(f"tool_0: {tools[0].__dict__}\n")
63+
async with client:
64+
# List available tools
65+
tools = await client.list_tools()
66+
print(f"tool_0: {tools[0].__dict__}\n")
6767

68-
# Call run_agent tool, pass user input and session information
69-
res = await client.call_tool(
70-
"run_agent",
71-
{
72-
"user_input": "How is the weather like in Beijing?",
73-
"session_id": SESSION_ID,
74-
"user_id": USER_ID,
75-
},
76-
)
77-
print(f"VeFaaS application ID: {cloud_app.vefaas_application_id}")
78-
print(f"Response from {cloud_app.vefaas_endpoint}: {res}")
68+
# Call run_agent tool, pass user input and session information
69+
res = await client.call_tool(
70+
"run_agent",
71+
{
72+
"user_input": query_example,
73+
"session_id": SESSION_ID,
74+
"user_id": USER_ID,
75+
},
76+
)
77+
print(f"VeFaaS application ID: {cloud_app.vefaas_application_id}")
78+
print(f"Response from {cloud_app.vefaas_endpoint}: {res}")
7979

8080
else:
8181
print(f"Web is running at: {cloud_app.vefaas_endpoint}")

veadk/cli/services/vefaas/template/src/app.py

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@
1313
# limitations under the License.
1414

1515
import os
16-
1716
from agent import agent, app_name, short_term_memory
1817
from veadk.a2a.ve_a2a_server import init_app
1918
from veadk.tracing.base_tracer import BaseTracer
2019
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer
20+
from veadk import Agent
21+
from veadk.memory.short_term_memory import ShortTermMemory
22+
from veadk.runner import Runner
23+
from contextlib import asynccontextmanager
24+
from fastmcp import FastMCP
25+
from fastapi import FastAPI
2126

2227

2328
# ==============================================================================
@@ -62,9 +67,85 @@
6267
# Tracer Config ================================================================
6368
# ==============================================================================
6469

65-
app = init_app(
66-
server_url="0.0.0.0", # Automatic identification is not supported yet.
70+
71+
# Create VeMCPServer class
72+
class VeMCPServer:
73+
def __init__(self, agent: Agent, app_name: str, short_term_memory: ShortTermMemory):
74+
self.agent = agent
75+
self.app_name = app_name
76+
self.short_term_memory = short_term_memory
77+
78+
self.runner = Runner(
79+
agent=self.agent,
80+
short_term_memory=self.short_term_memory,
81+
app_name=app_name,
82+
user_id="", # waiting for tool call to provide user_id
83+
)
84+
85+
def build(self) -> FastMCP:
86+
# Create MCP server
87+
mcp = FastMCP(name=self.app_name)
88+
89+
@mcp.tool
90+
async def run_agent(
91+
user_input: str,
92+
user_id: str = "unknown_user",
93+
session_id: str = "unknown_session",
94+
) -> str:
95+
"""
96+
Execute agent with user input and return final output
97+
Args:
98+
user_input: str, user_id: str = "unknown_user", session_id: str = "unknown_session"
99+
Returns:
100+
final_output: str
101+
"""
102+
# Set user_id for runner
103+
self.runner.user_id = user_id
104+
105+
# Running agent and get final output
106+
final_output = await self.runner.run(
107+
messages=user_input,
108+
session_id=session_id,
109+
)
110+
111+
return final_output
112+
113+
return mcp
114+
115+
116+
# Create A2A app
117+
a2a_app = init_app(
118+
server_url="0.0.0.0",
67119
app_name=app_name,
68120
agent=agent,
69121
short_term_memory=short_term_memory,
70122
)
123+
124+
# Create MCP server instance
125+
mcp_server = VeMCPServer(
126+
agent=agent,
127+
app_name=app_name,
128+
short_term_memory=short_term_memory,
129+
)
130+
mcp = mcp_server.build()
131+
132+
# Create MCP ASGI app
133+
mcp_app = mcp.http_app(path="/")
134+
135+
136+
# Combined lifespan management
137+
@asynccontextmanager
138+
async def combined_lifespan(app: FastAPI):
139+
async with mcp_app.lifespan(app):
140+
yield
141+
142+
143+
# Create main FastAPI app with combined lifespan
144+
app = FastAPI(title=a2a_app.title, version=a2a_app.version, lifespan=combined_lifespan)
145+
146+
# Mount A2A routes to main app
147+
for route in a2a_app.routes:
148+
app.routes.append(route)
149+
150+
# Mount MCP server at /mcp endpoint
151+
app.mount("/mcp", mcp_app)

veadk/cli/services/vefaas/template/src/app_mcp.py

Lines changed: 0 additions & 134 deletions
This file was deleted.

veadk/cli/services/vefaas/template/src/run.sh

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ python3 -m pip install fastmcp
4242

4343
USE_STUDIO=${USE_STUDIO:-False}
4444
USE_ADK_WEB=${USE_ADK_WEB:-False}
45-
USE_MCP=${USE_MCP:-False}
4645

4746
if [ "$USE_STUDIO" = "True" ]; then
4847
echo "USE_STUDIO is True, running veadk studio"
@@ -57,12 +56,8 @@ elif [ "$USE_STUDIO" = "False" ]; then
5756
cd ../
5857
exec python3 -m veadk.cli.main web --host "0.0.0.0"
5958
else
60-
if [ "$USE_MCP" = "True" ]; then
61-
echo "USE_MCP is True, running MCP server"
62-
exec python3 app_mcp.py --transport http --host $HOST --port $PORT --log-level "INFO"
63-
else
64-
echo "USE_MCP is False, running a2a server"
65-
exec python3 -m uvicorn app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT --loop asyncio
59+
echo "USE_ADK_WEB is False, running a2a server"
60+
exec python3 -m uvicorn app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT --loop asyncio
6661
fi
6762
fi
6863
else

0 commit comments

Comments
 (0)