autobyteus 1.1.0__py3-none-any.whl → 1.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +1 -1
  2. autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +1 -1
  3. autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -1
  4. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +1 -1
  5. autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +1 -1
  6. autobyteus/agent/context/__init__.py +0 -5
  7. autobyteus/agent/context/agent_config.py +6 -2
  8. autobyteus/agent/context/agent_context.py +2 -5
  9. autobyteus/agent/context/agent_phase_manager.py +105 -5
  10. autobyteus/agent/context/agent_runtime_state.py +2 -2
  11. autobyteus/agent/context/phases.py +2 -0
  12. autobyteus/agent/events/__init__.py +0 -11
  13. autobyteus/agent/events/agent_events.py +0 -37
  14. autobyteus/agent/events/notifiers.py +25 -7
  15. autobyteus/agent/events/worker_event_dispatcher.py +1 -1
  16. autobyteus/agent/factory/agent_factory.py +6 -2
  17. autobyteus/agent/group/agent_group.py +16 -7
  18. autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +28 -14
  19. autobyteus/agent/handlers/lifecycle_event_logger.py +1 -1
  20. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +4 -2
  21. autobyteus/agent/handlers/tool_invocation_request_event_handler.py +40 -15
  22. autobyteus/agent/handlers/tool_result_event_handler.py +12 -7
  23. autobyteus/agent/hooks/__init__.py +7 -0
  24. autobyteus/agent/hooks/base_phase_hook.py +11 -2
  25. autobyteus/agent/hooks/hook_definition.py +36 -0
  26. autobyteus/agent/hooks/hook_meta.py +37 -0
  27. autobyteus/agent/hooks/hook_registry.py +118 -0
  28. autobyteus/agent/input_processor/base_user_input_processor.py +6 -3
  29. autobyteus/agent/input_processor/passthrough_input_processor.py +2 -1
  30. autobyteus/agent/input_processor/processor_meta.py +1 -1
  31. autobyteus/agent/input_processor/processor_registry.py +19 -0
  32. autobyteus/agent/llm_response_processor/base_processor.py +6 -3
  33. autobyteus/agent/llm_response_processor/processor_meta.py +1 -1
  34. autobyteus/agent/llm_response_processor/processor_registry.py +19 -0
  35. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +2 -1
  36. autobyteus/agent/message/context_file_type.py +2 -3
  37. autobyteus/agent/phases/__init__.py +18 -0
  38. autobyteus/agent/phases/discover.py +52 -0
  39. autobyteus/agent/phases/manager.py +265 -0
  40. autobyteus/agent/phases/phase_enum.py +49 -0
  41. autobyteus/agent/phases/transition_decorator.py +40 -0
  42. autobyteus/agent/phases/transition_info.py +33 -0
  43. autobyteus/agent/remote_agent.py +1 -1
  44. autobyteus/agent/runtime/agent_runtime.py +5 -10
  45. autobyteus/agent/runtime/agent_worker.py +62 -19
  46. autobyteus/agent/streaming/agent_event_stream.py +58 -5
  47. autobyteus/agent/streaming/stream_event_payloads.py +24 -13
  48. autobyteus/agent/streaming/stream_events.py +14 -11
  49. autobyteus/agent/system_prompt_processor/base_processor.py +6 -3
  50. autobyteus/agent/system_prompt_processor/processor_meta.py +1 -1
  51. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +45 -31
  52. autobyteus/agent/tool_invocation.py +29 -3
  53. autobyteus/agent/utils/wait_for_idle.py +1 -1
  54. autobyteus/agent/workspace/__init__.py +2 -0
  55. autobyteus/agent/workspace/base_workspace.py +33 -11
  56. autobyteus/agent/workspace/workspace_config.py +160 -0
  57. autobyteus/agent/workspace/workspace_definition.py +36 -0
  58. autobyteus/agent/workspace/workspace_meta.py +37 -0
  59. autobyteus/agent/workspace/workspace_registry.py +72 -0
  60. autobyteus/cli/__init__.py +4 -3
  61. autobyteus/cli/agent_cli.py +25 -207
  62. autobyteus/cli/cli_display.py +205 -0
  63. autobyteus/events/event_manager.py +2 -1
  64. autobyteus/events/event_types.py +3 -1
  65. autobyteus/llm/api/autobyteus_llm.py +2 -12
  66. autobyteus/llm/api/deepseek_llm.py +11 -173
  67. autobyteus/llm/api/grok_llm.py +11 -172
  68. autobyteus/llm/api/kimi_llm.py +24 -0
  69. autobyteus/llm/api/mistral_llm.py +4 -4
  70. autobyteus/llm/api/ollama_llm.py +2 -2
  71. autobyteus/llm/api/openai_compatible_llm.py +193 -0
  72. autobyteus/llm/api/openai_llm.py +11 -139
  73. autobyteus/llm/extensions/token_usage_tracking_extension.py +11 -1
  74. autobyteus/llm/llm_factory.py +168 -42
  75. autobyteus/llm/models.py +25 -29
  76. autobyteus/llm/ollama_provider.py +6 -2
  77. autobyteus/llm/ollama_provider_resolver.py +44 -0
  78. autobyteus/llm/providers.py +1 -0
  79. autobyteus/llm/token_counter/kimi_token_counter.py +24 -0
  80. autobyteus/llm/token_counter/token_counter_factory.py +3 -0
  81. autobyteus/llm/utils/messages.py +3 -3
  82. autobyteus/tools/__init__.py +2 -0
  83. autobyteus/tools/base_tool.py +7 -1
  84. autobyteus/tools/functional_tool.py +20 -5
  85. autobyteus/tools/mcp/call_handlers/stdio_handler.py +15 -1
  86. autobyteus/tools/mcp/config_service.py +106 -127
  87. autobyteus/tools/mcp/registrar.py +247 -59
  88. autobyteus/tools/mcp/types.py +5 -3
  89. autobyteus/tools/registry/tool_definition.py +8 -1
  90. autobyteus/tools/registry/tool_registry.py +18 -0
  91. autobyteus/tools/tool_category.py +11 -0
  92. autobyteus/tools/tool_meta.py +3 -1
  93. autobyteus/tools/tool_state.py +20 -0
  94. autobyteus/tools/usage/parsers/_json_extractor.py +99 -0
  95. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +46 -77
  96. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +87 -96
  97. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +37 -47
  98. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +112 -113
  99. {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/METADATA +13 -12
  100. {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/RECORD +103 -82
  101. {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/WHEEL +0 -0
  102. {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/licenses/LICENSE +0 -0
  103. {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/top_level.txt +0 -0
@@ -23,7 +23,8 @@ class McpConfigService(metaclass=SingletonMeta):
23
23
  self._configs: Dict[str, BaseMcpConfig] = {}
24
24
  logger.info("McpConfigService initialized.")
25
25
 
26
- def _parse_transport_type(self, type_str: str, server_identifier: str) -> McpTransportType:
26
+ @staticmethod
27
+ def _parse_transport_type(type_str: str, server_identifier: str) -> McpTransportType:
27
28
  """Parses string to McpTransportType enum."""
28
29
  try:
29
30
  return McpTransportType(type_str.lower())
@@ -34,21 +35,19 @@ class McpConfigService(metaclass=SingletonMeta):
34
35
  f"Valid types are: {valid_types}."
35
36
  )
36
37
 
37
- def _create_specific_config(self, server_id: str, transport_type: McpTransportType, config_data: Dict[str, Any]) -> BaseMcpConfig:
38
+ @staticmethod
39
+ def _create_specific_config(server_id: str, transport_type: McpTransportType, config_data: Dict[str, Any]) -> BaseMcpConfig:
38
40
  """
39
41
  Creates a specific McpServerConfig (Stdio, Sse, StreamableHttp) based on transport_type.
40
42
  The 'server_id' is injected.
41
43
  Parameters from nested structures like 'stdio_params' are un-nested.
42
44
  """
43
- # Start with base parameters that can be at the top level of config_data
44
45
  constructor_params = {'server_id': server_id}
45
46
 
46
- # Explicitly copy known BaseMcpConfig fields from config_data if they exist
47
47
  for base_key in ['enabled', 'tool_name_prefix']:
48
48
  if base_key in config_data:
49
49
  constructor_params[base_key] = config_data[base_key]
50
50
 
51
- # Define keys for nested transport-specific parameters
52
51
  transport_specific_params_key_map = {
53
52
  McpTransportType.STDIO: "stdio_params",
54
53
  McpTransportType.SSE: "sse_params",
@@ -60,39 +59,19 @@ class McpConfigService(metaclass=SingletonMeta):
60
59
  specific_params_dict = config_data.get(params_key, {})
61
60
  if not isinstance(specific_params_dict, dict):
62
61
  raise ValueError(f"'{params_key}' for server '{server_id}' must be a dictionary, got {type(specific_params_dict)}.")
63
- # Merge extracted specific params into constructor_params
64
- # This allows specific params (e.g. 'command') to be defined inside the nested dict
65
62
  constructor_params.update(specific_params_dict)
66
63
 
67
- # Filter out keys that are not part of the target dataclass or already processed
68
- # For example, remove 'transport_type' and the 'xxx_params' keys themselves
69
- # from the final constructor_params if they were top-level in config_data.
70
- # Note: config_data at this point is the value part of the server_id -> value map,
71
- # or an item from the list of configs.
72
- # So, 'transport_type' and 'stdio_params' (etc.) will be keys in it.
64
+ constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.STDIO), None)
65
+ constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.SSE), None)
66
+ constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.STREAMABLE_HTTP), None)
67
+ constructor_params.pop('transport_type', None)
73
68
 
