@centure/node-sdk
A fully type-safe TypeScript SDK for interacting with Centure's API for prompt injection detection.
Installation
npm install @centure/node-sdk
Usage
Initialize the Client
import { CentureClient } from "@centure/node-sdk";
const client = new CentureClient();
const client = new CentureClient({
apiKey: "your-api-key",
baseUrl: "https://api.centure.ai",
});
Scan Text for Prompt Injection
const result = await client.scanText("Your text content here");
console.log("Is safe:", result.is_safe);
console.log("Detected categories:", result.categories);
console.log("Reason:", result.reason);
console.log("Request ID:", result.request_id);
Scan with Options
Both scanText and scanImage accept an optional ScanOptions parameter:
const result = await client.scanText("content", {
only: ["data_exfiltration", "unauthorized_actions"],
});
const result = await client.scanText("content", {
exclude: ["output_manipulation"],
});
const result = await client.scanText("content", {
minimum_confidence: "high",
});
Scan Options
All options are optional.
only | RiskCategory[]? | Only return detections for these categories. Cannot be used with exclude. |
exclude | RiskCategory[]? | Exclude detections for these categories. Cannot be used with only. |
minimum_confidence | "medium" | "high"? | Minimum confidence level for detections. |
Scan Image (Base64 or Buffer)
const base64Image = "iVBORw0KGgoAAAANSUhEUgAA...";
const result = await client.scanImage(base64Image);
console.log("Is safe:", result.is_safe);
console.log("Detected threats:", result.categories);
import fs from "fs";
const imageBuffer = fs.readFileSync("./image.png");
const result = await client.scanImage(imageBuffer);
API Response
All scan methods return a ScanResponse object:
interface ScanResponse {
is_safe: boolean;
categories: DetectedCategory[];
reason?: string;
request_id: string;
api_key_id: string;
request_units: number;
billed_request_units: number;
service_tier: ServiceTier;
}
interface DetectedCategory {
code: ThreatCategory;
confidence: ConfidenceLevel;
}
is_safe | boolean | Whether the content is safe (no prompt injection detected) |
categories | DetectedCategory[] | List of detected threat categories |
reason | string? | Explanation when content is flagged |
request_id | string | Unique identifier for this request |
api_key_id | string | ID of the API key used |
request_units | number | Number of request units consumed |
billed_request_units | number | Number of request units billed |
service_tier | ServiceTier | Service tier used for the request |
MCP Integration
The SDK provides a transport wrapper for the Model Context Protocol (MCP) that automatically scans messages for prompt injection attacks.
CentureMCPClientTransport
The CentureMCPClientTransport wraps any MCP transport and intercepts messages to scan them for security threats before they reach your MCP server.
Basic Usage
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";
const stdioTransport = new StdioClientTransport({
command: "your-mcp-server",
args: ["--arg1", "--arg2"],
});
const secureTransport = new CentureMCPClientTransport({
client: new CentureClient({
apiKey: "your-api-key",
}),
transport: stdioTransport,
});
const client = new Client({
name: "your-client",
version: "1.0.0",
});
await client.connect(secureTransport);
Configuration Parameters
Required Parameters
transport (Transport): The underlying MCP transport to wrap (e.g., StdioClientTransport, SSEClientTransport)
client (CentureClient): Centure API client instance for scanning messages
Optional Hooks
-
shouldScanMessage ((context: ShouldScanMessageContext) => boolean | ShouldScanMessageResult):
Determines whether a specific message should be scanned. Return false or { scan: false } to skip scanning.
shouldScanMessage: ({ message, extra }) => {
if (message.method === "tool/list") {
return false;
}
return true;
};
-
onAfterScan ((context: OnAfterScanContext) => void | OnAfterScanResult):
Called after a message is scanned, regardless of the result. Can return { passthrough: true } to allow the message even if unsafe.
onAfterScan: ({ message, scanResult }) => {
console.log(`Scanned ${message.method}: ${scanResult.is_safe}`);
};
-
onUnsafeMessage ((context: OnUnsafeMessageContext) => OnUnsafeMessageResult):
Called when an unsafe message is detected. Must return an object specifying whether to allow or block the message.
onUnsafeMessage: ({ message, scanResult }) => {
const isMedium = scanResult.categories.every(
(c) => c.confidence === "medium",
);
if (isMedium) {
return { passthrough: true };
}
return {
passthrough: false,
replace: {
jsonrpc: "2.0",
id: message.id,
error: {
code: -32001,
message: "Security violation detected",
},
},
};
};
-
onBeforeSend ((context: { message: JSONRPCMessage, extra?: MessageExtraInfo }) => void):
Called before any message is sent through the transport.
onBeforeSend: ({ message, extra }) => {
console.log(`Sending ${message.method}`);
};
Complete Example
const secureTransport = new CentureMCPClientTransport({
client: new CentureClient({
baseUrl: "http://localhost:3001",
apiKey: "your-api-key",
}),
transport: stdioTransport,
shouldScanMessage: ({ message }) => {
if (message.method === "tool/list") {
return false;
}
return true;
},
onUnsafeMessage: ({ message, scanResult }) => {
const isMedium = scanResult.categories.every(
(c) => c.confidence === "medium",
);
if (isMedium) {
return { passthrough: true };
}
return {
passthrough: false,
replace: {
jsonrpc: "2.0",
id: message.id,
error: {
code: -32001,
message: "Unsafe Message!",
},
},
};
},
});
Hook Types
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;
};
Error Handling
The SDK provides specific error classes for different scenarios:
import {
CentureClient,
BadRequestError,
UnauthorizedError,
PayloadTooLargeError,
MissingApiKeyError,
} from "@centure/node-sdk";
try {
const result = await client.scanText("content");
} catch (error) {
if (error instanceof UnauthorizedError) {
console.error("Invalid API key");
} else if (error instanceof BadRequestError) {
console.error("Invalid request:", error.message);
} else if (error instanceof PayloadTooLargeError) {
console.error("Image too large");
}
}
Configuration
Custom Fetch Options
const client = new CentureClient({
apiKey: "your-api-key",
fetchOptions: {
timeout: 30000,
headers: {
"X-Custom-Header": "value",
},
},
});
Custom Fetch Implementation
import fetch from "node-fetch";
const client = new CentureClient({
apiKey: "your-api-key",
fetch: fetch as any,
});
Threat Categories
The API detects the following threat categories:
output_manipulation | Controls AI output content, formatting, or style |
context_injection | Fake context, roles, system messages, or instruction overrides |
data_exfiltration | Attempts to extract sensitive data |
unauthorized_actions | Attempts to trigger unauthorized actions or API calls |
License
MIT