How to Debug Session Issues Using the Kimi Code Server Debug Endpoints

The Kimi Code server (kap-server) exposes reflective debug RPC endpoints under /api/v1/debug/ when started with --debug-endpoints on a loop-back interface, allowing you to inspect channel registries, invoke service methods, and capture business state snapshots.

When troubleshooting session-related bugs in Kimi Code's agent engine, the internal debug surface provides direct access to the running Dependency Injection (DI) registry. This article explains how to enable and use these endpoints based on the actual implementation in MoonshotAI/kimi-code.

Enabling the Debug Endpoints

The debug routes are conditionally registered to prevent accidental exposure in production. According to packages/kap-server/src/start.ts (lines 24-27), two conditions must both be true:

  • The server is started with the --debug-endpoints flag
  • The server is bound to a loop-back interface (127.0.0.1 or ::1)
kimi server start --debug-endpoints --bind-class loopback

The debugEndpoints variable is set to true only when both conditions are satisfied. If the server binds to a public interface, the flag is ignored and /debug routes remain unregistered.

Available Debug Routes

Once enabled, four route patterns become available:

Route Purpose
/api/v1/debug/channels List all Service channels with methods, arity, and parameters
/api/v1/debug/:service/:method Invoke a Service method via reflection
/api/v1/debug/:scope/:scope_id/... Scoped RPC calls (session, workspace, or agent-specific)
/api/v1/debug/business-snapshot Dump internal business state (sessions, workspaces, agents)

Route registration happens in packages/kap-server/src/transport/registerDebugRoutes.ts, which mounts both the dispatcher and business-snapshot handlers.

Response Envelope Format

All debug endpoints return responses wrapped in a standard envelope:

{
  "code": 0,
  "msg": "OK",
  "data": <payload>,
  "request_id": "<uuid>"
}
  • code: 0 indicates success
  • Non-zero codes indicate business errors (4xxx range) or internal failures (50001)

Listing Available Channels

To discover what Services are reachable in the DI registry, query the channels endpoint:

curl -s http://127.0.0.1:58627/api/v1/debug/channels | jq .

Sample response (trimmed):

{
  "code": 0,
  "msg": "OK",
  "data": [
    {
      "name": "sessionMetadata",
      "scope": "session",
      "domain": "session",
      "methods": [
        {"name": "get", "kind": "method", "arity": 0, "params": ""},
        {"name": "set", "kind": "method", "arity": 1, "params": "metadata"}
      ]
    }
  ],
  "request_id": "c6c2..."
}

The describeAllChannels() function in packages/kap-server/src/transport/channelRegistry.ts (lines 57-73) generates this list dynamically, including Services registered at runtime via the Feature-seam.

Invoking Service Methods

Once you identify a channel, invoke its methods using either GET or POST.

GET with query parameter:

curl -s 'http://127.0.0.1:58627/api/v1/debug/workspaceService/getAll?arg=[]' | jq .

POST with JSON body:

curl -s -X POST \
     -H 'Content-Type: application/json' \
     -d '{}' \
     http://127.0.0.1:58627/api/v1/debug/workspaceService/getAll | jq .

The dispatcher logic in packages/kap-server/src/transport/serviceDispatcherRoutes.ts handles:

  • Argument parsing via parseArgFromQuery or body parsing
  • Service resolution through resolveAnyScopedServiceId (defined in channelRegistry.ts lines 88-98)
  • Timeout handling and error mapping (lines 44-50)

Scoped Debugging for Sessions

To inspect a specific session, use the scoped path pattern:

curl -s "http://127.0.0.1:58627/api/v1/debug/session/abc123/sessionMetadata/get" | jq .

Path structure: /api/v1/debug/:scopeKind/:scopeId/:service/:method

Supported scope kinds include:

  • session — session-scoped Services
  • workspace — workspace-scoped Services
  • agent — Agent-scoped Services (nested: /session/:id/agent/:id/...)

The dispatcher sets scopeKind based on the URL segment, causing the DI resolver to look within that specific scope rather than the global registry.

Capturing Business State Snapshots

For a comprehensive view of server state, use the business-snapshot endpoint:

curl -s http://127.0.0.1:58627/api/v1/debug/business-snapshot | jq .

This returns serialized state for:

  • Active sessions
  • Workspaces
  • Running agents
  • Other business entities

The implementation resides in packages/kap-server/src/transport/businessSnapshotRoutes.ts, imported and registered by registerDebugRoutes.ts.

Practical Debugging Workflow for Session Issues

Follow this systematic approach to diagnose session problems:

  1. Start with debug endpoints enabled

    kimi server start --debug-endpoints --bind-class loopback
  2. Identify relevant channels via GET /api/v1/debug/channels

  3. Inspect session metadata using scoped calls:

    curl -s "http://127.0.0.1:58627/api/v1/debug/session/${SESSION_ID}/sessionMetadata/get"
  4. Check session lifecycle state through business-snapshot for broader context

  5. Invoke corrective methods if available (e.g., sessionMetadata.set to fix corrupt metadata)

  6. Parse error codes — non-zero code values with 50001 indicate internal failures requiring server log inspection

Core Implementation Files

Understanding these files helps trace debug call flows:

File Responsibility
packages/kap-server/src/transport/registerDebugRoutes.ts Mounts debug routes under /api/v1/debug
packages/kap-server/src/transport/serviceDispatcherRoutes.ts Core RPC handler with argument parsing, dispatch, and envelope generation
packages/kap-server/src/transport/channelRegistry.ts Channel indexing and /channels introspection
packages/kap-server/src/start.ts (lines 24-27) debugEndpoints flag evaluation
packages/kap-server/src/transport/businessSnapshotRoutes.ts Business state snapshot implementation

Summary

  • Enable debug endpoints with --debug-endpoints on loop-back binding only
  • Discover services via /api/v1/debug/channels — dynamically generated from the live DI registry
  • Invoke methods using GET ?arg= or POST body against /api/v1/debug/:service/:method
  • Scope calls to specific sessions using /api/v1/debug/session/:id/...
  • Capture state quickly with /api/v1/debug/business-snapshot
  • Interpret responses through the standard envelope — watch for non-zero code values

Frequently Asked Questions

Why don't the debug endpoints appear when I use --debug-endpoints?

The flag is ignored unless the server binds to a loop-back interface. Check packages/kap-server/src/start.ts lines 24-27: both conditions must be satisfied. Use --bind-class loopback or explicitly bind to 127.0.0.1.

Can I invoke methods on Services added by plugins at runtime?

Yes. The describeAllChannels() function in channelRegistry.ts scans the entire DI registry dynamically. Any Service registered through the Feature-seam appears immediately in /channels without server restart.

What's the difference between GET and POST for method invocation?

Both reach the same handler in serviceDispatcherRoutes.ts. GET passes arguments via the ?arg= query parameter as URL-encoded JSON. POST accepts arguments in the request body with Content-Type: application/json. Use POST for complex or large payloads.

How do I interpret error codes in the response envelope?

  • 0: Success
  • 4xxx: Business logic errors (specific to the invoked Service)
  • 50001: Internal server failure — check server logs for stack traces (logged in serviceDispatcherRoutes.ts lines 44-50)

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 →