74
- # Clean up params_for_constructor by removing original nested dict keys and transport_type
75
- if transport_type in transport_specific_params_key_map:
76
- constructor_params.pop(transport_specific_params_key_map[transport_type], None)
77
- constructor_params.pop('transport_type', None) # From original config_data if it was spread
78
- # Actually, config_data doesn't have server_id yet.
79
- # server_id is added to constructor_params at the start.
80
- # transport_type is not added to constructor_params from config_data.
81
-
82
- # This part ensures any other top-level keys in config_data that are valid for the
83
- # specific config class (but not 'enabled', 'tool_name_prefix', or the nested param dict key itself)
84
- # are also included.
85
- # Example: if StdioMcpServerConfig had a field 'priority' that could be in config_data top-level.
86
69
  other_top_level_keys_to_copy = {
87
70
  k: v for k, v in config_data.items()
88
- if k not in ['enabled', 'tool_name_prefix', 'transport_type',
89
- transport_specific_params_key_map.get(McpTransportType.STDIO),
90
- transport_specific_params_key_map.get(McpTransportType.SSE),
91
- transport_specific_params_key_map.get(McpTransportType.STREAMABLE_HTTP)]
71
+ if k not in ['enabled', 'tool_name_prefix', 'transport_type'] and k not in transport_specific_params_key_map.values()
92
72
  }
