Skip to main content

Architecture Deep Dive

This document provides detailed architecture diagrams showing how Station’s services, APIs, and components interact.

High-Level System Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                          STATION PLATFORM                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  │
│  │   CLI Layer      │    │   API Server     │    │  MCP Server      │  │
│  │  (cmd/main)      │    │   (:8585)        │    │  (stdio)         │  │
│  │                  │    │                  │    │                  │  │
│  │ • agent          │    │ • /api/v1/agents │    │ • Tool handlers  │  │
│  │ • bundle         │    │ • /api/v1/envs   │    │ • Agent handlers │  │
│  │ • env            │    │ • /api/v1/runs   │    │ • Resources      │  │
│  │ • sync           │    │ • /api/v1/mcp    │    │ • Tool Discovery │  │
│  │ • runs           │    │ • /api/v1/tools  │    │ • Prompts        │  │
│  └────────┬─────────┘    └────────┬─────────┘    └────────┬─────────┘  │
│           │                       │                        │             │
│           └───────────────────────┼────────────────────────┘             │
│                                   │                                      │
│                        ┌──────────▼──────────┐                          │
│                        │   Service Layer     │                          │
│                        │  (internal/services)│                          │
│                        └──────────┬──────────┘                          │
│                                   │                                      │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                     Environment System                            │   │
│  │  ~/.config/station/environments/<env>/                           │   │
│  │  ├── template.json       (MCP Server definitions)                │   │
│  │  ├── variables.yml       (Template variables)                    │   │
│  │  └── agents/             (Agent .prompt files)                   │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │         External Integration Layer                                │   │
│  │  • GenKit AI Models (OpenAI, Gemini, Ollama)                     │   │
│  │  • MCP Server Processes (filesystem, custom tools)               │   │
│  │  • Lighthouse (CloudShip data ingestion & telemetry)             │   │
│  │  • OpenTelemetry (Tracing & metrics)                             │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Agent Execution Flow

All entry points converge at the AgentExecutionEngine:
┌──────────────────────────────────────────────────────────────────────┐
│                     AGENT EXECUTION PATHS                             │
└──────────────────────────────────────────────────────────────────────┘

CLI PATH: stn agent run <name> <task>
═══════════════════════════════════════════════════════════════════════

  cmd/main/handlers/agent/execution.go
  └─ RunAgentLocal()

     ├─ Load config
     ├─ Open database connection
     └─ Call: agentExecutionEngine.ExecuteWithOptions()


API PATH: POST /api/v1/agents/:id/execute
═══════════════════════════════════════════════════════════════════════

  internal/api/v1/agents.go
  └─ executeAgent() handler

     ├─ Validate authentication
     ├─ Parse task from request body
     └─ Call: agentService.ExecuteAgent()


MCP SERVER PATH: call_agent tool
═══════════════════════════════════════════════════════════════════════

  internal/mcp/execution_handlers.go
  └─ handleMCPAgentRun()

     ├─ Parse MCP tool call arguments
     ├─ Create AgentRun database entry
     └─ Call: agentService.ExecuteAgentWithRunID()


SCHEDULER PATH: Cron-triggered execution
═══════════════════════════════════════════════════════════════════════

  internal/services/scheduler.go
  └─ SchedulerService.Start()

     ├─ Load scheduled agents from database
     └─ At cron trigger:
        └─ Call: agentService.ExecuteAgent()

AgentExecutionEngine Internals

The core execution engine orchestrates the full agent lifecycle:
┌─ AgentExecutionEngine Key Responsibilities ─────────────────────────┐
│                                                                      │
│ File: /internal/services/agent_execution_engine.go                 │
│                                                                      │
│ 1. Agent Validation & Loading                                      │
│    • Fetch agent from database                                     │
│    • Validate agent exists and is configured                       │
│    • Get environment and tool assignments                          │
│                                                                      │
│ 2. Environment Setup                                               │
│    • Load environment configuration                                │
│    • Load variables.yml for template processing                    │
│    • Validate environment exists                                   │
│                                                                      │
│ 3. AI Model Configuration                                          │
│    • Initialize GenKit with configured provider                    │
│    • Set up model-specific parameters                              │
│    • Handle model fallbacks if needed                              │
│                                                                      │
│ 4. MCP Server Connection                                           │
│    • Create MCPConnectionManager instance                          │
│    • Connect to each MCP server in environment                     │
│    • Discover available tools per server                           │
│    • Cache tools for performance                                   │
│                                                                      │
│ 5. Tool Preparation                                                │
│    • Build complete tool list from all servers                     │
│    • Apply agent-specific tool assignments                         │
│    • Filter tools based on permissions                             │
│                                                                      │
│ 6. Execution                                                       │
│    • Render dotprompt template with variables                      │
│    • Pass task + tools to GenKit                                   │
│    • Process iterative tool calls                                  │
│    • Enforce max steps limit                                       │
│                                                                      │
│ 7. Metadata Capture                                                │
│    • Record all tool calls with parameters                         │
│    • Capture execution steps                                       │
│    • Track token usage (input/output)                              │
│    • Measure execution duration                                    │
│                                                                      │
│ 8. Lighthouse Integration (Optional)                               │
│    • Send run data to Lighthouse                                   │
│    • Include app/app_type classification                           │
│    • Enable CloudShip data ingestion                               │
│                                                                      │
│ 9. Cleanup                                                         │
│    • Close all MCP connections                                     │
│    • Release resources                                             │
│    • Stop any running processes                                    │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

Service Layer Architecture

Station’s service layer contains 43+ focused modules:
┌─────────────────────────────────────────────────────────────────────┐
│                      CORE SERVICES LAYER                             │
│          /internal/services/ - 43 focused modules                    │
└─────────────────────────────────────────────────────────────────────┘

AGENT EXECUTION SERVICES
═════════════════════════════════════════════════════════════════════

  AgentService (agent_service_impl.go)
  ├─ Creates/manages AgentExecutionEngine
  ├─ Wraps execution with telemetry
  ├─ Interface: AgentServiceInterface
  └─ Methods:
     ├─ ExecuteAgent(agentID, task, variables) → Message
     ├─ ExecuteAgentWithRunID(agentID, task, runID, variables)
     ├─ CreateAgent(config) → Agent
     ├─ UpdateAgent(agentID, config) → Agent
     └─ DeleteAgent(agentID)

  AgentExecutionEngine (agent_execution_engine.go)
  ├─ Main execution orchestrator
  ├─ Manages GenKit + MCP lifecycle
  └─ Methods:
     ├─ Execute(agent, task, runID, userVars)
     └─ ExecuteWithOptions(agent, task, runID, userVars, opts)

  GenKitProvider (genkit_provider.go)
  ├─ AI model provider initialization
  ├─ Supports: OpenAI, Gemini, Ollama
  └─ Methods:
     └─ InitializeGenKit() → *genkit.Genkit


MCP MANAGEMENT SERVICES
═════════════════════════════════════════════════════════════════════

  MCPConnectionManager (mcp_connection_manager.go)
  ├─ Lifecycle management for MCP connections
  ├─ Tool discovery and caching
  └─ Methods:
     ├─ DiscoverTools(envID, genkitApp)
     ├─ GetCachedTools(envID)
     └─ CleanupConnections(clients)

  MCPToolDiscovery (mcp_tool_discovery.go)
  ├─ Discovers tools from MCP servers
  ├─ Maps tools to servers
  └─ Methods:
     ├─ DiscoverToolsPerServer(fileConfig)
     └─ SaveToolsForServer(envID, serverName, tools)

  ToolDiscoveryService (tool_discovery_service.go)
  ├─ High-level tool discovery orchestration
  └─ Methods:
     ├─ DiscoverTools(envID) → []Tool
     └─ RefreshTools(envID)


ENVIRONMENT & CONFIGURATION SERVICES
═════════════════════════════════════════════════════════════════════

  EnvironmentManagementService (environment_management_service.go)
  ├─ Environment CRUD operations
  ├─ File-based configuration management
  └─ Methods:
     ├─ CreateEnvironment(name, description)
     ├─ DeleteEnvironment(name)
     └─ GetEnvironmentFileConfig(name)

  DeclarativeSync (declarative_sync.go)
  ├─ Synchronizes file-based configs to database
  ├─ Bidirectional sync (files ↔ database)
  ├─ Template variable processing
  └─ Methods:
     ├─ SyncEnvironment(ctx, envName, options)
     ├─ SyncAgents(ctx, envID)
     └─ SyncMCPServers(ctx, envID)


SCHEDULING & AUTOMATION
═════════════════════════════════════════════════════════════════════

  SchedulerService (scheduler.go)
  ├─ Cron-based agent scheduling (6-field cron)
  ├─ Persistent schedule storage
  └─ Methods:
     ├─ Start() - loads and activates schedules
     ├─ Stop() - graceful shutdown
     └─ ScheduleAgent(agentID, cronExpression)


TELEMETRY & MONITORING
═════════════════════════════════════════════════════════════════════

  TelemetryService (telemetry_service.go)
  ├─ OpenTelemetry integration
  ├─ Span creation and tracking
  └─ Methods:
     ├─ Initialize(ctx)
     └─ CreateSpan(ctx, name, attributes)

MCP Server Architecture

┌──────────────────────────────────────────────────────────────────────┐
│                    MCP SERVER SUBSYSTEM                               │
│          /internal/mcp/ - Model Context Protocol                      │
└──────────────────────────────────────────────────────────────────────┘

CORE MCP SERVER
═══════════════════════════════════════════════════════════════════════

  MCP Server (mcp/server.go)
  └─ Main MCP server instance

     ├─ Capabilities:
     │  ├─ Tools (tool discovery & execution)
     │  ├─ Resources (read-only data access)
     │  ├─ Prompts (system prompts)
     │  └─ Tool suggestions

     └─ Core Components:
        ├─ mcpServer: *server.MCPServer (mark3labs/mcp-go)
        ├─ httpServer: *server.StreamableHTTPServer
        ├─ toolDiscoverySvc: *ToolDiscoveryService
        ├─ agentService: AgentServiceInterface
        ├─ authService: *auth.AuthService
        └─ repos: *repositories.Repositories


HANDLER ORGANIZATION
═══════════════════════════════════════════════════════════════════════

  /internal/mcp/

  ├─ server.go                  # Main server setup

  ├─ agent_handlers.go          # Agent CRUD tools
  │  ├─ call_agent              # Execute an agent
  │  ├─ list_agents             # List all agents
  │  ├─ get_agent_details       # Get agent info
  │  └─ create_agent            # Create new agent

  ├─ environment_handlers.go    # Environment tools
  │  ├─ list_environments       # List environments
  │  ├─ create_environment      # Create environment
  │  └─ sync_environment        # Sync from files

  ├─ mcp_handlers.go            # MCP server management
  │  ├─ add_mcp_server          # Add MCP server
  │  └─ list_mcp_servers        # List servers

  ├─ tool_handlers.go           # Tool management
  │  ├─ list_tools              # List all tools
  │  ├─ discover_tools          # Trigger discovery
  │  └─ add_tool                # Add tool to agent

  └─ workflow_handlers.go       # Workflow tools
     ├─ create_workflow         # Create workflow
     ├─ start_workflow_run      # Start execution
     └─ get_workflow_run        # Get run status

Database Layer

┌──────────────────────────────────────────────────────────────────────┐
│                     DATABASE LAYER                                    │
│          /internal/db/ - SQLite with Repositories                     │
└──────────────────────────────────────────────────────────────────────┘

REPOSITORY PATTERN
═══════════════════════════════════════════════════════════════════════

  /internal/db/repositories/

  ├─ agent_repository.go         # Agent CRUD
  │  ├─ Create(agent) → id
  │  ├─ GetByID(id) → Agent
  │  ├─ GetByName(name) → Agent
  │  ├─ Update(agent)
  │  └─ Delete(id)

  ├─ agent_run_repository.go     # Execution history
  │  ├─ Create(run) → id
  │  ├─ GetByID(id) → AgentRun
  │  ├─ ListByAgent(agentID) → []AgentRun
  │  └─ UpdateStatus(id, status)

  ├─ environment_repository.go   # Environment CRUD
  │  ├─ Create(env) → id
  │  ├─ GetByName(name) → Environment
  │  └─ List() → []Environment

  ├─ mcp_server_repository.go    # MCP server configs
  │  ├─ Create(server) → id
  │  ├─ GetByEnvironment(envID) → []MCPServer
  │  └─ Delete(id)

  └─ tool_repository.go          # Tool definitions
     ├─ Create(tool) → id
     ├─ GetByServer(serverID) → []Tool
     └─ GetByAgent(agentID) → []Tool


