Skip to main content

A model context protocol server for interacting with Unblu deployments.

Project description

unblu-mcp

ci documentation

A Model Context Protocol (MCP) server for interacting with Unblu deployments. This server provides AI assistants with token-efficient access to 300+ Unblu API endpoints through progressive disclosure.

Table of Contents

🔒 Security First: This server includes built-in safety controls. The call_api tool is marked with destructiveHint: true to trigger client confirmations, and optional Eunomia integration provides server-side policy enforcement to block destructive operations. Learn more →

Features

This server implements best practices from Anthropic's guide on building effective agents:

  • Progressive Disclosure: 5 discovery tools instead of 300+ API definitions upfront, dramatically reducing token usage
  • Clear Tool Interfaces: Descriptive parameters with examples, helpful error messages that suggest alternatives
  • Full API Coverage: Access to all Unblu REST API v4 endpoints
  • Smart Discovery: Search and browse operations by service category or keyword
  • Field Filtering: Request only the fields you need to reduce response size
  • Response Truncation: Limit response sizes to prevent token overflow

Built with FastMCP 2.14+, leveraging cutting-edge features:

  • MCP Annotations: Tools include readOnlyHint, destructiveHint, and openWorldHint metadata for smarter AI decision-making
  • Response Caching: Discovery tools cache results via FastMCP middleware for faster repeated queries
  • Policy-Based Authorization: Optional Eunomia integration for controlling which API operations are allowed
  • Built-in Logging: Automatic file-based logging with daily rotation for debugging and usage analysis
  • MCP 2025-11-25 Spec: Full support for the latest Model Context Protocol specification

Installation

This package is available on PyPI and designed to be run directly via uvx - no installation required. See MCP Client Configuration below.

For development or customization, clone from source:

From source

git clone https://github.com/detailobsessed/unblu-mcp.git
cd unblu-mcp
uv sync

Configuration

MCP Client Configuration

Add the server to your MCP client configuration (Claude Desktop, Windsurf, etc.):

With Kubernetes Provider (recommended for internal deployments)

The K8s provider automatically manages kubectl port-forward connections to your Unblu deployment. This is the most tested configuration.

macOS (~/Library/Application Support/Claude/claude_desktop_config.json or IDE MCP config):

{
  "mcpServers": {
    "unblu": {
      "command": "uvx",
      "args": ["unblu-mcp", "--provider", "k8s", "--environment", "dev"]
    }
  }
}

Windows (%APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "unblu": {
      "command": "uvx",
      "args": ["unblu-mcp", "--provider", "k8s", "--environment", "dev"]
    }
  }
}

See K8s Provider Configuration below for setting up your environments.

With Environment Variables

For direct API access without Kubernetes:

{
  "mcpServers": {
    "unblu": {
      "command": "uvx",
      "args": ["unblu-mcp"],
      "env": {
        "UNBLU_BASE_URL": "https://your-instance.unblu.cloud/app/rest/v4",
        "UNBLU_API_KEY": "your-api-key"
      }
    }
  }
}

Environment Variables