93
73
  constructor_params.update(other_top_level_keys_to_copy)
94
74
 
95
-
96
75
  try:
97
76
  if transport_type == McpTransportType.STDIO:
98
77
  return StdioMcpServerConfig(**constructor_params)
@@ -101,33 +80,77 @@ class McpConfigService(metaclass=SingletonMeta):
101
80
  elif transport_type == McpTransportType.STREAMABLE_HTTP:
102
81
  return StreamableHttpMcpServerConfig(**constructor_params)
103
82
  else:
104
- # This path should ideally not be taken if transport_type is validated upfront.
105
- raise ValueError(f"Unsupported McpTransportType '{transport_type}' for server '{server_id}'. Cannot create specific config.")
83
+ raise ValueError(f"Unsupported McpTransportType '{transport_type}' for server '{server_id}'.")
106
84
  except TypeError as e:
107
85
  logger.error(f"TypeError creating config for server '{server_id}' with transport '{transport_type}'. "
108
86
  f"Params: {constructor_params}. Error: {e}", exc_info=True)
109
87
  raise ValueError(f"Failed to create config for server '{server_id}' due to incompatible parameters for {transport_type.name} config: {e}")
110
88
 
89
+ @staticmethod
90
+ def parse_mcp_config_dict(config_dict: Dict[str, Any]) -> BaseMcpConfig:
91
+ """
92
+ Parses a dictionary representing a single MCP server configuration into a
93
+ validated BaseMcpConfig dataclass object.
94
+ The dictionary is expected to have a single top-level key which is the server_id.
95
+ """
96
+ if not isinstance(config_dict, dict) or len(config_dict) != 1:
97
+ raise ValueError("Input must be a dictionary with a single top-level key representing the server_id.")
98
+
99
+ server_id = next(iter(config_dict))
100
+ config_data = config_dict[server_id]
111
101
 
112
- def load_configs(self, source: Union[str, List[Dict[str, Any]], Dict[str, Any]]) -> List[BaseMcpConfig]:
102
+ if not isinstance(config_data, dict):
103
+ raise ValueError(f"Configuration for server '{server_id}' must be a dictionary.")
104
+
105
+ transport_type_str = config_data.get('transport_type')
106
+ if not transport_type_str:
107
+ raise ValueError(f"Config data for server '{server_id}' is missing 'transport_type' field.")
108
+
109
+ transport_type = McpConfigService._parse_transport_type(transport_type_str, server_id)
110
+ return McpConfigService._create_specific_config(server_id, transport_type, config_data)
111
+
112
+ def add_config(self, config_object: BaseMcpConfig) -> BaseMcpConfig:
113
+ """Adds or updates a single, pre-instantiated MCP server configuration object."""
114
+ if not isinstance(config_object, BaseMcpConfig):
115
+ raise TypeError(f"Unsupported input type for add_config: {type(config_object)}. "
116
+ "Expected a BaseMcpConfig subclass object (e.g., StdioMcpServerConfig).")
117
+
118
+ if config_object.server_id in self._configs:
119
+ logger.warning(f"Overwriting existing MCP config with server_id '{config_object.server_id}'.")
120
+
121
+ self._configs[config_object.server_id] = config_object
122
+ logger.info(f"Successfully added/updated {type(config_object).__name__} for server_id '{config_object.server_id}'. "
123
+ f"Total unique configs stored: {len(self._configs)}.")
124
+ return config_object
125
+
126
+ def load_config(self, config_dict: Dict[str, Any]) -> BaseMcpConfig:
113
127
  """
114
- Loads MCP configurations from various source types.
115
- Source can be:
116
- 1. A file path (str) to a JSON file. The JSON file can contain:
117
- a. A list of MCP server configuration dictionaries. Each dict must include "server_id" and "transport_type".
118
- b. A dictionary where keys are server IDs and values are configurations. Each value dict must include "transport_type".
119
- The dictionary key is used as the McpConfig 'server_id'.
120
- 2. A direct list of MCP server configuration dictionaries (List[Dict[str, Any]]).
121
- Each dictionary in the list must have "server_id" and "transport_type".
122
- 3. A direct dictionary where keys are server IDs and values are configurations (Dict[str, Any]).
123
- Each value dict must include "transport_type". The dictionary key is used as the McpConfig 'server_id'.
128
+ Parses a single raw configuration dictionary and adds it to the service.
124
129
 
125
130
  Args:
126
- source: Data source for configurations.
131
+ config_dict: A dictionary representing a single server config,
132
+ with the server_id as the top-level key.
133
+
134
+ Returns:
135
+ The successfully parsed and added McpServerConfig object.
136
+ """
137
+ config_object = self.parse_mcp_config_dict(config_dict)
138
+ return self.add_config(config_object)
127
139
 
140
+
141
+ def load_configs(self, source: Union[str, List[Dict[str, Any]], Dict[str, Any]]) -> List[BaseMcpConfig]:
142
+ """
143
+ Loads multiple MCP configurations from a source, parsing and adding them.
144
+ This will overwrite any existing configurations with the same server_id.
145
+
146
+ Args:
147
+ source: The data source. Can be:
148
+ 1. A file path (str) to a JSON file.
149
+ 2. A list of MCP server configuration dictionaries.
150
+ 3. A dictionary of configurations, keyed by server_id.
151
+
128
152
  Returns:
129
- A list of loaded McpServerConfig objects (subclasses of BaseMcpConfig).
130
- Stores unique configs by server_id internally.
153
+ A list of the successfully added McpServerConfig objects.
131
154
  """
132
155
  loaded_mcp_configs: List[BaseMcpConfig] = []
133
156
 
@@ -139,119 +162,75 @@ class McpConfigService(metaclass=SingletonMeta):
139
162
  with open(source, 'r', encoding='utf-8') as f:
140
163
  json_data = json.load(f)
141
164
  logger.info(f"Successfully loaded JSON data from file: {source}")
142
- # Recursive call with the parsed JSON data
143
165
  return self.load_configs(json_data)
144
166
  except json.JSONDecodeError as e:
145
- logger.error(f"Error decoding JSON from MCP configuration file {source}: {e}")
146
167
  raise ValueError(f"Invalid JSON in MCP configuration file {source}: {e}") from e
147
168
  except Exception as e:
148
- logger.error(f"Error reading MCP configuration file {source}: {e}")
149
169
  raise ValueError(f"Could not read MCP configuration file {source}: {e}") from e
150
170
 
151
171
  elif isinstance(source, list):
152
- logger.info(f"Loading {len(source)} MCP server configurations from provided list.")
153
- for i, config_item_dict in enumerate(source): # Renamed from config_dict to avoid confusion
172
+ for i, config_item_dict in enumerate(source):
154
173
  if not isinstance(config_item_dict, dict):
155
174
  raise ValueError(f"Item at index {i} in source list is not a dictionary.")
156
175
 
157
- current_server_id = config_item_dict.get('server_id')
158
- if not current_server_id:
176
+ server_id = config_item_dict.get('server_id')
177
+ if not server_id:
159
178
  raise ValueError(f"Item at index {i} in source list is missing 'server_id' field.")
160
179
 
161
- transport_type_str = config_item_dict.get('transport_type')
162
- if not transport_type_str:
163
- raise ValueError(f"Item at index {i} (server '{current_server_id}') in source list is missing 'transport_type' field.")
164
-
165
180
  try:
166
- transport_type_enum = self._parse_transport_type(transport_type_str, current_server_id)
167
- # Pass the config_item_dict (which contains transport_type, stdio_params etc.)
168
- config_obj = self._create_specific_config(current_server_id, transport_type_enum, config_item_dict)
169
-
170
- if config_obj.server_id in self._configs:
171
- logger.warning(f"Duplicate MCP config server_id '{config_obj.server_id}' found in list. Overwriting previous entry.")
172
- self._configs[config_obj.server_id] = config_obj
181
+ # A list item is a single config, but doesn't have the server_id as the key,
182
+ # so we wrap it to use the parser.
183
+ config_obj = McpConfigService.parse_mcp_config_dict({server_id: config_item_dict})
184
+ self.add_config(config_obj)
173
185
  loaded_mcp_configs.append(config_obj)
174
- logger.debug(f"Successfully loaded and validated {type(config_obj).__name__} for server_id '{config_obj.server_id}' from list.")
175
- except (ValueError, TypeError) as e:
176
- logger.error(f"Invalid MCP configuration for item at index {i} (server '{current_server_id}') from list: {e}. Config data: {config_item_dict}")
177
- raise ValueError(f"Invalid MCP configuration data (list item at index {i}, server '{current_server_id}'): {e}") from e
186
+ except ValueError as e:
187
+ logger.error(f"Invalid MCP configuration for list item at index {i}: {e}")
188
+ raise
178
189
 
179
190
  elif isinstance(source, dict):
180
- logger.info(f"Loading MCP server configurations from provided dictionary (assumed to be server_id -> config_data map).")
181
- for server_config_key_id, config_value_dict in source.items(): # Renamed variables for clarity
182
- if not isinstance(config_value_dict, dict):
183
- raise ValueError(f"Configuration for server_id '{server_config_key_id}' must be a dictionary.")
184
-
185
- transport_type_str = config_value_dict.get('transport_type')
186
- if not transport_type_str:
187
- raise ValueError(f"Config data for server '{server_config_key_id}' is missing 'transport_type' field.")
191
+ logger.info("Loading MCP server configurations from a dictionary of configs (keyed by server_id).")
192
+ for server_id, config_data in source.items():
193
+ if not isinstance(config_data, dict):
194
+ raise ValueError(f"Configuration for server_id '{server_id}' must be a dictionary.")
188
195
 
189
196
  try:
190
- transport_type_enum = self._parse_transport_type(transport_type_str, server_config_key_id)
191
- # Pass config_value_dict (which contains transport_type, stdio_params etc.)
192
- config_obj = self._create_specific_config(server_config_key_id, transport_type_enum, config_value_dict)
193
-
194
- if config_obj.server_id in self._configs:
195
- logger.warning(f"Duplicate MCP config server_id '{config_obj.server_id}' found in dictionary. Overwriting previous entry.")
196
- self._configs[config_obj.server_id] = config_obj
197
+ config_obj = McpConfigService.parse_mcp_config_dict({server_id: config_data})
198
+ self.add_config(config_obj)
197
199
  loaded_mcp_configs.append(config_obj)
