Skip to main content
Glama
liquid1982

TrustLayer MCP Server

by liquid1982
README.md
# Unofficial TrustLayer MCP Server

**Unofficial** community Model Context Protocol (MCP) server for the **Public** TrustLayer API - read-only access.

## Overview

This MCP server provides read-only access to the **Public** TrustLayer API data, allowing integration with:

**API Documentation:** This server implements the **Public** TrustLayer Platform API v1.0 and follows the public API documentation available at [https://developers.trustlayer.io/](https://developers.trustlayer.io/).

- Cursor IDE
- n8n workflows
- Claude Desktop
- Other MCP-compatible tools

## Features

- **Read-Only Access**: Only GET operations are supported (no create, update, or delete)
- **Resources**: List all TrustLayer entities (Parties, Documents, Projects, etc.)
- **Tools**: Query specific entities by ID or list with filters
- **JSON Responses**: All data returned as structured JSON
- **HTTP Transport**: Deploy as HTTP server for remote access
- **Token Authentication**: Support for per-request token via Authorization header

## Prerequisites

- Python 3.11+
- TrustLayer API token

## Installation

1. Navigate to the mcp-server directory:

```bash
cd mcp-server
```

2. Create a virtual environment:

```bash
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
```

3. Install dependencies:

```bash
pip install -r requirements.txt
```

4. Create a `.env` file:

```bash
cp env.example .env
```

5. Edit `.env` and configure:

```env
TRUSTLAYER_API_BASE_URL=https://api.trustlayer.io
TRUSTLAYER_API_VERSION=v1
# TRUSTLAYER_API_TOKEN is optional for HTTP mode (token from Authorization header)
# Required only for stdio mode
TRUSTLAYER_API_TOKEN=your_api_token_here
```

**Configuration Options:**
- `TRUSTLAYER_API_BASE_URL` - Base URL for TrustLayer API (default: `https://api.trustlayer.io`)
- `TRUSTLAYER_API_VERSION` - API version (default: `v1`)
- `TRUSTLAYER_API_TOKEN` - API token (required for stdio mode, optional for HTTP mode)

## Usage

### Running the MCP Server

The MCP server can run in two modes:

#### 1. Stdio Mode (for local MCP clients)

The MCP server runs via stdio and is typically started by MCP clients. To test manually:

**Option 1: Using the wrapper script (recommended):**

```bash
# Make sure the script is executable
chmod +x run_server.sh

# Run the server
./run_server.sh
```

**Option 2: Direct Python execution:**

```bash
# Activate virtual environment
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Run the server
python -m src.server
```

#### 2. HTTP Mode (for remote access)

To run the MCP server as an HTTP service:

```bash
# Activate virtual environment
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Run the HTTP server
python run_http_server.py
```

The server will be available at `http://localhost:8000` with the following endpoints:
- `http://localhost:8000/` - Health check and server info
- `http://localhost:8000/health` - Health check endpoint
- `http://localhost:8000/mcp` - MCP protocol endpoint

**Note:** 
- For **HTTP mode**: Token can be provided via `Authorization` header (recommended) or via `TRUSTLAYER_API_TOKEN` env var
- For **stdio mode**: Token must be set in `TRUSTLAYER_API_TOKEN` env var

#### 3. Docker Mode

To run the MCP server using Docker:

```bash
# Create .env file if it doesn't exist
cp env.example .env
# Edit .env and set TRUSTLAYER_API_TOKEN (optional for HTTP mode)

# Build and start the container
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the container
docker-compose down
```

**Rebuilding the Docker image:**

If you've made changes to the code and need to rebuild the image:

```bash
# Stop and remove containers
docker-compose down

# Rebuild without cache (recommended after code changes)
docker-compose build --no-cache

# Start the container
docker-compose up -d

# Or do it all in one command
docker-compose down && docker-compose build --no-cache && docker-compose up -d
```

**Quick rebuild and restart:**

```bash
# Rebuild and restart in one command
docker-compose up -d --build
```

**Checking if the server is running:**

```bash
# Check container status
docker-compose ps

# Check health endpoint
curl http://localhost:8000/health

# View logs
docker-compose logs --tail=50
```

The server will be available at `http://localhost:8000` with the same endpoints as HTTP mode.

### Production Deployment

#### Systemd Service Setup

For production deployment on Linux servers, you can create a systemd service:

1. Create service file:

```bash
sudo nano /etc/systemd/system/trustlayer-mcp.service
```

2. Add the following content:

```ini
[Unit]
Description=TrustLayer MCP Server
After=network.target

[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/mcp-server
Environment="PATH=/path/to/mcp-server/venv/bin"
EnvironmentFile=/path/to/mcp-server/.env
ExecStart=/path/to/mcp-server/venv/bin/python run_http_server.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

3. Activate the service:

```bash
# Reload systemd
sudo systemctl daemon-reload

# Enable auto-start
sudo systemctl enable trustlayer-mcp

# Start the service
sudo systemctl start trustlayer-mcp

# Check status
sudo systemctl status trustlayer-mcp

# View logs
sudo journalctl -u trustlayer-mcp -f
```

#### Nginx Reverse Proxy

For production, it's recommended to use Nginx as a reverse proxy:

1. Create Nginx configuration:

```nginx
server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        
        # For SSE/streaming
        proxy_buffering off;
        proxy_cache off;
    }
}
```

2. Enable SSL with Let's Encrypt:

```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
```

### Integration with Cursor

#### Option 1: Stdio Mode (Local)

Add to your Cursor settings (`.cursor/mcp.json`):

**Option A: Using the wrapper script (recommended):**

```json
{
  "mcpServers": {
    "trustlayer": {
      "command": "/path/to/mcp-server/run_server.sh",
      "cwd": "/path/to/mcp-server",
      "env": {
        "TRUSTLAYER_API_TOKEN": "your_api_token_here",
        "TRUSTLAYER_API_BASE_URL": "https://api.trustlayer.io",
        "TRUSTLAYER_API_VERSION": "v1"
      }
    }
  }
}
```

**Option B: Direct Python execution:**

```json
{
  "mcpServers": {
    "trustlayer": {
      "command": "/path/to/mcp-server/venv/bin/python3",
      "args": ["-m", "src.server"],
      "cwd": "/path/to/mcp-server",
      "env": {
        "PYTHONPATH": "/path/to/mcp-server",
        "TRUSTLAYER_API_TOKEN": "your_api_token_here",
        "TRUSTLAYER_API_BASE_URL": "https://api.trustlayer.io",
        "TRUSTLAYER_API_VERSION": "v1"
      }
    }
  }
}
```

**Example with absolute paths (using wrapper script):**

```json
{
  "mcpServers": {
    "trustlayer": {
      "command": "/path/to/mcp-server/run_server.sh",
      "cwd": "/path/to/mcp-server",
      "env": {
        "TRUSTLAYER_API_TOKEN": "your_api_token_here",
        "TRUSTLAYER_API_BASE_URL": "https://api.trustlayer.io",
        "TRUSTLAYER_API_VERSION": "v1"
      }
    }
  }
}
```

**Important:** 
- When using the wrapper script (`run_server.sh`): Just provide the full path to the script and set `cwd`
- When using direct Python execution: Use the full path to your Python executable in the virtual environment and set `PYTHONPATH`
- Always set `cwd` to the mcp-server directory

#### Option 2: HTTP Mode (Remote)

If you're running the HTTP server separately, connect via HTTP:

**Basic connection (uses token from server config):**

```json
{
  "mcpServers": {
    "trustlayer": {
      "url": "http://localhost:8000/mcp",
      "transport": "streamable-http"
    }
  }
}
```

**With Authorization header (recommended - token per client):**

```json
{
  "mcpServers": {
    "trustlayer": {
      "url": "http://localhost:8000/mcp",
      "transport": "streamable-http",
      "headers": {
        "Authorization": "Bearer your_api_token_here"
      }
    }
  }
}
```

For remote servers, replace `localhost:8000` with your server's address.

**Note:** When using Authorization header, the token is passed with each request, allowing different clients to use different tokens. This is more secure than storing tokens in server configuration.

### Integration with Claude Desktop

Add to Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

**Stdio Mode:**

```json
{
  "mcpServers": {
    "trustlayer": {
      "command": "python",
      "args": ["-m", "src.server"],
      "cwd": "/path/to/mcp-server",
      "env": {
        "TRUSTLAYER_API_TOKEN": "your_token_here",
        "TRUSTLAYER_API_BASE_URL": "https://api.trustlayer.io",
        "TRUSTLAYER_API_VERSION": "v1"
      }
    }
  }
}
```

**HTTP Mode:**

```json
{
  "mcpServers": {
    "trustlayer": {
      "url": "http://your-server:8000/mcp",
      "transport": "streamable-http",
      "headers": {
        "Authorization": "Bearer your_api_token_here"
      }
    }
  }
}
```

### Integration with n8n

Use the MCP server as a custom node or via HTTP interface. Start the HTTP server and connect to `http://your-server:8000/mcp`.

**Configuration example:**

```json
{
  "url": "http://your-server:8000/mcp",
  "transport": "streamable-http",
  "headers": {
    "Authorization": "Bearer your_api_token_here"
  }
}
```

**Note:** Replace `your-server:8000` with your actual server address and `your_api_token_here` with your TrustLayer API token.

## Available Resources

The MCP server provides resources for:

- `trustlayer://parties/{id}` - Individual parties
- `trustlayer://documents/{id}` - Individual documents
- `trustlayer://projects/{id}` - Individual projects
- `trustlayer://tags/{id}` - Individual tags
- `trustlayer://compliance-profiles/{id}` - Compliance profiles
- `trustlayer://party-types/{id}` - Party types
- `trustlayer://custom-fields/{id}` - Custom fields
- `trustlayer://reports/{id}` - Reports
- `trustlayer://webhooks/{id}` - Webhooks
- `trustlayer://branding/{id}` - Branding configurations

## Available Tools

### Get Operations

- `get_party` - Get a party by ID
- `get_document` - Get a document by ID
- `get_project` - Get a project by ID
- `get_contact` - Get a contact by ID
- `get_party_contacts` - Get all contacts for a party
- `get_party_compliance_profile` - Get compliance profile for a party
- `get_party_compliance_certificate` - Get compliance certificate for a party
- `get_party_document_request` - Get document request for a party
- `get_compliance_profile` - Get a compliance profile by ID
- `get_report` - Get a report by ID

### List Operations

- `list_parties` - List all parties (with optional limit/offset)
- `list_documents` - List all documents (with optional limit/offset)
- `list_projects` - List all projects (with optional limit/offset)
- `list_tags` - List all tags
- `list_compliance_profiles` - List all compliance profiles
- `list_party_types` - List all party types
- `list_custom_fields` - List all custom fields
- `list_reports` - List all reports
- `list_webhooks` - List all webhooks

## Project Structure

```
mcp-server/
├── src/
│   ├── __init__.py
│   ├── server.py              # Main MCP server (stdio mode)
│   ├── http_server.py         # HTTP MCP server
│   ├── trustlayer_client.py   # TrustLayer API client
│   ├── config.py              # Configuration
│   ├── resources.py           # MCP resources
│   └── tools.py                # MCP tools
├── run_server.sh              # Stdio server launcher script
├── run_http_server.py         # HTTP server launcher
├── test_server.py             # Test script to verify server setup
├── test_tools.py              # Test script to verify tools registration
├── pyproject.toml
├── requirements.txt
├── Dockerfile                  # Docker configuration
├── docker-compose.yml          # Docker Compose configuration
├── env.example                 # Environment variables example
└── README.md
```

## Example Usage

### In Cursor/Claude

You can ask questions like:

- "List all parties in TrustLayer"
- "Get details for party ID 12345"
- "Show me all documents for party 12345"
- "What compliance profile does party 12345 have?"

The MCP server will fetch the data from TrustLayer API and return it in a structured format.

## Security

- **Read-Only**: The MCP server only supports GET operations
- **Token Security**: Store API tokens securely in environment variables or use Authorization headers
- **No Data Modification**: No create, update, or delete operations are exposed
- **HTTPS Recommended**: Use HTTPS in production environments
- **Firewall**: Restrict access through firewall to only necessary IPs

## Monitoring

### Health Check

The server provides a health check endpoint:

```bash
curl http://localhost:8000/health
```

Expected response:
```json
{"status": "healthy"}
```

### Logs

**Docker:**
```bash
docker-compose logs -f
```

**Systemd:**
```bash
sudo journalctl -u trustlayer-mcp -f
```

**Local:**
Logs are output to stdout/stderr when running directly.

## Troubleshooting

### Token Issues

Ensure `TRUSTLAYER_API_TOKEN` is set correctly in your environment or `.env` file. For HTTP mode, you can also provide the token via `Authorization` header.

### Connection Issues

- Verify `TRUSTLAYER_API_BASE_URL` is correct
- Check network connectivity
- Review server logs for error messages
- For HTTP mode, ensure the server is running: `curl http://localhost:8000/health`

### Port Already in Use

```bash
# Check what's using port 8000
sudo lsof -i :8000

# Or change the port in run_http_server.py
```

### MCP Client Issues

- Ensure Python is in your PATH
- Verify the MCP server can be started manually
- Check MCP client logs for connection errors
- For stdio mode, verify paths in configuration are correct

### Docker Issues

- Ensure Docker and Docker Compose are installed
- Check container logs: `docker-compose logs`
- Verify `.env` file exists and is properly configured
- Rebuild image if code changes: `docker-compose build --no-cache`

## Development

### Testing

#### Quick Verification Scripts

**Test server setup and imports:**

```bash
python test_server.py
```

This script verifies that:
- Configuration loads correctly
- Server can be imported
- Tools are available

**Test tools registration:**

```bash
python test_tools.py
```

This script verifies that tools are properly registered and can be listed.

#### Test Stdio Server

**Option 1: Using the wrapper script:**

```bash
./run_server.sh
```

**Option 2: Direct Python execution:**

```bash
source venv/bin/activate
python -m src.server
```

#### Test HTTP Server

```bash
# Start the HTTP server
python run_http_server.py

# In another terminal, test the endpoints
curl http://localhost:8000/health
curl http://localhost:8000/
```

### Code Formatting

```bash
black src/
ruff check src/
```

## License

Apache 2.0