Skip to main content
Glama
Shawn-Falconbury

Multi-Tool MCP Server

README.md
# MCP Server

A custom [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that provides Claude Code and other MCP clients with secure access to filesystem, system information, Obsidian vault, SQLite database, and UniFi network controller tools.

## Features

- **Filesystem Tools** - Read, write, list, and search files within allowed paths
- **System Tools** - Get system info, run whitelisted commands, view processes and disk usage
- **Obsidian Tools** - List notes, read content, search text, and find backlinks in your vault
- **Database Tools** - Query SQLite databases with read-only access
- **UniFi Tools** - Query and manage UniFi Dream Machine networks, including Threat Management (CyberSecure)

## Security

- HTTPS with TLS certificates (Let's Encrypt supported)
- Bearer token authentication for all MCP requests
- Path restrictions for filesystem operations
- Command whitelist for system operations
- Read-only database access with query filtering
- API key authentication for UniFi integration

## Requirements

- Node.js 18+ (for native fetch support)
- npm or yarn
- TLS certificates (self-signed for development, Let's Encrypt for production)
- Optional: UniFi Dream Machine with API key

## Installation

1. Clone the repository:
   ```bash
   git clone https://github.com/your-username/mcp-server.git
   cd mcp-server
   ```

2. Install dependencies:
   ```bash
   npm install
   ```

3. Configure environment:
   ```bash
   cp .env.example .env
   # Edit .env with your settings
   ```

4. Generate TLS certificates (for development):
   ```bash
   mkdir -p certs
   openssl req -x509 -newkey rsa:4096 -keyout certs/server.key -out certs/server.crt -days 365 -nodes -subj "/CN=localhost"
   ```

5. Build and run:
   ```bash
   npm run build
   npm start
   ```

## Configuration

Copy `.env.example` to `.env` and configure:

| Variable | Required | Description |
|----------|----------|-------------|
| `MCP_TOKEN` | Yes | Authentication token for MCP clients |
| `MCP_PORT` | No | Server port (default: 8443) |
| `USE_HTTPS` | No | Use HTTPS (default: true) |
| `SSL_CERT_PATH` | No | Path to SSL certificate |
| `SSL_KEY_PATH` | No | Path to SSL private key |
| `ALLOWED_PATHS` | No | Comma-separated paths for filesystem access |
| `OBSIDIAN_VAULT_PATH` | No | Path to Obsidian vault |
| `DB_PATH` | No | Path to SQLite database |
| `UNIFI_HOST` | No | UniFi controller IP/hostname |
| `UNIFI_API_KEY` | No | UniFi API key |
| `UNIFI_SITE` | No | UniFi site name (default: "default") |

## Usage

### Development

```bash
npm run dev    # Run with tsx (hot reload)
```

### Production

```bash
npm run build  # Compile TypeScript
npm start      # Run compiled server
```

### Systemd Service

Create `/etc/systemd/system/mcp-server.service`:

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

[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/mcp-server
ExecStart=/usr/bin/npm start
Restart=on-failure
RestartSec=10

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

Then:
```bash
sudo systemctl daemon-reload
sudo systemctl enable mcp-server
sudo systemctl start mcp-server
```

## Connecting Clients

### Claude Code (CLI)

```bash
claude mcp add --transport http my-mcp https://your-server.example.com:8443/mcp \
  --header "Authorization: Bearer YOUR_MCP_TOKEN"
```

Or add to your project's `.mcp.json`:

```json
{
  "mcpServers": {
    "my-mcp": {
      "url": "https://your-server.example.com:8443/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_MCP_TOKEN"
      }
    }
  }
}
```

### Claude Desktop

Add to your Claude Desktop config file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "my-mcp": {
      "url": "https://your-server.example.com:8443/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_MCP_TOKEN"
      }
    }
  }
}
```

Restart Claude Desktop after saving.

## Available Tools

See [docs/tools-reference.md](docs/tools-reference.md) for complete tool documentation.

### Tool Categories

| Category | Tools | Description |
|----------|-------|-------------|
| Filesystem | 4 | File read/write/list/search |
| System | 4 | System info and commands |
| Obsidian | 4 | Vault notes and search |
| Database | 3 | SQLite queries |
| UniFi | 19 | Network management and security |

**Total: 34 tools**

## Project Structure

```
mcp-server/
├── src/
│   ├── index.ts          # Entry point
│   ├── server.ts         # Express + MCP setup
│   ├── auth.ts           # Token authentication
│   └── tools/
│       ├── index.ts      # Tool registry
│       ├── filesystem.ts # File operations
│       ├── system.ts     # System commands
│       ├── obsidian.ts   # Obsidian vault
│       ├── database.ts   # SQLite queries
│       └── unifi.ts      # UniFi controller
├── docs/                 # Documentation
├── certs/                # TLS certificates (not in repo)
├── dist/                 # Compiled output (not in repo)
├── .env                  # Configuration (not in repo)
└── .env.example          # Example configuration
```

## API Endpoints

The server provides two ways to access tools:

### REST API (Simple)

Direct tool access without MCP protocol handshake. Best for scripts, automation, and testing.

| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| `/health` | GET | No | Health check |
| `/api/tools` | GET | Yes | List all available tools with schemas |
| `/api/tools/:name` | GET | Yes | Get info for a specific tool |
| `/api/tools/:name` | POST | Yes | Execute a tool (args in request body) |

**Example - Single request to call a tool:**
```bash
curl -X POST https://your-server.example.com:8443/api/tools/unifi_get_network_health \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**Response format:**
```json
{
  "success": true,
  "tool": "unifi_get_network_health",
  "data": { ... }
}
```

### MCP Protocol (Full)

Standard MCP protocol with session management. Required for Claude Code and Claude Desktop.

| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| `/mcp` | GET | Yes | Server info |
| `/mcp` | POST | Yes | MCP protocol messages |
| `/mcp` | DELETE | Yes | Close session |

## License

ISC

## Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.