198
- logger.debug(f"Successfully loaded and validated {type(config_obj).__name__} for server_id '{config_obj.server_id}' from dictionary.")
199
- except (ValueError, TypeError) as e:
200
- logger.error(f"Invalid MCP configuration for server_id '{server_config_key_id}' from dictionary: {e}. Config data: {config_value_dict}")
201
- raise ValueError(f"Invalid MCP configuration data (dict entry for server_id '{server_config_key_id}'): {e}") from e
200
+ except ValueError as e:
201
+ logger.error(f"Invalid MCP configuration for server_id '{server_id}': {e}")
202
+ raise
202
203
  else:
203
- raise TypeError(f"Unsupported source type for McpConfigService.load_configs: {type(source)}. "
204
- "Expected file path (str), list of dicts, or dict of dicts.")
204
+ raise TypeError(f"Unsupported source type for load_configs: {type(source)}. "
205
+ "Expected file path, list of dicts, or dict of dicts.")
205
206
 
206
207
  logger.info(f"McpConfigService load_configs completed. {len(loaded_mcp_configs)} new configurations processed. "
207
208
  f"Total unique configs stored: {len(self._configs)}.")
208
209
  return loaded_mcp_configs
209
210
 
210
- def add_config(self, config_object: BaseMcpConfig) -> BaseMcpConfig:
211
- """
212
- Adds a single, pre-instantiated MCP server configuration object to the service.
213
- The configuration object must be an instance of a BaseMcpConfig subclass
214
- (e.g., StdioMcpServerConfig, SseMcpServerConfig).
215
- If a configuration with the same server_id already exists, it will be overwritten.
216
-
217
- Args:
218
- config_object: A BaseMcpConfig subclass instance (e.g., StdioMcpServerConfig).
211
+ def get_config(self, server_id: str) -> Optional[BaseMcpConfig]:
212
+ """Retrieves an MCP server configuration by its unique server ID."""
213
+ return self._configs.get(server_id)
219
214
 
220
- Returns:
221
- The added or updated McpServerConfig object.
215
+ def get_all_configs(self) -> List[BaseMcpConfig]:
216
+ return list(self._configs.values())
222
217
 
223
- Raises:
224
- TypeError: If config_object is not a BaseMcpConfig subclass instance.
218
+ def remove_config(self, server_id: str) -> bool:
225
219
  """
226
- if not isinstance(config_object, BaseMcpConfig):
227
- raise TypeError(f"Unsupported input type for add_config: {type(config_object)}. "
228
- "Expected a BaseMcpConfig subclass object (e.g., StdioMcpServerConfig).")
220
+ Removes an MCP server configuration by its unique server ID.
229
221
 
230
- logger.debug(f"Attempting to add provided {type(config_object).__name__} object with server_id: '{config_object.server_id}'.")
231
-
232
- if config_object.server_id in self._configs:
233
- logger.warning(f"Overwriting existing MCP config with server_id '{config_object.server_id}'.")
234
-
235
- self._configs[config_object.server_id] = config_object
236
- logger.info(f"Successfully added/updated {type(config_object).__name__} for server_id '{config_object.server_id}'. "
237
- f"Total unique configs stored: {len(self._configs)}.")
238
- return config_object
239
-
240
- def get_config(self, server_id: str) -> Optional[BaseMcpConfig]:
241
- """
242
- Retrieves an MCP server configuration by its unique server ID.
243
222
  Args:
244
- server_id: The unique ID of the MCP server configuration.
223
+ server_id: The unique ID of the MCP server configuration to remove.
224
+
245
225
  Returns:
246
- The McpServerConfig object (subclass of BaseMcpConfig) if found, otherwise None.
226
+ True if a configuration was found and removed, False otherwise.
247
227
  """
248
- config = self._configs.get(server_id)
249
- if not config:
250
- logger.debug(f"McpServerConfig not found for server_id: '{server_id}'.")
251
- return config
252
-
253
- def get_all_configs(self) -> List[BaseMcpConfig]:
254
- return list(self._configs.values())
228
+ if server_id in self._configs:
229
+ del self._configs[server_id]
230
+ logger.info(f"Successfully removed MCP config for server_id '{server_id}'.")
231
+ return True
232
+ logger.warning(f"Attempted to remove MCP config for server_id '{server_id}', but it was not found.")
233
+ return False
255
234
 
256
235
  def clear_configs(self) -> None:
257
236
  self._configs.clear()