# How CyberStrikeAI Handles AI Agent Orchestration for Automated Security Testing

> Discover how CyberStrikeAI orchestrates AI agents using a think act reflect ReAct pattern driving automated security testing and tool execution via a unified MCP interface.

- Repository: [公明/CyberStrikeAI](https://github.com/Ed1s0nZ/CyberStrikeAI)
- Tags: architecture
- Published: 2026-03-09

---

**CyberStrikeAI implements AI agent orchestration through a closed-loop "think-act-reflect" ReAct pattern, where a central Agent struct drives iterative tool execution while dynamically federating internal and external security capabilities via a unified MCP interface.**

CyberStrikeAI's architecture centers on an AI-native orchestration engine that transforms natural language security commands into multi-step penetration testing workflows. The system, available in the `Ed1s0nZ/CyberStrikeAI` repository, combines a Go-based agent core with a Model Context Protocol (MCP) server infrastructure to coordinate both built-in and third-party security tools. Understanding how this AI agent orchestration system works reveals a production-ready implementation of the ReAct (Reasoning and Acting) paradigm optimized for cybersecurity automation.

## Core Orchestration Architecture

The orchestration engine revolves around the **Agent** struct defined in [`internal/agent/agent.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/agent/agent.go) (lines 22-38). This struct maintains the complete state required for autonomous operation:

- LLM client configuration and API credentials
- System prompts defining the security testing persona
- Tool mapping for both internal and external capabilities
- Conversation state and message history
- Progress callbacks for real-time UI updates

The Agent exposes two primary entry points for orchestration: `AgentLoop` for synchronous execution and `AgentLoopWithProgress` for streaming operations. Both methods implement the same underlying ReAct cycle but differ in how they communicate interim steps to callers.

### The MCP Server Foundation

At the infrastructure layer, [`internal/mcp/server.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/mcp/server.go) provides the tool registry via the `RegisterTool` method (lines 80-86). This server maintains an internal map of available security tools and exposes JSON-RPC-like endpoints for `tools/list` and `tools/call` operations. When the Agent needs to execute a capability, it queries this server or delegates to external federated servers.

## The ReAct Orchestration Loop

The heart of CyberStrikeAI's AI agent orchestration lives in `AgentLoopWithProgress` at [`internal/agent/agent.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/agent/agent.go) (lines 314-388). This method implements a deterministic finite-state machine that iterates up to `maxIterations` (defaulting to 30) to complete complex security tasks.

### Iteration Cycle Details

Each loop iteration follows a strict protocol:

1. **Memory Compression** – Before each LLM call, `applyMemoryCompression` trims historical messages while reserving token budget for the current tool list, preventing context window overflow during long penetration testing sessions.

2. **Tool Discovery** – The Agent calls `getAvailableTools` (lines 891-934), which merges:
   - Internal tools from `mcpServer.GetAllTools()`
   - External tools from `externalMCPMgr.GetAllTools()` (lines 70-80 in [`internal/mcp/external_manager.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/mcp/external_manager.go))

3. **LLM Decision** – Via `callOpenAI` with exponential backoff, the system transmits the compressed history and available tool schema. The model returns either a completion text or a structured `tool_calls` array.

4. **Tool Execution** – For each tool invocation detected:
   - **Internal tools**: Direct invocation through `mcpServer.CallTool`
   - **External tools**: The Agent parses the `mcpName::toolName` syntax, resolves the mapping through `toolNameMapping`, and forwards to `externalMCPMgr.CallTool`

5. **Result Integration** – Tool outputs (including errors) are wrapped in `tool` role messages and appended to the conversation history, feeding the next reasoning cycle.

6. **Progress Streaming** – Throughout execution, `sendProgress` emits SSE events indicating "thinking", "tool_calls_detected", "tool_result", or final summarization states.

### Termination and Summarization

When the LLM returns a non-tool response or the iteration limit approaches, the Agent forces a final summarization request by injecting a user message requesting a summary. This ensures the `AgentLoopResult.Response` contains a coherent answer rather than raw tool output.

## Federating External Security Tools

CyberStrikeAI extends its orchestration capabilities beyond built-in tools through the **External MCP Manager** ([`internal/mcp/external_manager.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/mcp/external_manager.go)). This component enables federation with third-party MCP servers using HTTP, stdio, or Server-Sent Events (SSE) transports.

### External Tool Integration

When `ExternalMCPManager.StartAllEnabled()` initializes, it creates lazy clients for each configured external server, caching tool lists with a 10-second refresh interval. The Agent consumes these through a unified interface:

- External tools appear as `mcpName::toolName` in the available tools list
- The `getAvailableTools` method rewrites these identifiers to OpenAI-compatible function names before transmission to the LLM
- Execution automatically routes through the appropriate client based on the prefix

```go
// Example: Calling the Agent with external tool federation
import (
    "context"
    "cyberstrike-ai/internal/agent"
    "cyberstrike-ai/internal/config"
    "go.uber.org/zap"
)

logger, _ := zap.NewProduction()
a := agent.NewAgent(cfg.OpenAI, cfg.Agent, mcpServer, externalMCPMgr, logger, 30)

ctx := context.Background()
result, err := a.AgentLoop(ctx, "Scan 192.168.1.1 for open ports", nil)
if err != nil {
    logger.Error("Agent failed", zap.Error(err))
}
fmt.Println("Final answer:", result.Response)

```

## HTTP API and Real-Time Progress

The orchestration engine exposes three critical endpoints through [`internal/handler/agent.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/handler/agent.go):

- **POST `/agent-loop`** – Synchronous execution via `AgentHandler.AgentLoop` (lines 251-270)
- **GET `/agent-loop/stream`** – Server-Sent Events stream via `AgentLoopStream` (lines 646-667)
- **POST `/agent-loop/cancel`** – Graceful termination through context cancellation

The streaming endpoint enables real-time visualization of the security testing workflow, allowing UI components to display the Agent's "thinking" phases, individual tool invocations, and incremental results as they occur.

### HTTP Invocation Example

```bash
curl -X POST http://localhost:8080/api/agent-loop \
  -H "Authorization: Bearer <token>" \
  -d '{
        "userInput":"Enumerate subdomains of example.com then run nuclei",
        "conversationId":"c123",
        "role":"penetration-testing"
      }'

```

This request triggers the full orchestration pipeline: message preparation, iterative ReAct execution, and final summarization.

## Memory Management and Large Result Handling

Production security tools often generate substantial output (scan results, packet captures, log files). CyberStrikeAI handles this through **ResultStorage** integration within `executeToolViaMCP`.

When a tool returns more than 50KB of data, the system automatically:
1. Persists the full result to file storage via `ResultStorage.SaveResult`
2. Returns a minimal notification to the LLM containing a reference ID and summary
3. Prevents prompt token exhaustion while maintaining result accessibility

This mechanism ensures that orchestration can continue through multi-tool chains involving large vulnerability scans or network reconnaissance without hitting context limits.

## Extending the Orchestration System

The architecture supports two primary extension patterns:

### Adding Internal Tools

Drop a YAML recipe into the `tools/` directory. The initialization code in [`cmd/server/main.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/cmd/server/main.go) automatically calls `RegisterTool` during server startup, making the capability available to the Agent without code changes.

