Aasher commited on
Commit
e58fdc1
·
1 Parent(s): a2dea64

feat: Enhance MCP server configuration handling and logging in Axiom 2.0 Agent

Browse files
Files changed (2) hide show
  1. mcp.json +17 -0
  2. src/axiom/config.py +85 -2
mcp.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "command": "npx",
5
+ "args": ["-y", "@upstash/context7-mcp@latest"]
6
+ },
7
+ "sequential-thinking": {
8
+ "command": "npx",
9
+ "args": [
10
+ "-y",
11
+ "@modelcontextprotocol/server-sequential-thinking"
12
+ ]
13
+ }
14
+ }
15
+ }
16
+
17
+
src/axiom/config.py CHANGED
@@ -1,10 +1,32 @@
1
  import os
 
 
 
2
  from dotenv import load_dotenv
3
 
 
 
 
 
4
  from pydantic_settings import BaseSettings, SettingsConfigDict
5
 
 
 
6
  _ = load_dotenv()
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  class Settings(BaseSettings):
9
  model_config = SettingsConfigDict(
10
  env_file=".env", extra="ignore", env_file_encoding="utf-8"
@@ -12,10 +34,12 @@ class Settings(BaseSettings):
12
  """
13
  Configuration settings for the Axiom 2.0 Agent.
14
  """
 
15
  GOOGLE_API_KEY: str
16
  DEFAULT_MODEL: str = "gemini-2.0-flash"
17
  BASE_URL: str = "https://generativelanguage.googleapis.com/v1beta/openai/"
18
 
 
19
  AVAILABLE_MODELS: list[str] = [
20
  "gemini-2.0-flash",
21
  "gemini-2.0-flash-lite",
@@ -23,7 +47,66 @@ class Settings(BaseSettings):
23
  "gemini-2.5-pro-exp-03-25",
24
  "gemini-2.5-flash-preview-04-17",
25
  ]
26
-
 
 
27
  MAX_DOCS_TOKEN_LIMIT: int = 20000 # Maximum tokens to retrieve from the documentations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- settings = Settings()
 
1
  import os
2
+ import json
3
+ import logging
4
+ from pathlib import Path
5
  from dotenv import load_dotenv
6
 
7
+ from typing import Dict, List, Optional, Any
8
+
9
+ from dotenv import load_dotenv
10
+ from pydantic import Field, ValidationError
11
  from pydantic_settings import BaseSettings, SettingsConfigDict
12
 
13
+ from agents.mcp import MCPServer, MCPServerStdio
14
+
15
  _ = load_dotenv()
16
 
17
+ # --- Setup Logging ---
18
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
19
+ logger = logging.getLogger(__name__)
20
+
21
+ # --- Determine Project Root ---
22
+ PROJECT_ROOT = Path(__file__).parent.parent.parent
23
+
24
+ # --- MCP Server Configuration Model ---
25
+ class MCPServerConfig(BaseSettings):
26
+ """Represents the configuration for a single MCP server in mcp.json."""
27
+ command: str
28
+ args: List[str]
29
+
30
  class Settings(BaseSettings):
31
  model_config = SettingsConfigDict(
32
  env_file=".env", extra="ignore", env_file_encoding="utf-8"
 
34
  """
35
  Configuration settings for the Axiom 2.0 Agent.
36
  """
37
+ # --- API Configuration ---
38
  GOOGLE_API_KEY: str
39
  DEFAULT_MODEL: str = "gemini-2.0-flash"
40
  BASE_URL: str = "https://generativelanguage.googleapis.com/v1beta/openai/"
41
 
42
+ # --- Model Configuration ---
43
  AVAILABLE_MODELS: list[str] = [
44
  "gemini-2.0-flash",
45
  "gemini-2.0-flash-lite",
 
47
  "gemini-2.5-pro-exp-03-25",
48
  "gemini-2.5-flash-preview-04-17",
49
  ]
50
+
51
+ # --- Agent Configuration ---
52
+ AGENT_NAME: str = "Axiom 2.0"
53
  MAX_DOCS_TOKEN_LIMIT: int = 20000 # Maximum tokens to retrieve from the documentations
54
+
55
+ # --- Tracing ---
56
+ TRACING_ENABLED: bool = False
57
+
58
+ # --- MCP Configuration ---
59
+ MCP_CONFIG_PATH: Path = Field(default=PROJECT_ROOT / "mcp.json")
60
+
61
+ # --- Instantiate Settings ---
62
+ try:
63
+ settings = Settings()
64
+ if not settings.GOOGLE_API_KEY:
65
+ logger.warning("GOOGLE_API_KEY is not set. OpenAI client initialization might fail.")
66
+ except ValidationError as e:
67
+ logger.error(f"Configuration validation failed: {e}")
68
+ raise SystemExit(f"Configuration error: {e}") from e
69
+
70
+
71
+ # --- MCP Server Loading Function ---
72
+ def load_mcp_servers_from_config(config_path: Path = settings.MCP_CONFIG_PATH) -> List[MCPServer]:
73
+ """
74
+ Loads MCP server configurations from the specified JSON file.
75
+ """
76
+ servers: List[MCPServer] = []
77
+
78
+ # Raise FileNotFoundError if file doesn't exist
79
+ if not config_path.is_file():
80
+ logger.error(f"MCP configuration file not found: {config_path}")
81
+ raise FileNotFoundError(f"MCP configuration file not found: {config_path}")
82
+
83
+ logger.info(f"Loading MCP servers from: {config_path}")
84
+
85
+ # Allow json.JSONDecodeError to propagate if file is invalid JSON
86
+ with open(config_path, 'r', encoding='utf-8') as f:
87
+ data = json.load(f)
88
+
89
+ mcp_servers_data = data.get("mcpServers")
90
+ if not isinstance(mcp_servers_data, dict):
91
+ # Raise ValueError if the main structure is wrong
92
+ raise ValueError("Invalid mcp.json structure: 'mcpServers' key must map to an object.")
93
+
94
+ # Iterate and handle individual server errors as warnings
95
+ for name, config_dict in mcp_servers_data.items():
96
+ try:
97
+ server_config = MCPServerConfig(**config_dict)
98
+
99
+ server_instance = MCPServerStdio(
100
+ name=name,
101
+ params={
102
+ "command": server_config.command,
103
+ "args": server_config.args,
104
+ }
105
+ )
106
+ servers.append(server_instance)
107
+ logger.info(f"Prepared MCP Server: {name}")
108
+
109
+ except (ValidationError, Exception) as e:
110
+ logger.warning(f"Skipping MCP server '{name}' due to configuration error: {e}")
111
 
112
+ return servers