npm package: @igris-security/sdk
Description: Igris SDK — TypeScript client for the Igris MCP Gateway
Latest version: 0.1.1

<p align="center">
  <img src="https://raw.githubusercontent.com/cybertron288/igris/main/apps/www/public/logo.svg" alt="Igris" width="60" />
</p>

<h1 align="center">@igris-security/sdk</h1>

<p align="center">
  <strong>TypeScript SDK for the Igris MCP Gateway</strong>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@igris-security/sdk"><img src="https://img.shields.io/npm/v/@igris-security/sdk?color=teal&label=npm" alt="npm version" /></a>
  <a href="https://github.com/cybertron288/igris/blob/main/packages/sdk/LICENSE"><img src="https://img.shields.io/npm/l/@igris-security/sdk?color=blue" alt="license" /></a>
  <a href="https://docs.igris.dev"><img src="https://img.shields.io/badge/docs-igris.dev-teal" alt="docs" /></a>
</p>

<p align="center">
  Govern every MCP tool call. Enforce policies, track users, audit everything.
</p>

---

## What is Igris?

Igris is an **AI governance gateway** that sits between your AI agents and MCP servers. It enforces security policies, tracks who called what tool and when, detects anomalies, and gives you a complete audit trail.

The SDK connects your application to the Igris gateway with type-safe APIs.

## Install

```bash
# bun
bun add @igris-security/sdk

# npm
npm install @igris-security/sdk

# pnpm
pnpm add @igris-security/sdk
```

## Quick Start

```typescript
import { Igris } from "@igris-security/sdk";

const igris = new Igris({
  apiKey: "ig_your_api_key",
  baseUrl: "https://your-igris-instance.com", // optional, defaults to gateway.igris.dev
});

// Get MCP config for your AI agent
const mcpConfig = igris.getMcpConfig("my-connection", {
  user: "alice@company.com",
  metadata: { role: "developer", team: "platform" },
});

console.log(mcpConfig);
// {
//   url: "https://your-igris-instance.com/v1/mcp/my-connection",
//   headers: {
//     Authorization: "Bearer ig_your_api_key",
//     "X-Igris-Trace-Id": "ig_trace_a1b2c3d4e5f6g7h8",
//     "X-Igris-User": "alice@company.com",
//     "X-Igris-Metadata": '{"role":"developer","team":"platform"}'
//   }
// }
```

## Usage with MCP Clients

### Claude Desktop / Cursor / Windsurf

Use the SDK to generate the MCP config, then pass it to your MCP client:

```typescript
import { Igris } from "@igris-security/sdk";

const igris = new Igris({ apiKey: process.env.IGRIS_API_KEY! });

// Every tool call now flows through the Igris gateway
const config = igris.getMcpConfig("my-mcp-server", {
  user: "developer@company.com",
  traceId: "session-abc-123", // optional: correlate requests
  metadata: { role: "admin" }, // optional: used for policy conditions
});

// Use config.url and config.headers with your MCP client
```

### Standalone Function

If you don't need the full client, use `buildMcpConfig` directly:

```typescript
import { buildMcpConfig } from "@igris-security/sdk";

const config = buildMcpConfig(
  "ig_your_api_key",
  "https://your-igris-instance.com",
  "my-connection",
  { user: "alice@company.com" },
);
```

## Resource APIs

The SDK provides typed access to the Igris management API for programmatic control.

### Connections (Virtual Keys)

```typescript
// List all connections
const { data: connections } = await igris.virtualKeys.list();

// Get a specific connection by slug
const connection = await igris.virtualKeys.get("my-connection");
console.log(connection.upstreamUrl); // "https://my-mcp-server.com"
```

### Policies

```typescript
// List all policies
const { data: policies } = await igris.policies.list();

// List policies for a specific connection
const { data: filtered } = await igris.policies.list({
  virtualKeySlug: "my-connection",
});

// Get a specific policy
const policy = await igris.policies.get("policy-uuid");
console.log(policy.rules);
// [
//   { tool: "delete_*", action: "deny", conditions: { "metadata.role": "viewer" } },
//   { tool: "*", action: "allow" }
// ]
```

### Audit Events

```typescript
// List recent audit events
const { data: events } = await igris.auditEvents.list({ limit: 50 });

// Filter by user
const { data: userEvents } = await igris.auditEvents.list({
  userId: "alice@company.com",
});

// Filter by trace ID (correlate a session)
const { data: traceEvents } = await igris.auditEvents.list({
  traceId: "ig_trace_a1b2c3d4e5f6g7h8",
});

// Filter by connection
const { data: connectionEvents } = await igris.auditEvents.list({
  virtualKey: "my-connection",
  limit: 100,
  offset: 0,
});
```

## Identity & Tracing

Igris tracks **who** made each tool call and lets you correlate requests across sessions.

### User Identity

Pass `user` to attach a user identity to every tool call flowing through the gateway:

```typescript
const config = igris.getMcpConfig("my-connection", {
  user: "alice@company.com",
});
```

This shows up in the audit trail and can be used in policy conditions:

```json
{ "tool": "delete_*", "action": "deny", "conditions": { "metadata.role": "viewer" } }
```

### Trace IDs

Every request gets an auto-generated trace ID (`ig_trace_...`). You can also provide your own:

```typescript
const config = igris.getMcpConfig("my-connection", {
  traceId: "my-custom-trace-id",
});
```

Use trace IDs to correlate all tool calls within a single agent session.

### Metadata

Attach arbitrary key-value metadata for policy evaluation:

```typescript
const config = igris.getMcpConfig("my-connection", {
  user: "alice@company.com",
  metadata: {
    role: "developer",
    team: "platform",
    environment: "production",
  },
});
```

Metadata is available in policy conditions via dot notation: `metadata.role`, `metadata.team`, etc.

## Headers Reference

| Header | Description | Auto-generated |
|--------|-------------|:--------------:|
| `Authorization` | `Bearer <apiKey>` | Yes |
| `X-Igris-Trace-Id` | Trace ID for request correlation | Yes (overridable) |
| `X-Igris-User` | User identity string | No |
| `X-Igris-Metadata` | JSON-encoded metadata object | No |

## API Reference

### `new Igris(config)`

| Parameter | Type | Required | Description |
|-----------|------|:--------:|-------------|
| `config.apiKey` | `string` | Yes | Your Igris API key (starts with `ig_`) |
| `config.baseUrl` | `string` | No | Gateway URL. Defaults to `https://gateway.igris.dev` |

### `igris.getMcpConfig(slug, options?)`

Returns `{ url: string, headers: Record<string, string> }` for wiring into an MCP client.

| Parameter | Type | Required | Description |
|-----------|------|:--------:|-------------|
| `slug` | `string` | Yes | Connection slug (virtual key) |
| `options.user` | `string` | No | User identity |
| `options.traceId` | `string` | No | Custom trace ID (auto-generated if omitted) |
| `options.metadata` | `Record<string, string \| number \| boolean>` | No | Key-value pairs for policy conditions |

### `igris.virtualKeys`

| Method | Returns | Description |
|--------|---------|-------------|
| `.list()` | `PaginatedResponse<VirtualKey>` | List all connections |
| `.get(slug)` | `VirtualKey` | Get connection by slug |

### `igris.policies`

| Method | Returns | Description |
|--------|---------|-------------|
| `.list(params?)` | `PaginatedResponse<Policy>` | List policies. Filter with `{ virtualKeySlug }` |
| `.get(id)` | `Policy` | Get policy by ID |

### `igris.auditEvents`

| Method | Returns | Description |
|--------|---------|-------------|
| `.list(params?)` | `PaginatedResponse<AuditEvent>` | List audit events. Filter with `{ userId, traceId, virtualKey, limit, offset }` |

## Types

All types are exported from the package:

```typescript
import type {
  IgrisConfig,
  McpConfig,
  McpConfigOptions,
  VirtualKey,
  Policy,
  PolicyRule,
  AuditEvent,
  PaginatedResponse,
} from "@igris-security/sdk";
```

## Full Example

A complete example: an AI agent simulator that makes governed MCP tool calls through the Igris gateway with role-based policy enforcement.