### Federating Remote MCP Servers

Configure external capabilities in [`config.yaml`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/config.yaml):

```yaml
mcp:
  external:
    burp-mcp:
      transport: http
      url: "http://127.0.0.1:9000/mcp"
      timeout: 30
      externalMCPEnable: true

```

The `ExternalMCPManager` lazy-loads these clients, retrieves tool schemas, and exposes them as `burp-mcp::scan` within the orchestration loop.

## Summary

- **CyberStrikeAI implements AI agent orchestration** through a Go-based Agent struct that maintains LLM state, tool mappings, and conversation history in [`internal/agent/agent.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/agent/agent.go).
- **The ReAct loop** in `AgentLoopWithProgress` drives iterative reasoning for up to 30 iterations, compressing memory and handling tool calls at each step.
- **Tool federation** unifies internal MCP server tools and external third-party servers through `ExternalMCPManager`, using the `mcpName::toolName` naming convention.
- **Real-time progress** streams via SSE endpoints in [`internal/handler/agent.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/handler/agent.go), enabling UI visualization of the security testing workflow.
- **Result management** automatically offloads outputs exceeding 50KB to storage, keeping LLM prompts concise while preserving data accessibility.
- **Extensibility** supports YAML-defined internal tools and configuration-driven external MCP federation without core code modification.

## Frequently Asked Questions

### How does CyberStrikeAI prevent context window overflow during long security scans?

The system implements **memory compression** via `applyMemoryCompression` at the start of each ReAct iteration. This method trims historical messages while preserving critical conversation state and reserving token space for the current tool list. Additionally, the **ResultStorage** mechanism automatically offloads large tool outputs (>50KB) to file storage, returning only concise notifications to the LLM.

### What is the difference between internal and external tools in the orchestration system?

**Internal tools** are registered directly with the MCP server in [`internal/mcp/server.go`](https://github.com/Ed1s0nZ/CyberStrikeAI/blob/main/internal/mcp/server.go) and execute within the same process space. **External tools** are federated through `ExternalMCPManager` from remote MCP servers (HTTP, stdio, or SSE) and appear to the Agent with the `mcpName::toolName` syntax. The Agent handles both identically in the ReAct loop but routes external calls through the appropriate client connection.

### How can I cancel a running agent orchestration session?

Send a POST request to `/agent-loop/cancel` with the conversation ID. This sets a cancellation flag on the context, which the Agent checks at the start of each iteration in `AgentLoopWithProgress`. Upon detection, the Agent saves the current ReAct input state and exits gracefully, returning the partial results accumulated up to that point.

### What happens when the LLM returns a tool call versus a final answer?

If the LLM returns **tool calls** (the `tool_calls` array), the Agent executes each tool via `executeToolViaMCP`, records the results as `tool` role messages, and continues to the next iteration. If the LLM returns **plain text**, or when approaching the `maxIterations` limit, the Agent forces a final summarization request to ensure the `AgentLoopResult.Response` contains a coherent, user-facing answer rather than raw intermediate outputs.