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-endpointsflag - 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: 0indicates 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
parseArgFromQueryor body parsing - Service resolution through
resolveAnyScopedServiceId(defined inchannelRegistry.tslines 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 Servicesworkspace— workspace-scoped Servicesagent— 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:
-
Start with debug endpoints enabled
kimi server start --debug-endpoints --bind-class loopback -
Identify relevant channels via
GET /api/v1/debug/channels -
Inspect session metadata using scoped calls:
curl -s "http://127.0.0.1:58627/api/v1/debug/session/${SESSION_ID}/sessionMetadata/get" -
Check session lifecycle state through
business-snapshotfor broader context -
Invoke corrective methods if available (e.g.,
sessionMetadata.setto fix corrupt metadata) -
Parse error codes — non-zero
codevalues with50001indicate 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-endpointson loop-back binding only - Discover services via
/api/v1/debug/channels— dynamically generated from the live DI registry - Invoke methods using
GET ?arg=orPOSTbody 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
codevalues
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.tslines 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →