diff --git a/libs/arcade-cli/arcade_cli/configure.py b/libs/arcade-cli/arcade_cli/configure.py
index 5c8627e0..8aa728c7 100644
--- a/libs/arcade-cli/arcade_cli/configure.py
+++ b/libs/arcade-cli/arcade_cli/configure.py
@@ -56,6 +56,26 @@ def configure_claude_local(server_name: str, port: int = 8000, path: Path | None
config_path = path or get_claude_config_path()
config_path.parent.mkdir(parents=True, exist_ok=True)
+ # Assume server.py is the entry point for the server
+ server_file = Path.cwd() / "server.py"
+
+ # Find the Python interpreter in the virtual environment
+ venv_python = None
+ # Check for .venv first (uv default)
+ if (Path.cwd() / ".venv").exists():
+ system = platform.system()
+ if system == "Windows":
+ venv_python = Path.cwd() / ".venv" / "Scripts" / "python.exe"
+ else:
+ venv_python = Path.cwd() / ".venv" / "bin" / "python"
+
+ # Fall back to system python if no venv found
+ if not venv_python or not venv_python.exists():
+ console.print("[yellow]Warning: No .venv found, using system python[/yellow]")
+ import sys
+
+ venv_python = Path(sys.executable)
+
# Load existing config or create new one
config = {}
if config_path.exists():
@@ -66,10 +86,10 @@ def configure_claude_local(server_name: str, port: int = 8000, path: Path | None
if "mcpServers" not in config:
config["mcpServers"] = {}
+ # Claude Desktop uses stdio transport
config["mcpServers"][server_name] = {
- "command": "python",
- "args": ["-m", "arcade_mcp_server", "stream"],
- "url": f"http://localhost:{port}/mcp",
+ "command": str(venv_python),
+ "args": [str(server_file), "stdio"],
}
# Write updated config
@@ -82,7 +102,8 @@ def configure_claude_local(server_name: str, port: int = 8000, path: Path | None
)
config_file_path = config_path.as_posix().replace(" ", "\\ ")
console.print(f" MCP client config file: {config_file_path}", style="dim")
- console.print(f" MCP Server URL: http://localhost:{port}/mcp", style="dim")
+ console.print(f" Server file: {server_file}", style="dim")
+ console.print(f" Python interpreter: {venv_python}", style="dim")
console.print(" Restart Claude Desktop for changes to take effect.", style="yellow")
diff --git a/libs/arcade-cli/arcade_cli/new.py b/libs/arcade-cli/arcade_cli/new.py
index d4c67fd7..6da5be90 100644
--- a/libs/arcade-cli/arcade_cli/new.py
+++ b/libs/arcade-cli/arcade_cli/new.py
@@ -19,14 +19,14 @@ try:
ARCADE_MCP_MAX_VERSION = str(int(ARCADE_MCP_MIN_VERSION.split(".")[0]) + 1) + ".0.0"
except Exception as e:
console.print(f"[red]Failed to get arcade-mcp version: {e}[/red]")
- ARCADE_MCP_MIN_VERSION = "1.0.0" # Default version if unable to fetch
+ ARCADE_MCP_MIN_VERSION = "1.1.0" # Default version if unable to fetch
ARCADE_MCP_MAX_VERSION = "2.0.0"
ARCADE_TDK_MIN_VERSION = "3.0.0"
ARCADE_TDK_MAX_VERSION = "4.0.0"
ARCADE_SERVE_MIN_VERSION = "3.0.0"
ARCADE_SERVE_MAX_VERSION = "4.0.0"
-ARCADE_MCP_SERVER_MIN_VERSION = "1.0.1"
+ARCADE_MCP_SERVER_MIN_VERSION = "1.1.1"
ARCADE_MCP_SERVER_MAX_VERSION = "2.0.0"
diff --git a/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/pyproject.toml b/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/pyproject.toml
index 5501a074..59411b62 100644
--- a/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/pyproject.toml
+++ b/libs/arcade-cli/arcade_cli/templates/minimal/{{ toolkit_name }}/pyproject.toml
@@ -9,6 +9,7 @@ description = "MCP Server created with Arcade.dev"
requires-python = ">=3.10"
dependencies = [
"arcade-mcp-server>={{ arcade_mcp_server_min_version }},<{{ arcade_mcp_server_max_version }}",
+ "httpx>=0.28.0,<1.0.0",
]
[project.optional-dependencies]
diff --git a/libs/arcade-mcp-server/arcade_mcp_server/__main__.py b/libs/arcade-mcp-server/arcade_mcp_server/__main__.py
index 36b01693..ca9af2d4 100644
--- a/libs/arcade-mcp-server/arcade_mcp_server/__main__.py
+++ b/libs/arcade-mcp-server/arcade_mcp_server/__main__.py
@@ -54,7 +54,7 @@ def setup_logging(level: str = "INFO", stdio_mode: bool = False) -> None:
# Remove existing handlers
logger.remove()
- # Configure output destination
+ # In stdio mode, use stderr (stdout is reserved for JSON-RPC)
sink = sys.stderr if stdio_mode else sys.stdout
# Add handler with appropriate format
@@ -69,7 +69,7 @@ def setup_logging(level: str = "INFO", stdio_mode: bool = False) -> None:
sink,
format=format_str,
level=level,
- colorize=True,
+ colorize=(not stdio_mode),
diagnose=(level == "DEBUG"),
)
diff --git a/libs/arcade-mcp-server/arcade_mcp_server/mcp_app.py b/libs/arcade-mcp-server/arcade_mcp_server/mcp_app.py
index bad6d94a..7e77d027 100644
--- a/libs/arcade-mcp-server/arcade_mcp_server/mcp_app.py
+++ b/libs/arcade-mcp-server/arcade_mcp_server/mcp_app.py
@@ -103,7 +103,8 @@ class MCPApp:
self.server: MCPServer | None = None
self._load_env()
- self._setup_logging()
+ if not logger._core.handlers: # type: ignore[attr-defined]
+ self._setup_logging(transport == "stdio")
# Properties (exposed below initializer)
@property
@@ -128,17 +129,21 @@ class MCPApp:
load_dotenv(env_path, override=False)
logger.info(f"Loaded environment from {env_path}")
- def _setup_logging(self) -> None:
+ def _setup_logging(self, stdio_mode: bool = False) -> None:
logger.remove()
+
+ # In stdio mode, use stderr (stdout is reserved for JSON-RPC)
+ sink = sys.stderr if stdio_mode else sys.stdout
+
if self.log_level == "DEBUG":
format_str = "{level: <8} | {time:HH:mm:ss} | {name}:{line} | {message}"
else:
format_str = "{level: <8} | {time:HH:mm:ss} | {message}"
logger.add(
- sys.stdout,
+ sink,
format=format_str,
level=self.log_level,
- colorize=True,
+ colorize=(not stdio_mode),
diagnose=(self.log_level == "DEBUG"),
)
@@ -209,10 +214,13 @@ class MCPApp:
logger.error("No tools added to the server. Use @app.tool decorator or app.add_tool().")
sys.exit(1)
- logger.info(f"Starting {self.name} v{self.version} with {len(self._catalog)} tools")
-
host, port, transport = MCPApp._get_configuration_overrides(host, port, transport)
+ # Since the transport could have changed since __init__, we need to setup logging again
+ self._setup_logging(transport == "stdio")
+
+ logger.info(f"Starting {self.name} v{self.version} with {len(self._catalog)} tools")
+
if transport in ["http", "streamable-http", "streamable"]:
run_arcade_mcp(
catalog=self._catalog,
diff --git a/libs/arcade-mcp-server/pyproject.toml b/libs/arcade-mcp-server/pyproject.toml
index d6b06349..1b897056 100644
--- a/libs/arcade-mcp-server/pyproject.toml
+++ b/libs/arcade-mcp-server/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "arcade-mcp-server"
-version = "1.1.0"
+version = "1.1.1"
description = "Model Context Protocol (MCP) server framework for Arcade.dev"
readme = "README.md"
authors = [{ name = "Arcade.dev" }]
diff --git a/pyproject.toml b/pyproject.toml
index 287ff2ec..e128247f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "arcade-mcp"
-version = "1.0.2"
+version = "1.1.0"
description = "Arcade.dev - Tool Calling platform for Agents"
readme = "README.md"
license = {file = "LICENSE"}
@@ -21,7 +21,7 @@ requires-python = ">=3.10"
dependencies = [
# CLI dependencies
- "arcade-mcp-server>=1.1.0,<2.0.0",
+ "arcade-mcp-server>=1.1.1,<2.0.0",
"arcade-core>=3.0.0,<4.0.0",
"typer==0.10.0",
"rich==13.9.4",
@@ -42,7 +42,7 @@ all = [
"pytz>=2024.1",
"python-dateutil>=2.8.2",
# mcp
- "arcade-mcp-server>=1.1.0,<2.0.0",
+ "arcade-mcp-server>=1.1.1,<2.0.0",
# serve
"arcade-serve>=3.0.0,<4.0.0",
# tdk