MCP_Latch

lSAAGl/MCP_Latch

3.1

If you are the rightful owner of MCP_Latch and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

MCP Latch is a policy-enforced proxy server designed to provide secure, auditable, and controllable AI agent tool usage.

Tools
3
Resources
0
Prompts
0

MCP Latch

A Policy-Enforced MCP Proxy Server with Human Oversight

Secure, auditable, and controllable AI agent tool usage

TypeScript Node.js MCP

FeaturesQuick StartArchitectureConfigurationAPI Reference


Overview

MCP Latch is a sophisticated proxy server that sits between AI agents and external tools, providing enterprise-grade security, policy enforcement, and human oversight for AI tool usage. Built on the Model Context Protocol (MCP), Latch enables organizations to safely deploy AI agents while maintaining complete control over their actions.

Why MCP Latch?

  • 🛡️ Security First: Policy-based access control with granular permissions
  • 👥 Human Oversight: Real-time approval workflows for sensitive operations
  • 📊 Cost Control: Budget management and usage tracking
  • 🔍 Full Auditability: Complete logging and monitoring of all AI actions
  • 🔌 MCP Compatible: Works with any MCP-compliant AI agent or tool
  • 🎛️ Flexible Configuration: YAML-based policy management

Features

🔐 Policy Enforcement

  • Rule-based Access Control: Define allow/deny rules based on tool parameters
  • Conditional Logic: Complex matching patterns (regex, wildcards, host filtering)
  • Hierarchical Policies: Server and tool-level configuration

💰 Budget Management

  • Cost Tracking: Per-call cost estimation and total budget limits
  • Rate Limiting: Time-window based call restrictions
  • Token Limits: Control AI model token usage

✅ Approval Workflows

  • Real-time Gates: Human approval for sensitive operations
  • Time-bound Approvals: Temporary permissions with automatic expiry
  • Risk Assessment: Automatic risk scoring and escalation

🖥️ Management Interface

  • Web Dashboard: Intuitive approval interface built with Next.js
  • Real-time Updates: Live monitoring of pending approvals
  • Batch Operations: Approve multiple actions efficiently

🔧 Developer Experience

  • TypeScript: Full type safety and excellent IDE support
  • Modular Architecture: Clean separation of concerns
  • Extensible: Easy to add new upstreams and policy rules
  • Testing: Comprehensive dry-run mode for policy testing

Quick Start

Prerequisites

  • Node.js 18+
  • npm or pnpm
  • TypeScript knowledge (recommended)

Installation

  1. Clone the repository

    git clone https://github.com/lSAAGl/MCP_Latch.git
    cd MCP_Latch
    
  2. Install dependencies

    cd latch
    npm install
    
  3. Configure upstreams (optional)

    # Edit proxy/upstreams.config.json to connect real MCP servers
    # Or use the included fake implementations for testing
    
  4. Start the components

    # Terminal 1: Start the MCP proxy server
    npm run mcp:stdio --workspace=proxy
    
    # Terminal 2: Start the approval HTTP API  
    npm run approvals:http --workspace=proxy
    
    # Terminal 3: Start the web UI
    npm run dev:ui
    

Basic Usage

Once running, MCP Latch exposes tools via the MCP protocol:

// AI agent connects to Latch proxy
const result = await mcp.callTool("browsermcp.navigate", {
  url: "https://example.com"
});

// Latch evaluates policy, may require approval
// Returns result or creates approval gate

Architecture

graph TB
    Agent[AI Agent] --> Latch[MCP Latch Proxy]
    Latch --> Policy[Policy Engine]
    Latch --> Approval[Approval Controller]
    Latch --> Budget[Budget Manager]
    
    Policy --> Allow[Auto Allow]
    Policy --> Deny[Auto Deny]  
    Policy --> Gate[Approval Gate]
    
    Gate --> UI[Web Dashboard]
    UI --> Human[Human Approver]
    
    Allow --> Browser[Browser MCP]
    Allow --> Email[Email MCP]
    Allow --> Custom[Custom Tools]
    
    Browser --> Web[Web Actions]
    Email --> SMTP[Email Service]

Core Components

ComponentPurposeLocation
ProxyCoreMain orchestration engineproxy/src/proxyCore.ts
Policy EngineRule evaluation and matchingproxy/src/evaluator.ts
MCP ServerProtocol implementationproxy/src/mcp/server.ts
Approval SystemHuman oversight workflowsproxy/src/approval.ts
Budget ManagerCost and usage controlsproxy/src/budgets.ts
Web UIManagement interfaceui/app/

Configuration

Policy Definition

Policies are defined in YAML format (policy/policy.yaml):

