Skip to main content
Glama
tendrl-inc-labs

Surface MCP Server

README.md
# Surface MCP Server

Model Context Protocol server for [Surface](https://tendrl.com/docs/surface/). Gives any MCP-compatible AI assistant (Claude, etc.) the ability to scan files, manage accounts, and access SDK/API documentation.

## Install

```bash
npx -y github:tendrl-inc-labs/surface-mcp
```

npm clones this repository and builds it from source on install, so there is
nothing to publish and nothing stale to serve.

Install by repository, not by name: an unrelated third party owns the name
`surface-mcp` on npm, and installing that name runs their code.

In an MCP client config:

```json
{
  "mcpServers": {
    "surface": {
      "command": "npx",
      "args": ["-y", "github:tendrl-inc-labs/surface-mcp"],
      "env": {
        "SURFACE_KEY": "${SURFACE_KEY}"
      }
    }
  }
}
```

## Build from source

```bash
git clone https://github.com/tendrl-inc-labs/surface-mcp
cd surface-mcp
npm install
npm run build
```

## Configuration

Set your API key:

```bash
export SURFACE_KEY="sfk_your_token_here"
```

### Optional: Local Scanner

Point `SURFACE_SCANNER_PATH` at the Surface scanner binary to scan files locally. Files never leave your machine — the binary runs on your hardware and reports results to the server.

```bash
export SURFACE_SCANNER_PATH="/usr/local/bin/surface-scanner"
```

When this is not set, `scan_file` uploads to the API instead.

### Optional: Custom API URL

Set a custom base URL (defaults to `https://app.tendrl.com/surface`):

```bash
export SURFACE_BASE_URL="http://localhost:9080/api"
```

## Usage with Claude Desktop

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "surface": {
      "command": "node",
      "args": ["/path/to/surface/mcp-server/dist/index.js"],
      "env": {
        "SURFACE_KEY": "sfk_your_token_here"
      }
    }
  }
}
```

With local scanner (files never leave your machine):

```json
{
  "mcpServers": {
    "surface": {
      "command": "node",
      "args": ["/path/to/surface/mcp-server/dist/index.js"],
      "env": {
        "SURFACE_KEY": "sfk_your_token_here",
        "SURFACE_SCANNER_PATH": "/usr/local/bin/surface-scanner"
      }
    }
  }
}
```

## Usage with Claude Code

Add to your Claude Code settings:

```bash
# API mode (uploads to server)
claude mcp add surface node /path/to/surface/mcp-server/dist/index.js -e SURFACE_KEY=sfk_your_token_here

# Local scanner mode (files stay on your machine)
claude mcp add surface node /path/to/surface/mcp-server/dist/index.js -e SURFACE_KEY=sfk_your_token_here -e SURFACE_SCANNER_PATH=/usr/local/bin/surface-scanner
```

## Tools

| Tool | Description |
|------|-------------|
| `scan_file` | Upload and scan a file for malware (accepts absolute file path) |
| `scan_payload` | Scan raw content for threats — detects prompt injection, SQL/XSS injection, credential leaks, malicious code, and suspicious tool calls. Accepts raw text (default) or base64 for binary. Max 10 MB. Takes an optional `context` for action screening (see below). |
| `get_scan` | Poll a deferred scan result by scan ID |
| `get_account` | Get account details |
| `get_usage` | Get scan usage vs monthly limit |
| `list_profiles` | List scan profiles |
| `create_profile` | Create a scan profile |
| `update_profile` | Update a scan profile |
| `delete_profile` | Delete a scan profile |
| `list_api_keys` | List API keys |
| `create_api_key` | Create an API key |
| `delete_api_key` | Delete an API key |
| `get_scan_history` | Get paginated scan history |
| `get_scan_detail` | Get full details of a historical scan |
| `get_plans` | Get available billing plans |

### Action screening context

When `scan_payload` (or `scan_bundle`) receives a tool call an agent is about to make, some actions are dangerous on their own (deleting a database, a secret in a URL, a crypto-address payout) and some only relative to you — data is only leaking if it leaves your domains or goes to a host you never declared. Pass an optional `context` object so the screener can decide confidently instead of defaulting to "Review":

```json
{
  "payload": "{\"tool\":\"http_request\",\"args\":{\"method\":\"POST\",\"url\":\"https://webhook.partner.io/sync\",\"body\":{}}}",
  "context": {
    "principal_domains": ["acme.io"],
    "allowed_egress": ["api.stripe.com", "hooks.slack.com"],
    "user_request": "sync this week's tickets to our partner"
  }
}
```

- **Data egress** leaving `principal_domains` (or to a free-mail address) is flagged; with `allowed_egress` set, a POST to a host on neither list is flagged for review while a Stripe or Slack call passes. A bare-IP destination or a secret in the body flags even without context.
- **Dangerous on its face** — crypto and gift-card payouts, `rm -rf` of a data directory, admin grants — flag with no context.
- Build `context` from **trusted host state**, never from the payload being scanned. It is optional; omit it for face-value screening.

## Resources

| Resource | URI | Description |
|----------|-----|-------------|
| API Reference | `surface://docs/api-reference` | Complete REST API documentation |
| SDK Quick Reference | `surface://docs/sdk-overview` | Side-by-side SDK comparison |
| Webhook Guide | `surface://docs/webhooks` | Webhook setup and signature verification |
| Python SDK Docs | `surface://docs/sdk/python` | Python SDK README |
| JavaScript SDK Docs | `surface://docs/sdk/javascript` | JS/TS SDK README |
| Go SDK Docs | `surface://docs/sdk/go` | Go SDK README |
| SDK Source Files | `surface://src/sdk/{lang}/*` | SDK source code (client, models, errors, webhook) |

## Agentic Security

The `scan_payload` tool is designed for AI agent workflows. When an agent scans a payload, Surface automatically detects:

- **Prompt injection** — jailbreak attempts, role hijacking, instruction overrides
- **SQL injection** — union attacks, tautology auth bypass, blind injection
- **XSS injection** — script tags, event handlers, javascript: URIs
- **Credential exposure** — API keys, tokens, private keys, connection strings
- **Malicious code** — reverse shells, download cradles, eval/exec chains
- **Suspicious tool calls** — dangerous execute/write/http operations
- **Known malicious URLs** — checked against threat intelligence feeds

Results include `promptInjection`, `codeExtraction`, `sensitiveData`, and `toolCallAnalysis` fields with detailed findings.

## Prompts

| Prompt | Description |
|--------|-------------|
| `analyze_scan_result` | Analyze a scan result JSON and provide security assessment |
| `generate_sdk_code` | Generate SDK code for a given language and use case |