How CyberStrikeAI Connects to External MCP Servers: Implementation Guide
CyberStrikeAI connects to external MCP servers through a dedicated External MCP Manager that loads configurations from config.yaml, initializes JSON-RPC 2.0 clients over HTTP/SSE or stdio, and manages tool discovery and execution via the internal/mcp/external_manager.go implementation.
CyberStrikeAI (Ed1s0nZ/CyberStrikeAI) extends its offensive security capabilities by integrating with external Modular Command-Protocol (MCP) servers. Understanding how CyberStrikeAI connects to external MCP servers reveals a robust architecture based on JSON-RPC 2.0 communication, dynamic client management, and runtime tool discovery. The implementation enables seamless discovery and execution of remote tools whether the server speaks over HTTP/SSE or via a local stdio process.
Architecture Overview
The connection architecture centers on the External MCP Manager, implemented in internal/mcp/external_manager.go. This component orchestrates all external server interactions, maintaining separate maps for active clients and server configurations while caching advertised tools for rapid access.
When initialized via NewExternalMCPManager (lines 17-28), the manager prepares empty registries for:
- Clients: Active connections stored as
map[string]ExternalMCPClient - Configs: Server definitions from
config.yamlstored asmap[string]config.ExternalMCPServerConfig - Tool Cache: Local copy of tool definitions advertised by each connected MCP
Configuration and Setup
External MCP servers are defined in the externalMCP section of config.yaml. Each server entry specifies transport type, endpoint address, and enablement status.
Example configuration for HTTP and stdio transports:
externalMCP:
servers:
my-http-mcp:
description: "Remote HTTP MCP"
enable: true
address: "https://mcp.example.com/mcp"
type: "http" # or "stdio"
The LoadConfigs method copies these definitions into the manager's internal configs map during initialization.
Connection Lifecycle
Initializing the Manager
Create a manager instance with structured logging:
mgr := mcp.NewExternalMCPManager(logger) // create manager
if err := mgr.StartClient("my-http-mcp"); err != nil {
logger.Error("failed to start MCP", zap.Error(err))
}
Starting Client Connections
The StartClient method (lines 133-154 in internal/mcp/external_manager.go) initiates connections based on configuration type:
- HTTP Transport: Establishes an SSE (Server-Sent Events) POST connection to the server's
/mcpendpoint - Stdio Transport: Spawns a subprocess and wraps stdin/stdout as an SSE-compatible stream
Both implementations satisfy the ExternalMCPClient interface defined in internal/mcp/types.go. Upon successful connection, the manager updates the ExternalMCPEnable flag for that server configuration.
Message Exchange Protocol
CyberStrikeAI communicates using JSON-RPC 2.0 over newline-delimited streams. The handleMessage routine in internal/mcp/server.go (lines 268-277 and 1172-1177) parses incoming messages, dispatches tool registration calls, and manages bidirectional request/response cycles.
Each line represents a compact JSON-RPC object, enabling efficient stream-based communication for both HTTP/SSE and stdio transports.
Tool Discovery and Execution
Retrieving Available Tools
After connection, GetAllTools (lines 276-435 in internal/mcp/external_manager.go) iterates over all active clients, retrieves each MCP's tool list, and populates the manager's cache. The HTTP handler in internal/handler/external_mcp.go exposes these tools to the CyberStrikeAI UI.
List tools programmatically:
tools, err := mgr.GetAllTools(context.Background())
if err != nil {
log.Fatalf("cannot fetch tools: %v", err)
}
for _, t := range tools {
fmt.Printf("%s :: %s – %s\n", t.MCPName, t.Name, t.Description)
}
Invoking Remote Tools
The CallTool method forwards execution requests to specific external MCPs using the mcpName::toolName identifier format. It returns an execution ID for asynchronous tracking:
result, execID, err := mgr.CallTool(
context.Background(),
"my-http-mcp::port-scan",
map[string]interface{}{"target": "10.0.0.5"},
)
if err != nil {
log.Fatalf("tool call failed: %v", err)
}
fmt.Printf("Execution %s started, result: %+v\n", execID, result)
Core Implementation Files
The external MCP integration spans four critical files in the Ed1s0nZ/CyberStrikeAI repository:
internal/mcp/external_manager.go: Core manager handling config loading, client lifecycle, tool caching (lines 17-28 for initialization, 133-154 for client startup, 276-435 for tool operations)internal/mcp/types.go: Interface definitions forExternalMCPClientand JSON-RPC message structuresinternal/mcp/server.go: SSE connection handling and JSON-RPC message parsing (lines 268-277 and 1172-1177)internal/handler/external_mcp.go: HTTP API surface exposing manager functions to the UI for start/stop operations and tool executionconfig.yaml: User-editable configuration defining external MCP endpoints and transport parameters
Summary
- CyberStrikeAI uses a centralized External MCP Manager to handle all external server connections through
internal/mcp/external_manager.go - Configuration resides in
config.yamlunder theexternalMCP.serverskey, supporting both HTTP/SSE and stdio transports - Connections use JSON-RPC 2.0 over newline-delimited streams, implemented in
internal/mcp/server.go - Tool discovery happens via
GetAllToolswhich caches remote capabilities, whileCallToolexecutes methods usingmcpName::toolNamesyntax - The manager provides lifecycle controls including
StartClient,StopClient, and dynamic config reloading with fallback to cached tool definitions on connection failure
Frequently Asked Questions
What transport protocols does CyberStrikeAI support for external MCP connections?
CyberStrikeAI supports two transport protocols: HTTP/SSE (Server-Sent Events) for remote network connections and stdio (standard input/output) for local subprocess communication. The StartClient method in internal/mcp/external_manager.go automatically selects the appropriate client implementation based on the type field in config.yaml.
Where are external MCP server configurations stored in CyberStrikeAI?
Server configurations are stored in the externalMCP section of config.yaml at the repository root. Each entry under externalMCP.servers defines the server address, transport type (http or stdio), description, and enablement flag. The LoadConfigs method ingests these definitions during manager initialization.
How does CyberStrikeAI handle tool discovery from external MCP servers?
After establishing a connection, the manager calls GetAllTools (lines 276-435 in internal/mcp/external_manager.go) to iterate over all active clients and retrieve their advertised tool lists. These definitions are cached locally and exposed through internal/handler/external_mcp.go for integration with the CyberStrikeAI UI and automation workflows.
What happens if an external MCP server connection fails during tool execution?
The External MCP Manager implements error logging and graceful degradation. If a client connection fails, the manager falls back to cached tool definitions when possible. Individual client failures are isolated—other active MCP connections remain operational, and the manager can reload configurations or restart specific clients without affecting the overall system stability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →