Docs / Surface / ai/mcp-server

MCP Server

Surface exposes an MCP-compatible JSON-RPC endpoint so AI assistants can scan files and payloads for malware without writing HTTP client code.

There are three ways to connect:

Local scanning (scanner binary)#

For local scanning, point your MCP client straight at the scanner binary — no Node/npm layer required:

json

{
  "mcpServers": {
    "surface": {
      "command": "surface-scanner",
      "args": ["--mcp"],
      "env": { "SURFACE_API_KEY": "<token-from-the-dashboard>" }
    }
  }
}

This runs the binary as a native stdio MCP server exposing three tools, all scanned locally. Nothing about a scan leaves your machine: the server reports records only when it is started with --report-results.

Tool Description
scan_payload Scan raw text content: messages, JSON, code snippets, tool calls (10 MB cap, same as --stdin)
scan_file Scan a file by absolute path
scan_bundle Scan several payloads (e.g. main.py, boot.py, config.json) in one call and get an aggregate deploy_safe go/no-go, for gating a device deployment before you flash

The API key also unlocks the account tools and keeps threat feeds updating automatically. Add --report-results to the args if you additionally want each local scan recorded in your dashboard history, which counts it against your monthly quota:

json

{
  "mcpServers": {
    "surface": {
      "command": "surface-scanner",
      "args": ["--mcp"],
      "env": { "SURFACE_API_KEY": "${SURFACE_API_KEY}" }
    }
  }
}

With the key set, tools/list additionally includes these tools, which call the hosted Surface API (only these calls go over the network — scanning stays local either way):

Tool Description
get_scan Retrieve results for a deferred scan by scan ID
get_scan_history Browse past scans (paginated)
get_scan_detail Full result for a historical scan
get_usage Check scan quota (used vs monthly limit)
get_account Account details
get_plans List available billing plans and scan limits
list_profiles List available scan profiles and their configurations
create_profile Create a new scan profile
update_profile Update an existing scan profile
delete_profile Delete a scan profile
list_api_keys List Surface API keys (metadata only — secrets are never returned)

If the API is unreachable, account tool calls return a clean error and the scanning tools keep working — local scans never depend on the network.

On a first-ever launch the binary downloads threat feeds in the background; the MCP handshake completes immediately and the first scan tool call waits until feeds are ready (progress is logged to stderr). Account tools don't wait — they work as soon as the server is up.

The scanner's daemon mode also serves MCP over streamable HTTP at http://localhost:8080/mcp, for url-based clients that should share one long-running local scanner.

If you also want API key create/delete tools, the Surface skills, or the .mcpb bundle, use the npx github:tendrl-inc-labs/surface-mcp server instead. Doc search (search_docs) is a hosted-endpoint tool only; the npx server publishes the docs as MCP resources under surface://docs/... rather than as a search tool.

Hosted endpoint#

code

POST https://app.tendrl.com/surface/mcp

Requires an API key: Authorization: Bearer <API_KEY>. The endpoint is POST-only JSON-RPC.

Note

The hosted endpoint is being validated against url-based MCP clients. If a url client fails to connect, use the local npx github:tendrl-inc-labs/surface-mcp server instead.

Hosted tools#

Tool Description
scan_payload Scan raw text content: messages, JSON, code snippets, tool calls. Detects prompt injection, SQL/XSS injection, credential leaks, malicious code
get_scan Retrieve results for a deferred scan by scan ID
get_scan_history Browse past scans (paginated)
get_scan_detail Full result for a historical scan
list_profiles List available scan profiles and their configurations
create_profile Create a new scan profile
update_profile Update an existing scan profile
delete_profile Delete a scan profile
get_account Account details
get_usage Check scan quota (used vs monthly limit)
list_api_keys List Surface API keys
get_plans List available billing plans and scan limits
search_docs Search Surface documentation and return relevant snippets

The hosted endpoint does not scan files. To scan files via MCP, use the scanner binary's --mcp mode or the local npx github:tendrl-inc-labs/surface-mcp server — both expose a scan_file tool.

Client setup (hosted endpoint)#

These configs point a url-based client at the hosted endpoint.

Cursor#

In .cursor/mcp.json:

json

{
  "mcpServers": {
    "surface": {
      "url": "https://app.tendrl.com/surface/mcp",
      "headers": {
        "Authorization": "Bearer <SURFACE_API_KEY>"
      }
    }
  }
}

VS Code#

In .vscode/mcp.json:

json

{
  "servers": {
    "surface": {
      "type": "http",
      "url": "https://app.tendrl.com/surface/mcp",
      "headers": { "Authorization": "Bearer <SURFACE_API_KEY>" }
    }
  }
}

Claude Desktop#

In claude_desktop_config.json:

json

{
  "mcpServers": {
    "surface": {
      "url": "https://app.tendrl.com/surface/mcp",
      "headers": {
        "Authorization": "Bearer <SURFACE_API_KEY>"
      }
    }
  }
}

Local server (npx)#

Surface's local stdio MCP server installs straight from its GitHub repository — there is no npm package to publish or trust. If local scanning plus the account tools covers you, the scanner binary's --mcp mode does that with no Node layer at all — reach for this package when you also want API key create/delete, the Surface skills, or a .mcpb bundle, or when a url-based client can't reach the hosted endpoint. It exposes a different toolset from the hosted endpoint — broader in most respects, but without search_docs:

It also serves the Surface skills as MCP resources (see AI Skills). The hosted endpoint serves documentation as resources but not skills.

Install it by repository, not by name. An unrelated third-party package
called surface-mcp exists on npm; installing that name runs someone else's
code. The github:tendrl-inc-labs/surface-mcp specifier below is
unambiguous, and npm builds it from source on install.

Add it to your MCP client config:

json

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

By default, scan_file, scan_payload, and scan_bundle upload to the Surface API. To scan locally (content never leaves your machine), set SURFACE_SCANNER_PATH to a local scanner binary. All three then run every scan through the local binary instead:

json

{
  "mcpServers": {
    "surface": {
      "command": "npx",
      "args": ["-y", "github:tendrl-inc-labs/surface-mcp"],
      "env": {
        "SURFACE_KEY": "${SURFACE_KEY}",
        "SURFACE_SCANNER_PATH": "/path/to/scanner"
      }
    }
  }
}

See Scanner Binary for details on local vs API mode.