Install the official client:
npm install @kumokodo/kodori-sdk
REST quickstart:
import { KodoriClient } from '@kumokodo/kodori-sdk';
const kodori = new KodoriClient({ apiKey: process.env.KODORI_API_KEY! });
const me = await kodori.me.get(); const { hits } = await kodori.search.run({ query: 'indemnity clause', limit: 10 }); const doc = await kodori.documents.get(hits[0].documentId);
The SDK ships typed methods for every /api/v1 endpoint:
- **me** — GET /api/v1/me (identity probe + scope list) - **search.run({ query, limit })** — POST /api/v1/search (hybrid keyword + semantic) - **documents.list / get / rename / setSensitivity / setMetadata / tombstone / restore** - **collections.list / create / addMember / removeMember**
**Typed errors.** Non-2xx responses throw KodoriApiError with status, machine-readable code, optional details payload, and the underlying Response:
import { KodoriApiError } from '@kumokodo/kodori-sdk';
try { await kodori.documents.tombstone(id, 'duplicate'); } catch (err) { if (err instanceof KodoriApiError && err.code === 'hold-deny') { console.warn('on legal hold:', err.details); } else { throw err; } }
**MCP helpers** under the /mcp subpath. Generate the exact JSON snippet for Claude Desktop or Cursor:
import { claudeDesktopConfig, cursorMcpConfig, mcpEndpointUrl, bearerAuthHeader } from '@kumokodo/kodori-sdk/mcp';
// ~/Library/Application Support/Claude/claude_desktop_config.json console.log(JSON.stringify(claudeDesktopConfig({ apiKey: '…' }), null, 2));
// For the full MCP client, pair with Anthropic's SDK: import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(new URL(mcpEndpointUrl()), { requestInit: { headers: bearerAuthHeader(process.env.KODORI_API_KEY!) }, }); const client = new Client({ name: 'my-app', version: '1.0.0' }); await client.connect(transport);
The SDK doesn't ship its own MCP client — Anthropic's official one already does that work. We provide the connection helpers so you don't have to remember endpoint URLs or header shapes.
**Custom fetch.** Pass a fetch implementation for tests, retry middleware, or OpenTelemetry instrumentation:
const kodori = new KodoriClient({ apiKey: '…', fetch: async (url, init) => { const start = Date.now(); const res = await globalThis.fetch(url, init); console.log('kodori', res.status, Date.now() - start, 'ms'); return res; }, });
**Self-hosted.** Pass baseUrl for staging or BYO-bucket deployments:
new KodoriClient({ apiKey: '…', baseUrl: 'https://kodori.staging.acme.com' });
**License: MIT.** Source on GitHub.