# Textual MCP Server

The [Textual MCP Server](https://github.com/TonicAI/textual-mcp) is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that connects AI assistants to Tonic Textual to detect and de-identify sensitive values.

## Prerequisites

* Node.js version 18.0.0 or higher.
* Textual instance, either Textual Cloud or a self-hosted instance.
* [Textual API key](https://docs.tonic.ai/textual/tonic-textual-api/textual-api-keys).

## Installing the server

### From npm

```
npm install -g @tonicai/textual-mcp
```

### From source

```
git clone https://github.com/TonicAI/textual-mcp.git
cd textual-mcp
npm install
npm run build
```

## Configuring the server

To configure the server, set the following environment variables:

<table><thead><tr><th width="341.69140625" valign="top">Variable</th><th width="198.44921875" valign="top">Description</th><th valign="top">Default</th></tr></thead><tbody><tr><td valign="top"><code>TONIC_TEXTUAL_API_KEY</code></td><td valign="top">Required. Your Textual API key.</td><td valign="top">—</td></tr><tr><td valign="top"><code>TONIC_TEXTUAL_BASE_URL</code></td><td valign="top">Base URL of your Textual instance.</td><td valign="top"><code>https://textual.tonic.ai</code></td></tr><tr><td valign="top"><code>PORT</code></td><td valign="top">HTTP port for the MCP server.</td><td valign="top"><code>3000</code></td></tr><tr><td valign="top"><code>TONIC_TEXTUAL_MAX_CONCURRENT_REQUESTS</code></td><td valign="top">Maximum number of concurrent requests to the Textual API.</td><td valign="top"><code>50</code></td></tr><tr><td valign="top"><code>TONIC_TEXTUAL_POLL_TIMEOUT_SECONDS</code></td><td valign="top">Timeout (in seconds) for polling file processing jobs.</td><td valign="top"><code>900</code></td></tr><tr><td valign="top"><code>TONIC_TEXTUAL_LOG_DIR</code></td><td valign="top">Directory for structured log files.</td><td valign="top"><code>./logs</code></td></tr></tbody></table>

## Running the server

When you run the server, you must provide `TONIC_TEXTUAL_API_KEY`.

For a self-hosted Textual instance, you must also set `TONIC_TEXTUAL_BASE_URL`.

### Global install

{% code overflow="wrap" %}

```
# Textual Cloud
TONIC_TEXTUAL_API_KEY=your-key textual-mcp

# Self-hosted instance
TONIC_TEXTUAL_API_KEY=your-key TONIC_TEXTUAL_BASE_URL=https://your-instance.example.com textual-mcp
```

{% endcode %}

### From source

{% code overflow="wrap" %}

```
# Tonic Textual cloud
TONIC_TEXTUAL_API_KEY=your-key npm start

# Self-hosted instance
TONIC_TEXTUAL_API_KEY=your-key TONIC_TEXTUAL_BASE_URL=https://your-instance.example.com npm start
```

{% endcode %}

### Start and health check locations

By default, the server starts on `http://localhost:3000/mcp`.

A health check endpoint is available at `http://localhost:3000/health`.

## Adding to Claude

{% hint style="info" %}
Before you add it to your Claude client, you must [start the MCP server](#running-the-server).
{% endhint %}

### Claude Code

With the server running, register it as an HTTP transport:

```
claude mcp add --transport http textual-mcp http://localhost:3000/mcp
```

### Claude Desktop

With the server running, add the following to your Claude Desktop config file.

On macOS, the file is `~/Library/Application Support/Claude/claude_desktop_config.json`.

```
{
  "mcpServers": {
    "textual-mcp": {
      "type": "http",
      "url": "http://localhost:3000/mcp"
    }
  }
}
```

## Available tools and examples

Once the server is running and connected to your MCP client, you can use natural language to interact with Textual in order to perform the following types of tasks.

### Redacting text

You can send requests to redact entities text, including:

* Entities in a single plain text string.
* Entities in a set of plain text strings.
* Entities in a JSON string. The output preserves the JSON structure.
* Entities in an XML string. The output preserves the XML structure.
* Entities in a HTML string. The output preserves the HTML structure.

When you send a request to redact text, you can specify the following configuration information:

* For specific entity types, the handling option. Indicates whether to redact, synthesize, or ignore the value.
* The default handling option to use for all entity types.
* Any specific configuration to use to generate realistic replacement values for specific entity types.
* Any custom entity types to include in the detection.
* For specific entity types, regular expressions and string patterns to identify values to exclude from detection as that entity type.
* For specific entity types, regular expressions and string patterns to identify additional values to include in the detection for that entity type.

Here are example text redaction requests to the MCP server:

`"Redact the PII from this text: John Smith lives at 123 Main St and his SSN is 456-78-9012"`

`"Redact this text using synthesis for names and redaction for SSNs: John Smith's SSN is 456-78-9012"`

### Redacting files

You can send requests to redact and download redacted binary files.

Supports .pdf, .docx, .xslx, .jpg, and .png.

Here is an example request to redact and download a file:

`"Redact all PII from /path/to/document.pdf and save it to /path/to/output.pdf"`

### Redact files in a directory

You can send requests to:

* Scan the files in a directory. Returns the file types, sizes and counts.
* Redact all of the files in the directory. Preserves the file structure. You can optionally redact the folder and file names.

Here is an example request to scan and then redact a directory:

`"Scan /path/to/documents first, then de-identify the whole folder to /path/to/output, skipping any .log files"`

### Managing datasets

You can send requests to:

* Create a Textual dataset.
* List the datasets in Textual.
* Get details about a dataset, including the file list and processing status.
* Upload files to a dataset.
* Download files from a dataset.

Here is an example request to create a dataset, upload files to it, and then retrieve the redacted files:

`"Create a new dataset called 'training-data', upload all the files in /path/to/docs, and download the redacted versions when they're done"`

### Job monitoring

You can send requests to:

* Get a list of redaction jobs with their statuses.
* Get the status of a specific job.
* Download the error logs for a failed job.

Here is an example request to return a list of redaction jobs:

`"List all file redaction jobs from the last hour"`

### Listing entity types

You can ask Textual to return the list of entity types that Textual can detect.

`"Get me the list of Textual entity types."`
