A browser embedable http server running inside an Isolated Web App (IWA) using the Direct Sockets API. TLS, QUIC, and WS are supported.
This project is driven by a vision of decentralized local computing where services run directly on user devices and participate in collaborative networks. Our core motivations include:
- Device Autonomy: Run powerful services directly on your local machine without relying on remote servers
- Privacy by Design: Keep your data and processing local, reducing exposure to external services
- Offline Capability: Maintain full functionality even without internet connectivity
- Resource Efficiency: Leverage local computing power instead of consuming remote resources
- Peer-to-Peer Services: Enable devices to serve content and APIs to other devices in the network
- Distributed Computing: Participate in distributed workloads where each device contributes processing power
- Local Service Discovery: Automatically discover and connect to services running on nearby devices
- Edge Computing: Bring computation closer to where data is generated and consumed
- Direct Device Communication: Bypass traditional client-server models with direct device-to-device communication
- Local API Ecosystems: Create rich local API environments that can operate independently
- Reduced Latency: Eliminate network round-trips by serving content directly from local devices
- Bandwidth Conservation: Reduce internet bandwidth usage by serving content locally
- Community Networks: Enable local communities to create their own service networks
This approach represents a fundamental shift toward user-controlled computing environments where individuals and communities can run their own services, participate in local networks, and maintain sovereignty over their digital infrastructure.
- Chrome browser (version 113+)
- Direct Sockets API support
bun installbun run dev- Open Chrome and navigate to
chrome://flags - Enable the following flags:
#enable-isolated-web-apps#enable-experimental-web-platform-features#unrestricted-usb(if using USB features)
- Restart Chrome
- Navigate to the development server URL (typically
http://localhost:5173) - Click the "Install" button when prompted, or use the browser menu β "Install app"
- Open Chrome Apps (chrome://apps) or find "AppStore" in your applications
- Click to launch the isolated web app
- Click "Start Server" to begin the HTTP/WebSocket server
- Server will be available at
http://localhost:44818
- Click "Open Server Page" to access the built-in test interface
- Or navigate directly to
http://localhost:44818in any browser - Use the interactive test buttons to verify HTTP and WebSocket functionality
- HTTP/1.1 Server: Full HTTP server with support for GET, POST, OPTIONS, and other methods
- WebSocket Server: Real-time bidirectional communication with WebSocket protocol support
- CORS Support: Proper Cross-Origin Resource Sharing headers for web compatibility
- Private Network Access: Handles Chrome's Private Network Access requirements
- TypeScript: Fully typed implementation with Direct Sockets API definitions
- Bun Integration: Built with Bun for modern development experience
The implementations we're using for core protocols:
- MatrixAI js-quic - Pure JavaScript QUIC implementation with HTTP/3 and WebTransport support
- SubTLS - Lightweight TLS 1.3 implementation in TypeScript for browsers and Deno
- Custom HTTP/1.1 Implementation - Built from scratch using Direct Sockets API with full RFC compliance
- Custom WebSocket Implementation - RFC 6455 compliant WebSocket server with frame parsing and connection management
- Claude Opus 4.1 - Advanced AI model for intelligent code generation and system design
- Adam Roach (Mozilla) - API specification and implementation
- Thomas Nattestad (Google) - API design and Chrome integration
- Dominic Farolino (Google) - IWA architecture and standards
- Luai Al-assar (Google) - IWA implementation and tooling
- Alan Cutter (Google) - IWA security and deployment
- Michael B. Jones (Microsoft) - Authentication standards and protocols
- Akshay Kumar (Google) - WebAuthn implementation
- Jeff Hodges (Google) - Security architecture
- J.C. Jones (Mozilla) - Cross-browser compatibility
- Christiaan Brand (Google) - Authentication UX and integration
src/
βββ main.ts # Main IWA application with server UI
βββ server.ts # Demo server implementation
βββ http-server.ts # Core HTTP server class
βββ websocket-server.ts # WebSocket connection handler
βββ direct-sockets.d.ts # TypeScript definitions for Direct Sockets API
βββ service-worker.ts # Service worker for offline support
βββ style.css # Application styles
examples/
βββ test-http.html # Interactive HTML test client
βββ test-client.js # Programmatic test utilities
Clone and install dependencies:
bun install
Start development server:
bun run dev
Build for production:
bun run build
- Open your AppStore IWA in Chrome with Direct Sockets support
- Click the "Start Server" button in the UI
- The server will start on
http://localhost:44818 - Click "Open Server Page" to test the server
GET /- Server homepage with interactive testsGET /api/status- Server status and informationGET /api/time- Current server timePOST /api/echo- Echo back the request bodyWebSocket ws://localhost:44818/ws- WebSocket echo server
The server includes integrated AI and machine learning capabilities for local processing:
POST /api/ai/chat- Local chat completion using embedded language modelsPOST /api/ai/embedding- Generate text embeddings for semantic searchPOST /api/ai/classification- Text classification and sentiment analysisPOST /api/ai/summarization- Document summarization and key point extractionGET /api/ai/models- List available local AI models and their capabilitiesPOST /api/ai/vision- Image analysis and object detection using MediaPipePOST /api/ai/audio- Audio processing and speech recognitionWebSocket ws://localhost:44818/ai-stream- Real-time AI processing with streaming responses
GET /api/ai/models/status- Check model loading status and memory usagePOST /api/ai/models/load- Load specific AI models into memoryPOST /api/ai/models/unload- Unload models to free memoryGET /api/ai/models/benchmark- Performance benchmarks for loaded models
- Local Inference: All AI processing happens locally without sending data to external services
- Model Caching: Intelligent caching of frequently used models for faster response times
- Resource Management: Automatic memory management and model lifecycle handling
- Multi-Modal Support: Text, image, and audio processing capabilities
- Real-time Processing: Streaming responses for interactive AI applications
- Start the server in your IWA
- Click "Open Server Page"
- Use the interactive test buttons
- Open
examples/test-http.htmlin any browser - Use the test buttons to verify functionality
// Load the test utilities// In browser console or include examples/test-client.js// Run all testsawaitIWAServerTests.runAllTests();// Or run individual testsawaitIWAServerTests.testHttpEndpoints();awaitIWAServerTests.testWebSocket();awaitIWAServerTests.testCors();This project includes a built-in MCP server implementation that enables AI models to connect with external tools and data sources using standardized communication protocols.
- HTTP Resumable Transport: Implements MCP specification with resumable HTTP transport
- Session Management: Automatic session creation and cleanup
- JSON-RPC 2.0 Compliance: Full JSON-RPC 2.0 protocol support
- Tool Integration: Connect AI models with MediaPipe, Kotlin.js RAG, and function calling
- Real-time Communication: WebSocket support for streaming AI responses
The MCP server is automatically configured when the AI/ML server initializes. No additional configuration files are required.
// MCP Server Configuration (automatically applied)constmcpConfig={endpoint: '/api/ai/mcp',protocolVersion: '2025-03-26',transport: 'http-resumable',sessionTimeout: 300000,// 5 minutesmaxSessions: 100,features: {tools: true,resources: true,prompts: true,sampling: true}};To connect an MCP client to this server, use the following configuration:
{
"mcpServers": {
"iwa-local-server": {
"command": "curl",
"args": [
"-X", "POST",
"-H", "Content-Type: application/json",
"-H", "x-mcp-session-id: your-session-id",
"http://localhost:44818/api/ai/mcp"
],
"transport": "http"
}
}
}For Claude Desktop integration, add this to your claude_desktop_config.json:
{
"mcpServers": {
"iwa-project-templates": {
"command": "node",
"args": ["-e", "const http = require('http');const options = {hostname: 'localhost',port: 44818,path: '/api/ai/mcp',method: 'POST',headers: { 'Content-Type': 'application/json' }};process.stdin.on('data', (data) => {const req = http.request(options, (res) => {res.on('data', (chunk) => process.stdout.write(chunk));});req.write(data);req.end();});"],
"env": {
"NODE_ENV": "production"
}
}
}
}The server exposes the following tools through the MCP protocol:
get_server_status- Get current server status and capabilitieslist_endpoints- List all available API endpointsget_system_info- Retrieve system information and resource usage
generate_text- Generate text using local language modelsprocess_image- Analyze images using MediaPipe computer visionexecute_rag_query- Perform retrieval-augmented generation queriescall_function- Execute Kotlin.js function callsget_embeddings- Generate text embeddings for semantic search
detect_objects- Object detection in imagesanalyze_pose- Human pose estimationrecognize_gestures- Hand gesture recognitionsegment_image- Image segmentation and masking
curl -X POST http://localhost:44818/api/ai/mcp \
-H "Content-Type: application/json" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": { "tools": {}, "resources": {}, "prompts": {} }, "clientInfo": { "name": "test-client", "version": "1.0.0" } } }'curl -X POST http://localhost:44818/api/ai/mcp \
-H "Content-Type: application/json" \
-H "x-mcp-session-id: your-session-id" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'curl -X POST http://localhost:44818/api/ai/mcp \
-H "Content-Type: application/json" \
-H "x-mcp-session-id: your-session-id" \
-d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "generate_text", "arguments": { "prompt": "Explain quantum computing", "max_tokens": 100 } } }'Sessions are automatically created and managed:
- Session Creation: Automatic on first request or via
x-mcp-session-idheader - Session Timeout: 5 minutes of inactivity
- Session Cleanup: Automatic cleanup every 5 minutes
- Session Persistence: Messages stored for resumability
- Connection Refused: Ensure the IWA server is running on port 44818
- Invalid JSON-RPC: Verify
jsonrpc: "2.0"is included in all requests - Session Expired: Check session timeout and create a new session
- Tool Not Found: Use
tools/listto see available tools
Enable MCP debug logging by setting the debug flag:
// In browser console when server is runninglocalStorage.setItem('mcp-debug','true');// Reload the page to see detailed MCP logsThis implementation follows the official MCP specification:
- Protocol Version: 2025-03-26
- Transport: HTTP with resumable support
- Message Format: JSON-RPC 2.0
- Capabilities: Tools, Resources, Prompts, Sampling
- Error Handling: Standard JSON-RPC error codes
- Session Management: Custom session handling for HTTP transport
For more information about the MCP protocol, visit: https://modelcontextprotocol.io/
The HttpServer class provides a complete HTTP/1.1 server implementation:
import{HttpServer}from'./http-server.js';constserver=newHttpServer({host: '0.0.0.0',port: 44818,onRequest: async(request,response)=>{// Handle HTTP requestsawaitresponse.json({message: 'Hello World!'});},onWebSocket: async(ws)=>{// Handle WebSocket connectionsawaitws.send('Welcome!');}});awaitserver.listen();The WebSocketConnection class handles WebSocket protocol:
import{WebSocketConnection}from'./websocket-server.js';// WebSocket connection is automatically created during HTTP upgrade// Handle incoming messages:constreader=ws.incomingStream.getReader();while(!ws.closed){const{ value }=awaitreader.read();const{ opcode, payload }=value;if(opcode===ws.opcodes.TEXT){constmessage=newTextDecoder().decode(payload);awaitws.send(`Echo: ${message}`);}}The QuicServer class provides HTTP/3 and WebTransport support using the MatrixAI js-quic library:
import{QuicServer}from'./quic-server.js';constserver=newQuicServer({host: '0.0.0.0',port: 44819,onStream: async(stream)=>{// Handle QUIC streamsconstreader=stream.readable.getReader();constwriter=stream.writable.getWriter();// Process HTTP/3 or WebTransport data}});awaitserver.listen();The server uses Chrome's Direct Sockets API:
// Create TCP server socketconstsocket=newTCPServerSocket('0.0.0.0',{localPort: 44818});const{readable: server}=awaitsocket.opened;// Handle incoming connectionsawaitserver.pipeTo(newWritableStream({write: async(connection)=>{const{ readable, writable }=awaitconnection.opened;// Handle HTTP/WebSocket protocols}}));The server includes proper CORS headers for Chrome's Private Network Access:
Access-Control-Allow-Private-Network: trueAccess-Control-Allow-Origin: *- Handles OPTIONS preflight requests
- Runs in a secure IWA environment
- No access to user's file system or sensitive APIs
- Network access limited to Direct Sockets API
- What they are: Controlled Frames allow IWAs to embed and control external web content within secure, sandboxed iframe-like containers with enhanced permissions and communication capabilities
- Benefits: Enable secure integration of third-party services, controlled cross-origin communication, and the ability to grant specific permissions to embedded content while maintaining isolation
- Security model: Provides fine-grained control over what embedded content can access, including network permissions, storage access, and API capabilities
- Potential abuse vectors:
- Permission escalation: Malicious embedded content could attempt to exploit granted permissions beyond intended scope
- Data exfiltration: Compromised frames might try to access or transmit sensitive local data through permitted communication channels
- Resource exhaustion: Embedded content could consume excessive system resources (CPU, memory, network) affecting the host IWA performance
- Social engineering: Malicious frames could present deceptive UI to trick users into granting additional permissions or revealing sensitive information
- Mitigation strategies: Implement strict Content Security Policy (CSP), validate all frame communications, limit granted permissions to minimum required, and regularly audit embedded content sources
For testing, launch Chrome with:
chrome --unsafely-treat-insecure-origin-as-secure=http://localhost:44818- HTTP Requests: GET, POST, OPTIONS methods
- WebSocket: Connection, messaging, close handling
- CORS: Preflight requests and headers
- Error Handling: 404 responses, malformed requests
classHttpServer{constructor(options: HttpServerOptions)asynclisten(): Promise<void>asyncclose(): Promise<void>}interfaceHttpServerOptions{host?: string;port?: number;onRequest?: (request: HttpRequest,response: HttpResponse)=>Promise<void>;onWebSocket?: (ws: WebSocketConnection)=>Promise<void>;}classHttpResponse{setStatus(code: number,text?: string): voidsetHeader(name: string,value: string): voidasyncwrite(data: string|Uint8Array): Promise<void>asyncend(data?: string|Uint8Array): Promise<void>asyncjson(obj: any): Promise<void>asynctext(text: string): Promise<void>asynchtml(html: string): Promise<void>}classWebSocketConnection{readonlyincomingStream: ReadableStream<{opcode: number,payload: Uint8Array}>readonlyopcodes: {TEXT: 1,BINARY: 2,PING: 9,PONG: 10,CLOSE: 8}asyncsend(data: string|Uint8Array): Promise<void>asyncclose(code?: number,reason?: string): Promise<void>}- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
This project is licensed under the Apache License 2.0 - see the original license headers in the source files.
- WICG Direct Sockets Specification
- Isolated Web Apps
- Private Network Access
- WebSocket Protocol RFC 6455
- HTTP/1.1 Specification
- Server won't start: Ensure Chrome supports Direct Sockets and IWA is properly installed
- CORS errors: Check that proper headers are being sent
- WebSocket connection fails: Verify the WebSocket URL and protocol
- Port already in use: Change the port in server configuration
- Check browser console for errors
- Use Chrome DevTools Network tab to inspect requests
- Enable verbose logging in the server code
- Test with the provided example clients first

