Skip to content

HTTP+SSE Transport for aimdb-mcp #67

@lxsaah

Description

@lxsaah

Summary

Add HTTP transport support to aimdb-mcp alongside the existing stdio transport, enabling web servers and browsers to interact with AimDB instances via the MCP protocol.

Motivation

Currently aimdb-mcp only supports stdio transport, which works great for IDE integration (VS Code, Claude Desktop). However, there are valid use cases for accessing MCP tools over HTTP:

  1. Web applications - Browser-based dashboards that want to query AimDB via MCP tools
  2. HTTP gateways - Servers that aggregate data from AimDB and serve it to web clients
  3. Remote access - Accessing MCP tools from machines where the AimDB instance isn't local
  4. Microservices - Using MCP as the API layer between services

Concrete Use Case

I'm building an aggregation server (aimdb-server) that:

  • Collects sensor data from distributed AimDB nodes via MQTT
  • Serves a web UI with real-time WebSocket updates
  • Provides a chat interface where users can query the mesh

Currently I have a custom agent implementation with hand-written context building. Using aimdb-mcp tools would give me:

  • list_records with full metadata
  • get_record for current values
  • query_schema for type information
  • Consistent behavior with IDE-based MCP access

But I can't use it because my server communicates over HTTP, not stdio.

Proposed Solution

Add an optional HTTP+SSE transport per the MCP specification:

# Existing (default)
aimdb-mcp --transport stdio

# New
aimdb-mcp --transport http --port 3001

HTTP Transport Behavior

Endpoint Method Purpose
/mcp POST JSON-RPC 2.0 requests (initialize, tools/call, etc.)
/mcp/sse GET Server-Sent Events for notifications/subscriptions
/health GET Health check endpoint

Example Request/Response

curl -X POST http://localhost:3001/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_records",
      "arguments": {"socket_path": "/tmp/aimdb-demo.sock"}
    }
  }'
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{"type": "text", "text": "..."}],
    "isError": false
  }
}

Implementation Notes

Minimal Changes Required

The McpServer struct already handles protocol logic independent of transport:

  • handle_initialize()
  • handle_tools_list()
  • handle_tools_call()
  • etc.

Only a new transport layer is needed:

// src/transport/http.rs (new)
pub struct HttpTransport {
    port: u16,
}

impl HttpTransport {
    pub async fn run(self, server: McpServer) -> Result<()> {
        let app = Router::new()
            .route("/mcp", post(handle_mcp_request))
            .route("/mcp/sse", get(handle_sse))
            .route("/health", get(|| async { "OK" }))
            .with_state(Arc::new(server));
        
        axum::serve(listener, app).await
    }
}

Dependencies

Would add (behind feature flag):

[dependencies]
axum = { version = "0.7", optional = true }
tokio = { version = "1", features = ["net"], optional = true }

[features]
default = []
http = ["axum", "tokio/net"]

Alternatives Considered

  1. Proxy stdio↔HTTP in user code - Works but adds complexity and latency
  2. Use aimdb-client directly - Loses MCP tool abstractions (schema inference, metadata)
  3. Embed aimdb-mcp as library - Global state issues, not designed for embedding

Additional Context

Checklist

  • Add http feature flag
  • Implement HttpTransport struct
  • Add /mcp POST endpoint for JSON-RPC
  • Add /mcp/sse GET endpoint for notifications
  • Add --transport CLI argument
  • Update README with HTTP usage
  • Add integration tests for HTTP transport

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions