Platform Management Server Implementation Details

The ThreatExploit FastMCP server acts as a bridge between your environment and the underlying ThreatWinds and Studio APIs. This page covers the server's configuration, authentication handling, and its automated logic for discovering and routing requests to the correct pt-agent.

Configuration

The server relies on environment variables for its configuration. By default, it attempts to load these from a .env file located in the same directory as the server script.

VariableDefault ValueDescription
STUDIO_API_URLhttps://studio.dev.threatexploit.aiThe base URL for the Studio API.
THREATWINDS_API_URLhttps://apis.dev.threatwinds.com/apiThe base URL for the ThreatWinds API.
BEARER_TOKEN(Empty)Your authentication token for API requests.
PT_AGENT_PORT9741The port used to communicate with the pt-agent.

Never commit your .env file or hardcode your BEARER_TOKEN into your source code. Always use secure secret management practices.

Authentication and Routing

When the FastMCP server communicates with upstream services, it automatically injects the necessary headers to authenticate and route your requests.

  • Standard Requests: All requests include an Authorization: Bearer <TOKEN> header and set the Content-Type to application/json.

  • Studio API Requests: Requests directed to the Studio API require an additional X-Target-Server header. This header tells the Studio API exactly which internal pt-agent should process the request.

def _studio_headers(target_server: str) -> dict:
    h = _headers()
    h["X-Target-Server"] = target_server
    return h

Target Discovery Logic

To populate the X-Target-Server header, the server must locate a running pt-agent instance. It does this automatically using the _ensure_target() process, which queries the ThreatWinds compute API to find or provision resources.

Discovery Flow

flowchart TD
    Start[Request Target Server] --> Cache{Is target cached?}
    Cache -->|Yes| Return[Return cached IP:Port]
    Cache -->|No| API[Query /compute/v1/instances]
    
    API --> CheckRunning{Running instance found?}
    CheckRunning -->|Yes| Extract["Extract internalIp"]
    Extract --> UpdateCache[Update cache]
    UpdateCache --> Return
    
    CheckRunning -->|No| CheckTerminated{Terminated instance found?}
    CheckTerminated -->|Yes| StartInstance["Send POST to start instance"]
    StartInstance --> Wait[Wait for startup]
    CheckTerminated -->|No| Error[Raise RuntimeError]

How it works

When a request requires a target server, the FastMCP server follows these steps:

  1. 1

    Check the cache

    To minimize API calls and latency, the server first checks if a target server is already cached in memory (_cached_target_server). If it is, it uses that address immediately.

  2. 2

    Query compute instances

    If the cache is empty, the server sends a GET request to the ThreatWinds API (/compute/v1/instances) to retrieve a list of all available compute instances.

  3. 3

    Locate a running instance

    The server filters the list for instances with a status of RUNNING that possess an internalIp. If one is found, it combines the internal IP with the PT_AGENT_PORT (e.g., 10.0.0.5:9741), caches it for future requests, and uses it as the target.

  4. 4

    Start a terminated instance (Fallback)

    If no running instances are found, the server looks for instances with a status of TERMINATED. If one exists, the server automatically sends a POST request to start the instance, ensuring resources are spun up on-demand.

The automatic startup of terminated instances helps optimize resource costs by allowing pt-agents to remain offline when not in active use, only spinning up when a request is made.