SCHEMA (simplified)
═══════════════════════════════════════════════════════════════════════

  environments
  ├─ id (INTEGER PRIMARY KEY)
  ├─ name (TEXT UNIQUE)
  ├─ description (TEXT)
  └─ created_at (DATETIME)

  agents
  ├─ id (INTEGER PRIMARY KEY)
  ├─ environment_id (FOREIGN KEY)
  ├─ name (TEXT)
  ├─ prompt (TEXT)
  ├─ max_steps (INTEGER)
  └─ created_at (DATETIME)

  agent_runs
  ├─ id (TEXT PRIMARY KEY) -- UUID
  ├─ agent_id (FOREIGN KEY)
  ├─ task (TEXT)
  ├─ status (TEXT)
  ├─ response (TEXT)
  ├─ tool_calls (JSON)
  ├─ tokens_used (INTEGER)
  ├─ duration_ms (INTEGER)
  └─ created_at (DATETIME)

  mcp_servers
  ├─ id (INTEGER PRIMARY KEY)
  ├─ environment_id (FOREIGN KEY)
  ├─ name (TEXT)
  ├─ command (TEXT)
  ├─ args (JSON)
  └─ env_vars (JSON)

  tools
  ├─ id (INTEGER PRIMARY KEY)
  ├─ mcp_server_id (FOREIGN KEY)
  ├─ name (TEXT)
  ├─ description (TEXT)
  └─ input_schema (JSON)

Request Flow Example

Complete flow for stn agent run analyzer "Check logs":
┌─────────────────────────────────────────────────────────────────────┐
│                     REQUEST FLOW EXAMPLE                              │
│          stn agent run analyzer "Check logs"                          │
└─────────────────────────────────────────────────────────────────────┘

1. CLI ENTRY
   cmd/main/main.go
   └─ Parse command: "agent run analyzer 'Check logs'"

2. HANDLER
   cmd/main/handlers/agent/execution.go
   └─ RunAgentLocal()
      ├─ Load config.yaml
      ├─ Open database
      └─ agentService.ExecuteAgent("analyzer", "Check logs")

3. SERVICE LAYER
   internal/services/agent_service_impl.go
   └─ ExecuteAgent()
      ├─ Get agent from database
      ├─ Create AgentRun record (status: "running")
      └─ engine.ExecuteWithOptions(agent, task)

4. EXECUTION ENGINE
   internal/services/agent_execution_engine.go
   └─ ExecuteWithOptions()

      ├─ Load environment config
      ├─ Initialize GenKit (OpenAI/Gemini)

      ├─ MCPConnectionManager.DiscoverTools()
      │  ├─ Connect to MCP servers
      │  ├─ Call listTools on each
      │  └─ Cache tools

      ├─ Build tool list for agent

      └─ GenKit.Generate(prompt + task + tools)

         ├─ AI model processes request
         ├─ Returns tool call: {"name": "grep", "args": {...}}

         └─ Execute tool via MCP
            ├─ Route to correct MCP server
            ├─ Execute grep tool
            └─ Return results to AI

         └─ AI generates final response

5. RESULT CAPTURE
   └─ Update AgentRun
      ├─ status: "completed"
      ├─ response: "Found 3 errors in logs..."
      ├─ tool_calls: [{name: "grep", ...}]
      ├─ tokens_used: 1234
      └─ duration_ms: 5678

6. LIGHTHOUSE (if configured)
   └─ Send run data to CloudShip
      ├─ Include structured output
      └─ Enable platform features

7. OUTPUT
   └─ Print response to terminal

Key Design Decisions

DecisionRationale
Single execution engineAll entry points use the same logic
File-based config + DBGitOps-friendly, yet queryable
MCP for toolsStandard protocol, extensible
GenKit abstractionSwap AI providers easily
6-field cronSecond-level precision for scheduling
SQLite defaultZero-config, portable, cloud-upgradable

Next Steps