feat: Add MCP integration to enable tools from skills.sh and other MCP servers

- Added MCP client to discover and convert MCP tools to LangChain Tools
- Extended configuration manager to support MCP server configurations
- Updated CLI to manage MCP server configurations (list, add, remove, use)
- Integrated MCP tools into the agent's tool loading system
- Added documentation for MCP integration design
This commit is contained in:
opencode committed 2026-03-21 19:01:58 +01:00
1 parent 55a31278a8
commit 753c7d491e
5 files changed
+380 -11

No files matched your search

+38 -9
View File
@@ -115,14 +115,14 @@ class ConfigManager:
# Create a deep copy to avoid modifying original
result = copy.deepcopy(config)
# Decrypt configurations
if "configurations" in result and isinstance(result["configurations"], dict):
for name, config_data in result["configurations"].items():
if isinstance(config_data, dict):
# Decrypt API keys for relevant providers
provider = config_data.get("provider", "").lower()
if provider in ["openai", "openrouter"] and "api_key" in config_data:
config_data["api_key"] = self._decrypt_data(config_data["api_key"])
# Decrypt configurations
if "configurations" in result and isinstance(result["configurations"], dict):
for name, config_data in result["configurations"].items():
if isinstance(config_data, dict):
# Decrypt API keys for relevant providers
provider = config_data.get("provider", "").lower()
if provider in ["openai", "openrouter", "mcp"] and "api_key" in config_data:
config_data["api_key"] = self._decrypt_data(config_data["api_key"])
return result
@@ -207,7 +207,7 @@ class ConfigManager:
# Validate provider
provider = config.get("provider", "").lower()
valid_providers = ["openai", "ollama", "openrouter"]
valid_providers = ["openai", "ollama", "openrouter", "mcp"]
if not provider:
errors.append("Provider is required")
@@ -262,6 +262,35 @@ class ConfigManager:
if base_url.endswith("/"):
config["base_url"] = base_url.rstrip("/")
elif provider == "mcp":
server_url = config.get("server_url", "").strip()
if not server_url:
errors.append("Server URL is required for MCP provider")
else:
if not server_url.startswith(("http://", "https://")):
errors.append("MCP server URL must start with http:// or https://")
else:
# Remove trailing slash for consistency
if server_url.endswith("/"):
config["server_url"] = server_url.rstrip("/")
# API key is optional for MCP (some servers might not require auth)
api_key = config.get("api_key", "").strip()
if api_key and len(api_key) < 10:
errors.append("MCP API key appears too short if provided")
# Timeout is optional, but if provided must be positive integer
timeout = config.get("timeout")
if timeout is not None:
try:
timeout_int = int(timeout)
if timeout_int <= 0:
errors.append("MCP timeout must be a positive integer")
else:
config["timeout"] = timeout_int
except ValueError:
errors.append("MCP timeout must be a valid integer")
return len(errors) == 0, errors
def get_configurations(self) -> Dict[str, Any]: