@@ -31,50 +31,43 @@ def validate_servers(self) -> None:
31
31
raise ValueError (f'Invalid URL { url } : { str (e )} ' )
32
32
33
33
34
+ class MCPStdioConfigEntry (BaseModel ):
35
+ """Configuration for a single MCP stdio entry.
36
+
37
+ Attributes:
38
+ command: The command to run.
39
+ args: List of arguments for the command.
40
+ env: Dictionary of environment variables.
41
+ """
42
+
43
+ command : str
44
+ args : list [str ] = Field (default_factory = list )
45
+ env : dict [str , str ] = Field (default_factory = dict )
46
+
47
+ model_config = {'extra' : 'forbid' }
48
+
49
+
34
50
class MCPStdioConfig (BaseModel ):
35
51
"""Configuration for MCP stdio settings.
36
52
37
53
Attributes:
38
- commands: List of commands to run.
39
- args: List of arguments for each command.
40
- envs: List of environment variable tuples for each command.
54
+ tools: Dictionary of tool configurations, where keys are tool names.
41
55
"""
42
56
43
- commands : List [str ] = Field (default_factory = list )
44
- args : List [List [str ]] = Field (default_factory = list )
45
- envs : List [List [tuple [str , str ]]] = Field (default_factory = list )
57
+ tools : dict [str , MCPStdioConfigEntry ] = Field (default_factory = dict )
46
58
47
59
model_config = {'extra' : 'forbid' }
48
60
49
61
def validate_stdio (self ) -> None :
50
- """Validate that commands, args, and envs are properly configured."""
51
-
52
- # Check if number of commands matches number of args lists
53
- if len (self .commands ) != len (self .args ):
54
- raise ValueError (
55
- f'Number of commands ({ len (self .commands )} ) does not match '
56
- f'number of args lists ({ len (self .args )} )'
57
- )
58
-
59
- # Check if number of commands matches number of envs lists
60
- if len (self .commands ) != len (self .envs ):
61
- raise ValueError (
62
- f'Number of commands ({ len (self .commands )} ) does not match '
63
- f'number of envs lists ({ len (self .envs )} )'
64
- )
65
-
66
- # Validate each environment variable tuple
67
- for i , env_list in enumerate (self .envs ):
68
- for j , env_tuple in enumerate (env_list ):
69
- if not isinstance (env_tuple , tuple ) or len (env_tuple ) != 2 :
70
- raise ValueError (
71
- f'Environment variable at index { j } for command { i } must be a tuple of (key, value)'
72
- )
73
- key , value = env_tuple
74
- if not isinstance (key , str ) or not isinstance (value , str ):
75
- raise ValueError (
76
- f'Environment variable key and value at index { j } for command { i } must be strings'
77
- )
62
+ """Validate that tools are properly configured."""
63
+ # Tool names validation
64
+ for tool_name in self .tools :
65
+ if not tool_name .strip ():
66
+ raise ValueError ('Tool names cannot be empty' )
67
+ if not tool_name .replace ('-' , '' ).isalnum ():
68
+ raise ValueError (
69
+ f'Invalid tool name: { tool_name } . Tool names must be alphanumeric (hyphens allowed)'
70
+ )
78
71
79
72
80
73
class MCPConfig (BaseModel ):
@@ -105,11 +98,11 @@ def from_toml_section(cls, data: dict) -> dict[str, 'MCPConfig']:
105
98
106
99
try :
107
100
# Create SSE config if present
108
- sse_config = MCPSSEConfig ( ** data .get ('mcp-sse' , {}))
101
+ sse_config = MCPSSEConfig . model_validate ( data .get ('mcp-sse' , {}))
109
102
sse_config .validate_servers ()
110
103
111
104
# Create stdio config if present
112
- stdio_config = MCPStdioConfig ( ** data .get ('mcp-stdio' , {}))
105
+ stdio_config = MCPStdioConfig . model_validate ( data .get ('mcp-stdio' , {}))
113
106
stdio_config .validate_stdio ()
114
107
115
108
# Create the main MCP config
0 commit comments