MKS DevEnv

Agent Backend API

REST API for managing workspaces programmatically with AI agent integration

Agent Backend API

The @mks-devenv/agent-backend provides a REST API for managing development workspaces programmatically, with real-time communication via WebSocket and SSE.

Overview

The agent-backend bridges the DevEnv system with AI agents, enabling:

  • Workspace Management: Create, list, and destroy workspaces via HTTP
  • Real-time Communication: WebSocket and SSE for streaming logs and events
  • Bot Integration: Integration with @mks2508/bot-manager-agent for Claude SDK

Running the Server

# From monorepo root
bun run agent-backend

# Or from apps/devenv-agent-backend
bun run dev

Default port: 3100

API Endpoints

Workspaces

List Workspaces

GET /api/workspaces

Response:

{
  "success": true,
  "data": [
    {
      "id": "ws-abc123",
      "name": "myproject",
      "status": "running",
      "type": "persistent",
      "codeServerPort": 8443,
      "createdAt": "2024-01-15T10:30:00Z"
    }
  ]
}

Get Workspace

GET /api/workspaces/:id

Response:

{
  "success": true,
  "data": {
    "id": "ws-abc123",
    "name": "myproject",
    "status": "running",
    "type": "persistent",
    "codeServerPort": 8443,
    "containerId": "abc123def456",
    "createdAt": "2024-01-15T10:30:00Z",
    "resources": {
      "cpuPercent": 12.5,
      "memoryUsage": 512000000,
      "memoryLimit": 4294967296
    }
  }
}

Create Workspace

POST /api/workspaces
Content-Type: application/json

{
  "name": "myproject",
  "template": "bun-typescript",
  "type": "persistent"
}

Parameters:

FieldTypeRequiredDescription
namestringYesWorkspace name
templatestringNoTemplate type (default: bun-typescript)
typestringNopersistent, temporary, or agent
gitUrlstringNoRepository URL to clone
gitBranchstringNoBranch to checkout

Response:

{
  "success": true,
  "data": {
    "id": "ws-abc123",
    "name": "myproject",
    "status": "creating",
    "codeServerPort": 8443
  }
}

Delete Workspace

DELETE /api/workspaces/:id

This permanently removes the workspace container and all associated data.

Agent Sessions

Execute Agent Task

POST /api/agent/execute
Content-Type: application/json

{
  "workspaceId": "ws-abc123",
  "task": "Create a simple HTTP server with Bun",
  "sessionId": "session-xyz"
}

Response (streaming via SSE):

{
  "type": "progress",
  "data": {
    "step": 1,
    "total": 3,
    "message": "Creating index.ts..."
  }
}

Real-time Communication

WebSocket

Connect to WebSocket for bidirectional communication:

const ws = new WebSocket('ws://localhost:3100/agent/ws');

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'subscribe',
    workspaceId: 'ws-abc123'
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Event:', message.type, message.data);
};

Message Types:

TypeDirectionDescription
subscribeClient → ServerSubscribe to workspace events
unsubscribeClient → ServerUnsubscribe from events
logServer → ClientContainer log output
statusServer → ClientWorkspace status change
progressServer → ClientTask progress update
errorServer → ClientError notification

Server-Sent Events (SSE)

For unidirectional streaming:

const eventSource = new EventSource(
  'http://localhost:3100/agent/sse/session-xyz'
);

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Event:', data);
};

eventSource.onerror = (error) => {
  console.error('SSE Error:', error);
  eventSource.close();
};

Workspace Types

TypeDescriptionPersistence
persistentLong-lived workspaceData persists across restarts
temporaryShort-lived workspaceDeleted on stop
agentAI agent workspaceConfigurable TTL

Port Allocation

The agent-backend automatically allocates ports from a pool:

  • Code-Server: 8443-8550
  • SSH: 2223-2250
  • Custom: Configurable range
// Example workspace with allocated ports
{
  "id": "ws-abc123",
  "codeServerPort": 8445,  // Auto-allocated
  "sshPort": 2225          // Auto-allocated
}

Integration Examples

React Frontend

import { useState, useEffect } from 'react';

function WorkspaceStatus({ workspaceId }: { workspaceId: string }) {
  const [status, setStatus] = useState<string>('loading');

  useEffect(() => {
    const ws = new WebSocket(`ws://localhost:3100/agent/ws`);

    ws.onopen = () => {
      ws.send(JSON.stringify({
        type: 'subscribe',
        workspaceId
      }));
    };

    ws.onmessage = (event) => {
      const msg = JSON.parse(event.data);
      if (msg.type === 'status') {
        setStatus(msg.data.status);
      }
    };

    return () => ws.close();
  }, [workspaceId]);

  return <span>Status: {status}</span>;
}

Node.js Client

import { fetch } from 'bun';

async function createWorkspace(name: string) {
  const response = await fetch('http://localhost:3100/api/workspaces', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name,
      template: 'bun-typescript',
      type: 'persistent'
    })
  });

  return response.json();
}

async function listWorkspaces() {
  const response = await fetch('http://localhost:3100/api/workspaces');
  return response.json();
}

Error Handling

All endpoints return consistent error responses:

{
  "success": false,
  "error": "Workspace not found",
  "code": "WORKSPACE_NOT_FOUND"
}

Error Codes:

CodeDescription
WORKSPACE_NOT_FOUNDWorkspace does not exist
WORKSPACE_ALREADY_EXISTSName conflict
DOCKER_ERRORDocker operation failed
VALIDATION_ERRORInvalid request body
PORT_EXHAUSTEDNo available ports

OpenAPI Documentation

Interactive API documentation is available at:

http://localhost:3100/openapi

This provides a Scalar UI for exploring and testing all endpoints.

Health Check

GET /health

Response:

{
  "status": "healthy",
  "version": "1.0.0",
  "uptime": 3600,
  "docker": "connected"
}

Configuration

Environment variables:

VariableDefaultDescription
PORT3100Server port
DOCKER_HOST-Docker socket path
WORKSPACE_BASE_PATH/workspaceBase path for workspaces
LOG_LEVELinfoLogging level

Actions

On this page