Skip to content

Commit 39314bd

Browse files
committed
Read config from envvar
1 parent a4b97af commit 39314bd

File tree

3 files changed

+22
-28
lines changed

3 files changed

+22
-28
lines changed

backend/src/neuroagent/app/config.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import Any, Literal, Optional
66

77
from dotenv import dotenv_values
8-
from pydantic import BaseModel, ConfigDict, SecretStr, model_validator
8+
from pydantic import BaseModel, ConfigDict, Field, SecretStr, model_validator
99
from pydantic_settings import BaseSettings, SettingsConfigDict
1010

1111

@@ -241,10 +241,20 @@ def disable_if_no_url(cls, data: Any) -> Any:
241241
return data
242242

243243

244+
class MCPServerConfig(BaseModel):
245+
"""Configuration for a single MCP server."""
246+
247+
command: str
248+
args: list[str] | None = None
249+
env: dict[str, SecretStr] | None = None
250+
251+
244252
class SettingsMCP(BaseModel):
245253
"""Settings for the MCP."""
246254

247-
config_path: Path | None = None
255+
servers: dict[str, MCPServerConfig] = Field(
256+
default_factory=dict,
257+
)
248258

249259

250260
class Settings(BaseSettings):

backend/src/neuroagent/app/main.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,8 @@ async def lifespan(fastapi_app: FastAPI) -> AsyncContextManager[None]: # type:
115115
semantic_router = get_semantic_router(settings=app_settings)
116116
app.state.semantic_router = semantic_router
117117

118-
if app_settings.mcp.config_path is not None:
119-
mcp_client: MCPClient | None = MCPClient(
120-
config_path=app_settings.mcp.config_path,
121-
)
118+
if app_settings.mcp.servers:
119+
mcp_client: MCPClient | None = MCPClient(config=app_settings.mcp)
122120
# start mcp servers and autogenerate input schemas
123121

124122
await mcp_client.start()

backend/src/neuroagent/mcp.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,15 @@
1818
from mcp.types import CallToolResult, Tool
1919
from neuroagent.tools.base_tool import BaseTool, BaseMetadata
2020
from datamodel_code_generator.parser import LiteralType
21+
from neuroagent.app.config import SettingsMCP
2122

2223
logger = logging.getLogger(__name__)
2324

2425

25-
class MCPServerConfig(BaseModel):
26-
command: str
27-
args: list[str] | None = None
28-
env: dict[str, str] | None = None
29-
30-
31-
class MCPConfig(BaseModel):
32-
servers: dict[str, MCPServerConfig]
33-
34-
@classmethod
35-
def parse_file(cls, config_path: Path) -> "MCPConfig":
36-
"""Parse the configuration file and return an MCPConfig object."""
37-
if not config_path.exists():
38-
raise FileNotFoundError(f"Configuration file {config_path} does not exist.")
39-
dct = json.loads(config_path.read_text())
40-
41-
return cls(**dct)
42-
43-
4426
class MCPClient:
45-
def __init__(self, config_path: Path):
27+
def __init__(self, config: SettingsMCP):
4628
# Initialize session and client objects
47-
self.config = MCPConfig.parse_file(config_path)
29+
self.config = config
4830
self.exit_stack: dict[str, AsyncExitStack] = {
4931
name: AsyncExitStack() for name in self.config.servers.keys()
5032
}
@@ -79,10 +61,14 @@ async def connect_to_servers(self) -> None:
7961
"""
8062
for name, server_config in self.config.servers.items():
8163
logger.info(f"Connecting to server: {name}")
64+
if server_config.env:
65+
env = {k: v.get_secret_value() for k, v in server_config.env.items()}
66+
else:
67+
env = None
8268
server_params = StdioServerParameters(
8369
command=server_config.command,
8470
args=server_config.args or [],
85-
env=server_config.env or None,
71+
env=env,
8672
)
8773

8874
stdio_transport = await self.exit_stack[name].enter_async_context(

0 commit comments

Comments
 (0)