How to Integrate with the `klient` Package from Kimi-Code: A Complete Guide

Use @moonshot-ai/klient to connect to the Kimi-Code engine via memory or IPC transport, then interact through typed facades for global, session, and agent-level operations.

The @moonshot-ai/klient package is the official, transport-agnostic client SDK for the MoonshotAI/kimi-code repository. It provides a unified interface to the agent-core-v2 runtime, letting you build tools and extensions that talk to the Kimi-Code engine whether it runs in-process or across a Unix socket.

What Is the klient Package?

At its core, klient exposes a three-tier facade—global, session, and agent—that mirrors the engine's RPC surface. The SDK abstracts away transport details so the same code works whether you're embedding the engine directly or connecting to a separate process.

The architecture centers on createKlientFromChannel in packages/klient/src/core/klient.ts. This factory builds a Klient instance from any object implementing the KlientChannel interface, which defines three low-level operations:

  • call – synchronous RPC invocation
  • stream – streaming response handling
  • listen – bi-directional event subscription

Transport Options for klient Integration

Memory Transport (In-Process)

The memory transport runs the engine inside your Node.js process using a MemoryDispatcher that simulates JSON round-trips without actual serialization overhead.

import { createKlient } from '@moonshot-ai/klient/memory';
import { bootstrap } from '@moonshot-ai/agent-core-v2';

const { app } = bootstrap(
  { homeDir: '/tmp/demo', clientIdentity: { name: 'my-app' } },
  [...logSeed(resolveLoggingConfig({ homeDir: '/tmp/demo', env: process.env }))]
);

const klient = createKlient({ scope: app });

Implementation source: packages/klient/src/transports/memory/index.ts

This approach minimizes latency and eliminates IPC overhead. Ideal for CLI tools, automated tests, and embedded assistants.

IPC Transport (Separate Process)

The IPC transport connects to an engine process via Unix-domain socket, enabling multi-process architectures and remote engine hosting.

import { createKlient } from '@moonshot-ai/klient/ipc';

const klient = createKlient({
  socketPath: '/var/run/kimi-code.sock',
  validate: true,  // runtime contract validation
});

Implementation source: packages/klient/src/transports/ipc/index.ts

The companion serveKlientIpc function (from packages/klient/src/transports/ipc/host.ts) starts the server side.

The Three-Tier Facade System

Once connected, all klient instances expose the same typed interface regardless of transport.

Global Facade

Access engine-wide capabilities through klient.global:

const envInfo = await klient.global.env();
console.log(envInfo.platform, envInfo.homeDir);

const workspaces = await klient.global.workspaces.list();
const providers = await klient.global.kosong.listProviders();

Implementation source: packages/klient/src/core/facade/global.ts

Session Facade

Open a session handle to work with conversation-scoped APIs:

const { id: sessionId } = await klient.global.sessions.create({ title: 'My Session' });
const session = klient.session(sessionId);

const answer = await session.questions.ask({ content: 'Explain quantum computing' });

Implementation source: packages/klient/src/core/facade/session.ts

Agent Facade

Interact with specific agents within a session for tool execution:

const agent = session.agent('default');
const result = await agent.shell.runCommand({ command: 'uname -a' });
console.log(result.stdout, result.stderr, result.exitCode);

Implementation source: packages/klient/src/core/facade/agent.ts

Event Subscription with klient

Every facade includes an EventHub that forwards engine events with automatic cleanup on client close.

// Subscribe to provider changes
const subscription = klient.events.on('kosong.providers.changed', (event) => {
  console.log('Providers updated:', event.providers);
});

// Later: clean up
subscription.dispose();

The hub validates event payloads against globalContract and supports wildcards for namespaced events. Implementation: packages/klient/src/core/events/hub.ts.

Complete Integration Example

This end-to-end example from packages/klient/examples/basic.ts demonstrates the full klient integration pattern:

import { bootstrap, logSeed, resolveLoggingConfig } from '@moonshot-ai/agent-core-v2';
import { createKlient } from '@moonshot-ai/klient/memory';

async function run() {
  // 1. Bootstrap engine in-process
  const { app } = bootstrap(
    { homeDir: '/tmp/klient-demo', clientIdentity: { name: 'demo' } },
    [...logSeed(resolveLoggingConfig({ homeDir: '/tmp/klient-demo', env: process.env }))],
  );

  // 2. Create klient with memory transport
  const klient = createKlient({ scope: app });

  // 3. Global operations
  const envInfo = await klient.global.env();
  const sessions = await klient.global.sessions.list({});

  // 4. Event handling
  const sub = klient.events.on('kosong.providers.changed', console.log);

  // 5. Mutate state and observe events
  await klient.global.kosong.addProvider('demo', {
    type: 'openai',
    auth: { method: 'api-key', apiKey: 'demo-key' },
  });
  await klient.global.kosong.removeProvider('demo');

  // 6. Cleanup
  sub.dispose();
  await klient.close();
  app.dispose();
}

run().catch(console.error);

Configuration and Performance Options

Control klient behavior via KlientOptions:

Option Default Purpose
validate true Validate all wire payloads against globalContract
socketPath required for IPC Unix socket path for IPC transport
scope required for memory Bootstrapped engine scope from agent-core-v2

Disable validation for hot-path performance: validate: false.

Summary

Frequently Asked Questions

What is the difference between memory and IPC transport in klient?

Memory transport runs the engine inside your Node.js process using a MemoryDispatcher, eliminating serialization overhead and enabling direct function calls. IPC transport communicates via Unix-domain socket with a separately launched engine process, supporting distributed architectures and process isolation. The same facade code works unchanged—only the createKlient import and configuration differ.

How do I subscribe to engine events when integrating with klient?

Use klient.events.on(eventName, handler) from any Klient instance. The EventHub in packages/klient/src/core/events/hub.ts forwards typed events like 'kosong.providers.changed'. Returns a disposable subscription; call .dispose() or await klient.close() to clean up. Events are validated against the contract unless validate: false is set.

Can I disable payload validation for better performance?

Yes. Set validate: false in KlientOptions when calling createKlient. This skips runtime validation against globalContract for all RPC calls and events. Recommended only in production environments where you control both client and engine versions, since mismatched contracts will fail silently rather than throwing descriptive errors.

Where is the public API surface defined in the klient package?

packages/klient/src/index.ts re-exports all public types and factories: Klient, SessionHandle, AgentHandle, GlobalFacade, SessionFacade, AgentFacade, and transport-specific createKlient functions. This is your single import target—avoid deep imports from internal paths to ensure forward compatibility.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →