# 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