Variable Required Description
UNBLU_BASE_URL No Your Unblu API base URL (default: https://unblu.cloud/app/rest/v4)
UNBLU_API_KEY One of these API key for authentication (Bearer token)
UNBLU_USERNAME One of these Username for basic authentication
UNBLU_PASSWORD With username Password for basic authentication

Available Tools

The server exposes 5 tools for progressive API discovery and execution:

Tool Description
list_services() List all API service categories (e.g., Conversations, Users, Bots)
list_operations(service) List operations in a specific service
search_operations(query) Search for operations by keyword
get_operation_schema(operation_id) Get full schema for an operation
call_api(operation_id, ...) Execute any API operation

Example Workflow

  1. Discover services: list_services() → See categories like "Conversations", "Users", "Bots"
  2. Browse operations: list_operations("Conversations") → See available conversation operations
  3. Get details: get_operation_schema("conversationsGetById") → See required parameters
  4. Execute: call_api("conversationsGetById", path_params={"conversationId": "abc123"})

Advanced Options

The call_api tool supports additional parameters for token efficiency:

call_api(
    operation_id="conversationsSearch",
    body={"query": "support"},
    fields=["id", "topic", "creationTimestamp"],  # Only return these fields
    max_response_size=10000  # Truncate response if larger than 10KB
)

Command Line Usage

# Run with stdio transport (default, for MCP clients)
unblu-mcp

# Use a custom swagger.json location
unblu-mcp --spec /path/to/swagger.json

# Run with Eunomia authorization policy (requires unblu-mcp[safety])
unblu-mcp --policy /path/to/mcp_policies.json

# Run with K8s provider (auto-starts kubectl port-forward)
unblu-mcp --provider k8s --environment dev

# Run with K8s provider using custom config file
unblu-mcp --provider k8s --environment my-env --k8s-config /path/to/k8s_environments.yaml

# Show version
unblu-mcp --version

# Show debug info
unblu-mcp --debug-info

CLI Arguments

Argument Values Default Description
--spec path auto-detect Path to swagger.json
--policy path none Eunomia policy file
--provider default, k8s default Connection provider
--environment string dev K8s environment (with --provider k8s)
--k8s-config path none Custom K8s environments YAML file

Logging & Observability

The server automatically logs all tool calls to help with debugging and usage analysis.

Log Location

Logs are written to ~/.unblu-mcp/logs/ with daily rotation:

~/.unblu-mcp/logs/
├── unblu-mcp.log              # Current log
├── unblu-mcp.log.2025-01-14   # Yesterday
├── unblu-mcp.log.2025-01-13   # Day before
└── ...

Configuration

Environment Variable Description
UNBLU_MCP_LOG_DIR Custom log directory (default: ~/.unblu-mcp/logs)
UNBLU_MCP_LOG_DISABLE Set to 1, true, or yes to disable file logging

Log Format

2025-01-15 14:30:22 | INFO     | fastmcp | tools/call request: call_api(operation_id="conversationsGetById", ...)

Logs include:

  • Timestamp (UTC)
  • Log level
  • Tool name and arguments
  • Response summaries

Logs are retained for 30 days and automatically rotated at midnight UTC.

Safety & Authorization

The call_api tool can execute any Unblu API operation, including destructive ones (DELETE, PUT, POST). This is a powerful capability that requires appropriate controls.

Two Layers of Protection

Layer Type Description
MCP Annotations Client-side destructiveHint: true signals clients to prompt for confirmation
Eunomia Policies Server-side Block unauthorized operations before they execute

Layer 1: Tool Annotations (Built-in)

The call_api tool includes these MCP annotations:

  • destructiveHint: true — Signals this tool may modify data
  • idempotentHint: false — Repeated calls may have different effects
  • openWorldHint: true — Interacts with external systems

Well-behaved MCP clients (like Claude Desktop) will prompt for user confirmation before executing tools marked as destructive.

Layer 2: Policy-Based Authorization (Optional)

For server-side enforcement, use Eunomia to define what operations are allowed:

# Install with safety features
pip install unblu-mcp[safety]

# Run with policy enforcement
unblu-mcp --policy config/mcp_policies.json

The included config/mcp_policies.json provides a sensible default:

Operation Type Policy Examples
Discovery tools ✅ Allowed list_services, list_operations, search_operations, get_operation_schema
Read-only API calls ✅ Allowed ~190 operations like *Get*, *Search*, *List*, *Read*, *Find*, *Check*
Destructive API calls ❌ Blocked ~140 operations like *Create*, *Update*, *Delete*, *Send*, *Login*, etc.

Custom Policies

To allow additional operations beyond read-only, create a custom policy file. For example, to allow creating and updating conversations:

{
  "version": "1.0",
  "name": "custom-policy",
  "default_effect": "deny",
  "rules": [
    {
      "name": "allow-all-discovery",
      "effect": "allow",
      "resource_conditions": [
        {"path": "attributes.tool_name", "operator": "in",
         "value": ["list_services", "list_operations", "search_operations", "get_operation_schema"]}
      ],
      "actions": ["execute"]
    },
    {
      "name": "allow-conversation-operations",
      "effect": "allow",
      "resource_conditions": [
        {"path": "attributes.tool_name", "operator": "eq", "value": "call_api"},
        {"path": "attributes.args.operation_id", "operator": "regex",
         "value": "^conversations(Get|Search|Read|Create|Update|Set)"}
      ],
      "actions": ["execute"]
    }
  ]
}

To allow all operations (no restrictions):

{
  "version": "1.0",
  "name": "allow-all",
  "default_effect": "allow",
  "rules": []
}

See the Eunomia documentation for advanced policy configuration.

Programmatic Usage

Connection Providers

The server supports pluggable connection providers for different deployment scenarios:

from unblu_mcp import create_server, DefaultConnectionProvider

# Default provider (uses environment variables)
server = create_server()

# Custom provider with explicit credentials
provider = DefaultConnectionProvider(
    base_url="https://my-instance.unblu.cloud/app/rest/v4",
    api_key="my-api-key",
)
server = create_server(provider=provider)

Kubernetes Port-Forward Provider

For Kubernetes deployments, use the built-in K8s provider:

from unblu_mcp import create_server, K8sConnectionProvider

# Connect to a K8s environment (starts kubectl port-forward automatically)
provider = K8sConnectionProvider(environment="dev")
server = create_server(provider=provider)

K8s environments are configured in ~/.unblu-mcp/k8s_environments.yaml:

environments:
  t1:
    local_port: 8084
    namespace: unblu-dev
    service: haproxy
    service_port: 8080
    api_path: /app/rest/v4

Custom Connection Providers

Implement the ConnectionProvider interface for custom connectivity:

from unblu_mcp import ConnectionProvider, ConnectionConfig

class MyProvider(ConnectionProvider):
    async def setup(self) -> None:
        # Initialize connection (e.g., start tunnel)
        pass

    async def teardown(self) -> None:
        # Clean up resources
        pass

    def get_config(self) -> ConnectionConfig:
        return ConnectionConfig(
            base_url="https://api.example.com",
            headers={"X-Custom-Header": "value"},
        )

Development

# Clone the repository
git clone https://github.com/detailobsessed/unblu-mcp.git
cd unblu-mcp

# Install dependencies
uv sync --all-extras --dev

# Run tests
uv run poe test

# Run linting
uv run poe lint

# Build documentation
uv run poe docs

License

ISC License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unblu_mcp-0.2.6.tar.gz (229.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unblu_mcp-0.2.6-py3-none-any.whl (233.2 kB view details)

Uploaded Python 3

File details

Details for the file unblu_mcp-0.2.6.tar.gz.

File metadata

  • Download URL: unblu_mcp-0.2.6.tar.gz
  • Upload date:
  • Size: 229.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for unblu_mcp-0.2.6.tar.gz
Algorithm Hash digest
SHA256 15cc9f90af771dec8a693ff0de2b46ff6b2477c535fcf3f29f82741b7e060657
MD5 79004b5b3dbf4a6d08cd623f6da54432
BLAKE2b-256 832be3d98e6552e21a8f1988559ff82648cace1b940f4c7e6b0700bd493d587f

See more details on using hashes here.

File details

Details for the file unblu_mcp-0.2.6-py3-none-any.whl.

File metadata

  • Download URL: unblu_mcp-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 233.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for unblu_mcp-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 ce974af6a0d90461c56dbe7e6926039bbe2e2af8adf5bb4a179be2905ea815fb
MD5 cfd1b17a964ecf61cfcf4d30c2038f5f
BLAKE2b-256 e6d05e8908270362fd5b64248c22a865fd7c535bbdddcf9cedddafd7cfcbadf5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page