Skip to content

Commit 936c519

Browse files
peterjEItanyaCopilot
authored
pin down dependencies + fix mcp/agent template (#1429)
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io> Co-authored-by: Eitan Yarmush <eitan.yarmush@solo.io> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent d257bcf commit 936c519

File tree

6 files changed

+58
-26
lines changed

6 files changed

+58
-26
lines changed

go/core/cli/internal/agent/frameworks/adk/python/templates/pyproject.toml.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ version = "0.1"
44
description = "{{.Name}} agent"
55
readme = "README.md"
66
dependencies = [
7-
"google-adk>=1.8.0",
7+
"google-adk==1.25.1",
88
]
9+
10+
requires-python = ">=3.13"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.11
1+
3.12

go/core/cli/internal/mcp/frameworks/python/templates/Dockerfile.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Multi-stage build for {{.ProjectName}} MCP server using uv
2-
FROM python:3.11-slim AS builder
2+
FROM python:3.12-slim AS builder
33

44
# Install uv
55
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
@@ -26,7 +26,7 @@ COPY src/ ./src/
2626
COPY manifest.yaml ./
2727

2828
# Production stage
29-
FROM python:3.11-slim
29+
FROM python:3.12-slim
3030

3131
# Install uv in production
3232
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

go/core/cli/internal/mcp/frameworks/python/templates/pyproject.toml.tmpl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ description = "{{.ProjectName}} MCP server built with FastMCP"
1212
{name = "Unknown Author"}
1313
]{{end}}{{end}}
1414
readme = "README.md"
15-
requires-python = ">=3.10"
15+
requires-python = ">=3.12"
1616
dependencies = [
17-
"fastmcp>=0.2.0",
18-
"pydantic>=2.0.0",
19-
"pyyaml>=6.0",
20-
"python-dotenv>=1.0.0",
17+
"fastmcp==3.0.0",
18+
"pydantic==2.12.5",
19+
"pyyaml==6.0.3",
20+
"python-dotenv==1.2.1",
2121
]
2222

2323
[build-system]
@@ -32,12 +32,12 @@ packages = ["src"]
3232

3333
[tool.uv]
3434
dev-dependencies = [
35-
"pytest>=7.0.0",
36-
"pytest-asyncio>=0.21.0",
37-
"black>=22.0.0",
38-
"mypy>=1.0.0",
39-
"ruff>=0.1.0",
40-
"types-PyYAML>=6.0.0",
35+
"pytest==9.0.2",
36+
"pytest-asyncio==1.3.0",
37+
"black==26.1.0",
38+
"mypy==1.19.1",
39+
"ruff==0.15.1",
40+
"types-PyYAML==6.0.12.20250915",
4141
]
4242

4343
[tool.black]

go/core/cli/internal/mcp/frameworks/python/templates/src/core/server.py.tmpl

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This server automatically discovers and loads tools from the tools directory.
44
Each tool file should contain a function decorated with @mcp.tool().
55
"""
66

7+
import asyncio
78
import importlib.util
89
import logging
910
import sys
@@ -75,14 +76,14 @@ class DynamicMCPServer:
7576
for tool_file in tool_files:
7677
try:
7778
# Get the number of tools before importing
78-
tools_before = len(self.mcp._tool_manager._tools)
79+
tools_before = len(asyncio.run(self.mcp.list_tools()))
7980

8081
# Simply import the module - tools auto-register via @mcp.tool()
8182
# decorator
8283
tool_name = tool_file.stem
8384
if self._import_tool_module(tool_file, tool_name):
8485
# Check if any tools were actually registered
85-
tools_after = len(self.mcp._tool_manager._tools)
86+
tools_after = len(asyncio.run(self.mcp.list_tools()))
8687
if tools_after > tools_before:
8788
self.loaded_tools.append(tool_name)
8889
loaded_count += 1
@@ -140,10 +141,21 @@ class DynamicMCPServer:
140141
return False
141142

142143
def get_tools_sync(self) -> dict[str, Any]:
143-
"""Get tools synchronously for testing purposes."""
144-
# This is a simplified version for testing - in real usage, use get_tools()
145-
# async
146-
return self.mcp._tool_manager._tools
144+
"""Get tools synchronously for testing purposes.
145+
146+
This prefers returning the internal tool mapping (name -> tool object)
147+
to preserve compatibility with existing tests/code, and falls back to
148+
using list_tools() if no such mapping is available.
149+
"""
150+
# Prefer an internal mapping if FastMCP exposes one (e.g., for tests
151+
# that rely on direct access to the underlying tool objects/callables).
152+
internal_tools = getattr(self.mcp, "tools", None)
153+
if isinstance(internal_tools, dict):
154+
return internal_tools
155+
156+
# Fallback: build a mapping from the async list_tools() API.
157+
tools_list = asyncio.run(self.mcp.list_tools())
158+
return {t.name: t for t in tools_list}
147159

148160
def run(self, transport_mode: str = "stdio", host: str = "localhost", port: int = 3000) -> None:
149161
"""Run the FastMCP server.

go/core/cli/internal/mcp/frameworks/python/templates/src/main.py.tmpl

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ Each tool file should contain a function decorated with @mcp.tool().
77
Usage Examples:
88
# Stdio mode (default MCP transport)
99
python src/main.py
10-
10+
1111
# HTTP mode with MCP protocol over HTTP
1212
python src/main.py --transport http
13-
13+
1414
# Custom host/port
1515
python src/main.py --transport http --host localhost --port 8080
16-
16+
17+
# Stateless HTTP mode
18+
python src/main.py --transport http --stateless-http
19+
1720
# Environment variable mode
1821
MCP_TRANSPORT_MODE=http python src/main.py
1922
"""
@@ -52,6 +55,18 @@ def main() -> None:
5255
help="Port to bind to in HTTP mode (default: 3000)"
5356
)
5457

58+
stateless_http_default = os.getenv("MCP_STATELESS_HTTP", "false").lower() == "true"
59+
60+
parser.add_argument(
61+
"--stateless-http",
62+
action=argparse.BooleanOptionalAction,
63+
default=stateless_http_default,
64+
help=(
65+
"Enable stateless HTTP mode (use --no-stateless-http to disable; "
66+
"default is derived from MCP_STATELESS_HTTP env var)"
67+
),
68+
)
69+
5570
args = parser.parse_args()
5671

5772
# Check environment variable for transport mode
@@ -78,8 +93,11 @@ def main() -> None:
7893

7994
if transport_mode not in ["http", "stdio"]:
8095
raise ValueError(f"Invalid transport mode: {transport_mode}. Must be one of: http, or stdio")
81-
82-
server.run(transport_mode=transport_mode, host=args.host, port=args.port)
96+
97+
server.run(transport_mode=transport_mode,
98+
host=args.host,
99+
port=args.port,
100+
stateless_http=args.stateless_http)
83101

84102
except KeyboardInterrupt:
85103
print("\nShutting down server...")

0 commit comments

Comments
 (0)