> ## Documentation Index
> Fetch the complete documentation index at: https://docs.centure.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Integration

> Secure Model Context Protocol applications with automatic prompt injection detection

The `@centure/node-sdk` provides a transport wrapper for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) that automatically scans messages for prompt injection attacks before they reach your MCP server.

## What is MCP?

The Model Context Protocol is a standard for connecting AI models to external tools and data sources. The Centure SDK intercepts MCP messages to detect and block malicious prompts.

## Installation

Install both the Centure SDK and the MCP SDK:

<CodeGroup>
  ```bash npm theme={null}
  npm install @centure/node-sdk @modelcontextprotocol/sdk
  ```

  ```bash yarn theme={null}
  yarn add @centure/node-sdk @modelcontextprotocol/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @centure/node-sdk @modelcontextprotocol/sdk
  ```
</CodeGroup>

## Basic Setup

Wrap any MCP transport with `CentureMCPClientTransport` to add automatic scanning:

```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { CentureClient } from "@centure/node-sdk";
import { CentureMCPClientTransport } from "@centure/node-sdk/mcp";

// Create your underlying MCP transport
const stdioTransport = new StdioClientTransport({
  command: "your-mcp-server",
  args: ["--arg1", "--arg2"],
});

// Wrap it with Centure security scanning
const secureTransport = new CentureMCPClientTransport({
  client: new CentureClient({
    apiKey: process.env.CENTURE_API_KEY,
  }),
  transport: stdioTransport,
});

// Use with MCP client
const client = new Client({
  name: "your-client",
  version: "1.0.0",
});

await client.connect(secureTransport);
```

<Info>
  The transport intercepts all messages sent through the MCP client and scans them before forwarding to the server.
</Info>

## Configuration Hooks

The transport provides hooks to customize scanning behavior:

### shouldScanMessage

Determines whether a specific message should be scanned. Return `false` to skip scanning.

```typescript theme={null}
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  shouldScanMessage: ({ message, extra }) => {
    // Skip scanning for tool list requests
    if (message.method === "tools/list") {
      return false;
    }

    // Skip scanning for specific notification types
    if (extra?.notification && extra.notification === "progress") {
      return false;
    }

    return true;
  },
});
```

**Parameters:**

* `message` (JSONRPCMessage) - The MCP message to potentially scan
* `extra` (MessageExtraInfo) - Additional context about the message

**Returns:** `boolean` or `{ scan: boolean }`

### onAfterScan

Called after a message is scanned, regardless of the result. Use this for logging or metrics.

```typescript theme={null}
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  onAfterScan: ({ message, scanResult }) => {
    // Log all scan results
    console.log(`Scanned ${message.method}:`, {
      safe: scanResult.is_safe,
      categories: scanResult.categories,
      requestId: scanResult.request_id,
    });

    // Optionally allow unsafe messages to pass through
    if (scanResult.categories.every((c) => c.confidence === "low")) {
      return { passthrough: true };
    }
  },
});
```

**Parameters:**

* `message` (JSONRPCMessage) - The scanned message
* `extra` (MessageExtraInfo) - Additional context
* `scanResult` (ScanResponse) - The scan result from Centure API

**Returns:** `void` or `{ passthrough: boolean }`

### onUnsafeMessage

Called when an unsafe message is detected. Controls whether to block or allow the message.

```typescript theme={null}
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  onUnsafeMessage: ({ message, scanResult }) => {
    // Allow medium-confidence threats
    const isMedium = scanResult.categories.every(
      (c) => c.confidence === "medium"
    );

    if (isMedium) {
      console.warn("Allowing medium-confidence threat:", scanResult.categories);
      return { passthrough: true };
    }

    // Block high-confidence threats with custom error
    console.error("Blocking high-confidence threat:", scanResult.categories);
    return {
      passthrough: false,
      replace: {
        jsonrpc: "2.0",
        id: message.id,
        error: {
          code: -32001,
          message: "Security violation: prompt injection detected",
          data: {
            categories: scanResult.categories,
            requestId: scanResult.request_id,
          },
        },
      },
    };
  },
});
```

**Parameters:**

* `message` (JSONRPCMessage) - The unsafe message
* `extra` (MessageExtraInfo) - Additional context
* `scanResult` (ScanResponse) - The scan result from Centure API

**Returns:** `{ passthrough: boolean, replace?: JSONRPCMessage }`

<Warning>
  Always return an object from `onUnsafeMessage`. Set `passthrough: false` to block the message and optionally provide a `replace` message to send instead.
</Warning>

### onBeforeSend

Called before any message is sent through the transport, before scanning occurs.

```typescript theme={null}
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  onBeforeSend: ({ message, extra }) => {
    console.log(`Sending ${message.method} to MCP server`);
  },
});
```

**Parameters:**

* `message` (JSONRPCMessage) - The message about to be sent
* `extra` (MessageExtraInfo) - Additional context

**Returns:** `void`

## Complete Example

Here's a production-ready configuration with all hooks:

```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { CentureClient } from "@centure/node-sdk";
import { CentureMCPClientTransport } from "@centure/node-sdk/mcp";

// Initialize Centure client
const centureClient = new CentureClient({
  apiKey: process.env.CENTURE_API_KEY,
});

// Create base MCP transport
const stdioTransport = new StdioClientTransport({
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
});

// Wrap with security scanning
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  // Skip scanning for safe methods
  shouldScanMessage: ({ message }) => {
    const safeMethods = [
      "initialize",
      "tools/list",
      "resources/list",
      "prompts/list",
    ];

    if (safeMethods.includes(message.method)) {
      return false;
    }

    return true;
  },

  // Log all scan results
  onAfterScan: ({ message, scanResult }) => {
    if (!scanResult.is_safe) {
      console.warn(`Unsafe message detected in ${message.method}:`, {
        categories: scanResult.categories,
        requestId: scanResult.request_id,
      });
    }
  },

  // Handle unsafe messages
  onUnsafeMessage: ({ message, scanResult }) => {
    // Allow low and medium confidence detections with logging
    const maxConfidence = scanResult.categories.reduce(
      (max, cat) => {
        const levels = { low: 1, medium: 2, high: 3 };
        return Math.max(max, levels[cat.confidence]);
      },
      0
    );

    if (maxConfidence < 3) {
      console.warn("Allowing non-high confidence threat");
      return { passthrough: true };
    }

    // Block high-confidence threats
    console.error("BLOCKED: High-confidence prompt injection");
    return {
      passthrough: false,
      replace: {
        jsonrpc: "2.0",
        id: message.id,
        error: {
          code: -32001,
          message: "Request blocked: security violation detected",
          data: {
            requestId: scanResult.request_id,
            categories: scanResult.categories.map((c) => c.code),
          },
        },
      },
    };
  },

  // Log all outgoing messages
  onBeforeSend: ({ message }) => {
    console.log(`→ ${message.method}`);
  },
});

// Connect MCP client
const client = new Client({
  name: "secure-mcp-client",
  version: "1.0.0",
});

await client.connect(secureTransport);

// Use the client normally
const tools = await client.listTools();
console.log("Available tools:", tools);
```

## Transport Types

### CentureMCPClientTransportOptions

Configuration options for the transport wrapper:

```typescript theme={null}
interface CentureMCPClientTransportOptions {
  client: CentureClient;
  transport: Transport;
  shouldScanMessage?: (context: ShouldScanMessageContext) => boolean | ShouldScanMessageResult;
  onAfterScan?: (context: OnAfterScanContext) => void | OnAfterScanResult;
  onUnsafeMessage?: (context: OnUnsafeMessageContext) => OnUnsafeMessageResult;
  onBeforeSend?: (context: { message: JSONRPCMessage; extra?: MessageExtraInfo }) => void;
}
```

### Hook Context Types

```typescript theme={null}
type ShouldScanMessageContext = {
  message: JSONRPCMessage;
  extra?: MessageExtraInfo;
};

type OnAfterScanContext = {
  message: JSONRPCMessage;
  extra?: MessageExtraInfo;
  scanResult: ScanResponse;
};

type OnUnsafeMessageContext = {
  message: JSONRPCMessage;
  extra?: MessageExtraInfo;
  scanResult: ScanResponse;
};

type OnUnsafeMessageResult = {
  passthrough: boolean;
  replace?: JSONRPCMessage;
};
```

## Best Practices

<Tip>
  **Block high-confidence threats:** Always block messages with `high` confidence detections in production environments.
</Tip>

<Tip>
  **Log all detections:** Use `onAfterScan` to log scanning results for security monitoring and incident response.
</Tip>

<Tip>
  **Skip safe methods:** Use `shouldScanMessage` to skip scanning for methods that cannot carry threats (e.g., `tools/list`, `initialize`).
</Tip>

<Tip>
  **Provide clear error messages:** When blocking messages, include the `request_id` in error responses for debugging and support.
</Tip>

<Warning>
  Do not allow `high` confidence detections to pass through without careful review. These indicate strong evidence of prompt injection attacks.
</Warning>

## Supported Transports

The `CentureMCPClientTransport` works with any MCP transport implementation:

* **StdioClientTransport** - Communicate with servers via stdin/stdout
* **SSEClientTransport** - Communicate with servers via Server-Sent Events
* **Custom transports** - Any transport implementing the MCP Transport interface

## Error Handling

The transport handles scanning errors gracefully:

```typescript theme={null}
const secureTransport = new CentureMCPClientTransport({
  client: centureClient,
  transport: stdioTransport,

  onAfterScan: ({ message, scanResult }) => {
    // This hook runs even if scanning fails
    // Check if scanResult indicates an error
  },
});
```

<Note>
  If the Centure API is unreachable or returns an error, the message is blocked by default. Use `onAfterScan` to implement custom fallback behavior.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/sdk/nodejs-quickstart">
    Get started with basic SDK usage
  </Card>

  <Card title="API Reference" icon="book" href="/sdk/nodejs-reference">
    Explore response types and configuration options
  </Card>

  <Card title="MCP Documentation" icon="external-link" href="https://modelcontextprotocol.io">
    Learn more about the Model Context Protocol
  </Card>

  <Card title="GitHub Repository" icon="github" href="https://github.com/centure-ai/typescript-sdk">
    View source code and examples
  </Card>
</CardGroup>