version: 1
servers:
  browsermcp:
    tools:
      - name: navigate
        allow_if:
          url_host_allow: ["*.example.com", "trusted-site.com"]
        budgets:
          window_seconds: 60
          max_calls: 10
      
      - name: click  
        require_approval_if:
          url_host_match: "*.payment.*"
        budgets:
          max_calls: 5

  agentmail:
    tools:
      - name: send_email
        allow_if:
          to_regex: ".*@company\\.com$"
        require_approval_if:
          to_regex: ".*@(gmail|yahoo)\\.com$"
        budgets:
          est_cost_per_call_usd: 0.02
          max_total_cost_usd: 1.00

Policy Rules

Access Control
  • allow_if: Conditions for automatic approval
  • require_approval_if: Conditions requiring human approval
  • deny_if: Conditions for automatic denial
Matching Patterns
  • url_host_allow: Whitelist of allowed domains
  • url_host_deny: Blacklist of forbidden domains
  • to_regex: Email address pattern matching
  • Custom matchers for specific use cases
Budget Controls
  • max_calls: Maximum calls per time window
  • window_seconds: Time window for rate limiting
  • est_cost_per_call_usd: Estimated cost per operation
  • max_total_cost_usd: Total budget limit
  • max_tokens_per_call: Token usage limits

Upstream Configuration

Connect real MCP servers via proxy/upstreams.config.json:

{
  "browsermcp": {
    "command": "npx",
    "args": ["@browser-use/mcp-server"],
    "env": {
      "BROWSER_EXECUTABLE_PATH": "/usr/bin/google-chrome"
    }
  },
  "agentmail": {
    "command": "npx", 
    "args": ["agentmail-mcp@latest"],
    "env": {
      "SMTP_HOST": "smtp.gmail.com",
      "SMTP_USER": "your-email@gmail.com",
      "SMTP_PASS": "app-password"
    }
  }
}

API Reference

MCP Tools

Latch exposes upstream tools with the naming pattern ${server}.${tool}:

// Browser automation
await mcp.callTool("browsermcp.navigate", { url: "https://example.com" });
await mcp.callTool("browsermcp.click", { selector: "#button" });

// Email operations  
await mcp.callTool("agentmail.send_email", {
  to: "user@example.com",
  subject: "Hello",
  body: "Message content"
});

HTTP API

The approval server exposes REST endpoints:

Get Pending Approvals
GET /pending
Approve/Deny Request
POST /decide
Content-Type: application/json

{
  "callId": "abc123",
  "decision": "approve",
  "minutes": 10
}
Seed Test Data
POST /_seed

CLI Commands

# Type checking
npm run typecheck

# Start MCP server
npm run mcp:stdio --workspace=proxy

# Start approval API
npm run approvals:http --workspace=proxy  

# Start web UI
npm run dev:ui

# Test policies
npm run policy:test --workspace=proxy

# Demo mode
npm run proxy:demo --workspace=proxy

Development

Project Structure

latch/
├── proxy/                 # Core proxy server
│   ├── src/
│   │   ├── mcp/          # MCP protocol implementation
│   │   ├── http/         # HTTP API server
│   │   ├── tools/        # Utility tools
│   │   └── ...           # Core logic files
│   └── package.json
├── ui/                    # Next.js web interface  
│   ├── app/
│   └── package.json
├── policy/                # Policy configuration
│   └── policy.yaml
└── package.json           # Workspace root

Testing

# Run type checks
npm run typecheck

# Test policy evaluation
npm run policy:test --workspace=proxy

# Start with dry run mode
LATCH_DRY_RUN=1 npm run mcp:stdio --workspace=proxy

Adding New Upstreams

  1. Define the upstream interface:

    class CustomUpstream implements Upstream {
      listTools(): ToolSpec[] { /* ... */ }
      callTool(tool: string, args: any): Promise<any> { /* ... */ }
    }
    
  2. Update the policy configuration:

    servers:
      custom:
        tools:
          - name: my_tool
            allow_if: { /* conditions */ }
    
  3. Register in upstreamsFactory:

    out["custom"] = await create("custom", new CustomUpstream());
    

Security Considerations

  • Input Validation: All tool arguments are validated against schemas
  • Sandbox Mode: Dry-run capability for testing without real effects
  • Audit Logging: Complete record of all actions and decisions
  • Time-bound Permissions: Approvals automatically expire
  • Least Privilege: Default deny with explicit allow rules

Contributing

We welcome contributions! Please see our for details.

Development Setup

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License

MIT License - see file for details.

Support


Built with ❤️ for the AI community

Secure AI agent deployments shouldn't be an afterthought