```typescript
import { Igris } from "@igris-security/sdk";

// ── Setup ────────────────────────────────────────────────────
const igris = new Igris({
  apiKey: process.env.IGRIS_API_KEY!,
  baseUrl: "http://localhost:3100",
});

// ── Helper: Make a governed MCP tool call ────────────────────
async function callTool(
  connectionSlug: string,
  toolName: string,
  args: Record<string, unknown>,
  user: string,
  metadata: Record<string, string> = {},
) {
  // Get gateway config with user identity + metadata for policy evaluation
  const mcp = igris.getMcpConfig(connectionSlug, { user, metadata });

  // Make the JSON-RPC call through the gateway
  const res = await fetch(mcp.url, {
    method: "POST",
    headers: mcp.headers,
    body: JSON.stringify({
      jsonrpc: "2.0",
      method: "tools/call",
      params: { name: toolName, arguments: args },
      id: Date.now(),
    }),
  });

  const json = (await res.json()) as any;

  if (json.error) {
    return { allowed: false, error: json.error.message };
  }

  const text = json.result?.content?.[0]?.text;
  return { allowed: true, result: text ? JSON.parse(text) : json.result };
}

// ── Scenario: Role-based access control ──────────────────────
//
// Policy on the gateway:
//   { tool: "delete_*", action: "deny", conditions: { "metadata.role": "viewer" } }
//   { tool: "*", action: "allow" }

const CONNECTION = "my-mcp-server";

console.log("=== Admin user (full access) ===\n");

const weather = await callTool(
  CONNECTION,
  "get_weather",
  { city: "San Francisco" },
  "admin@company.com",
  { role: "admin" },
);
console.log(`  get_weather: ${weather.allowed ? "ALLOWED" : "DENIED"}`);

const deleteResult = await callTool(
  CONNECTION,
  "delete_record",
  { id: "rec_123" },
  "admin@company.com",
  { role: "admin" },
);
console.log(`  delete_record: ${deleteResult.allowed ? "ALLOWED" : "DENIED"}`);

console.log("\n=== Viewer user (restricted) ===\n");

const viewerWeather = await callTool(
  CONNECTION,
  "get_weather",
  { city: "Tokyo" },
  "viewer@company.com",
  { role: "viewer" },
);
console.log(`  get_weather: ${viewerWeather.allowed ? "ALLOWED" : "DENIED"}`);

const viewerDelete = await callTool(
  CONNECTION,
  "delete_record",
  { id: "rec_456" },
  "viewer@company.com",
  { role: "viewer" },
);
console.log(`  delete_record: ${viewerDelete.allowed ? "DENIED" : "ALLOWED"}`);
// → DENIED by policy: delete_* blocked for viewers

// ── Query the audit trail ────────────────────────────────────
console.log("\n=== Audit Trail ===\n");

const { data: events } = await igris.auditEvents.list({ limit: 10 });

for (const event of events) {
  console.log(
    `  [${event.policyAction?.toUpperCase().padEnd(5)}] ${event.toolName?.padEnd(20)} by ${event.userId ?? "unknown"}`,
  );
}
// Output:
//   [DENY ] delete_record        by viewer@company.com
//   [ALLOW] get_weather           by viewer@company.com
//   [ALLOW] delete_record         by admin@company.com
//   [ALLOW] get_weather           by admin@company.com

// ── List connections & policies ──────────────────────────────
const { data: connections } = await igris.virtualKeys.list();
console.log(`\nConnections: ${connections.map((c) => c.slug).join(", ")}`);

const { data: policies } = await igris.policies.list({
  virtualKeySlug: CONNECTION,
});
for (const policy of policies) {
  console.log(`\nPolicy: ${policy.name}`);
  for (const rule of policy.rules) {
    console.log(`  ${rule.tool} → ${rule.action}`);
  }
}
```

Save as `demo.ts` and run:

```bash
IGRIS_API_KEY=ig_your_key bun demo.ts
```

## Requirements

- Node.js 18+ or Bun 1.0+
- An Igris API key ([get one from the dashboard](https://app.igris.dev/settings))

## Links

- [Documentation](https://docs.igris.dev)
- [Dashboard](https://app.igris.dev)
- [GitHub](https://github.com/cybertron288/igris)
- [npm](https://www.npmjs.com/package/@igris-security/sdk)

## License

MIT