Understanding the kap-server Architecture and Debug Endpoints in Kimi Code
The kap-server package in Kimi Code is a Fastify-based backend built on the agent-core-v2 DI-Scope engine that exposes a reflective RPC surface under /api/v1/debug, gated to loopback bindings and protected by bearer-token authentication.
Kimi Code's backend intelligence lives in the kap-server package located at packages/kap-server within the MoonshotAI/kimi-code repository. This architecture leverages dependency injection and a transport-layer abstraction to expose internal services via REST and WebSocket endpoints, with a special debug interface that allows runtime introspection of the agent state.
Core Bootstrapping and DI Scope
The entry point src/start.ts serves as the composition root for the entire server lifecycle.
It initializes the system by calling bootstrap() to create a DI scope and seed it with logging, host-identity, and skill directories. The server then registers its instance in <home>/server/instances to support multiple concurrent Kimi Code processes.
Critical boot logic determines the exposure class—loopback, lan, or public—and enforces TLS for non-loopback binds. Debug endpoints are conditionally enabled based on a strict security gate:
const debugEndpoints = exposureClass === 'loopback' && opts.debugEndpoints === true;
This line in src/start.ts ensures diagnostic routes only surface when the server binds to 127.0.0.1 and the --debug-endpoints CLI flag is explicitly passed.
Transport Layer and Debug Endpoint Wiring
All HTTP routes are organized under src/transport. The architecture separates concerns into distinct components that collectively expose the debug interface:
- Service Dispatcher (
src/transport/serviceDispatcherRoutes.ts): Implements a reflective RPC handler capable of calling any service registered in the DI scope. - Debug Route Registration (
src/transport/registerDebugRoutes.ts): Mounts the dispatcher at/api/v1/debugwithout hard-coding service-specific routes. - Channel Registry (
src/transport/channelRegistry.ts): Resolves service IDs from channel names usingresolveAnyScopedServiceIdand describes available channels viadescribeAllChannels.
The debug route registration is intentionally thin, forwarding directly to the generic dispatcher:
export function registerDebugRoutes(app: RouteHost, core: Scope): void {
registerServiceDispatcherRoutes(app, core, '/debug', {
lookup: resolveAnyScopedServiceId,
describe: describeAllChannels,
});
}
Mounted by registerApiV1Routes under the /api/v1 prefix, this dispatcher exposes every service—whether scoped to App, Session, or Agent—without maintaining a whitelist. Access remains constrained by the global authentication hook.
How Debug Requests Are Processed
When a client hits /api/v1/debug, the request flows through a unified pipeline:
- Authentication: The global
createAuthHookvalidates the persistent bearer token or optional RPC token for all/api/v1/*routes. - Dispatcher Lookup: The URL path (e.g.,
agent/<agentId>/state) is resolved viaresolveAnyScopedServiceId, which walks the DI registry to locate the concrete implementation. - Method Invocation: The dispatcher extracts the method name from the JSON-RPC payload and invokes it on the resolved service instance.
- Response Envelope: Results are wrapped in a uniform structure
{ code, msg, data, request_id }to ensure consistent client handling regardless of the underlying service.
Security Gating and Loopback Restrictions
The debug surface is protected by two layers of defense:
- Network Binding: Debug endpoints are strictly limited to loopback interfaces (
127.0.0.1). ThedebugEndpointsvariable insrc/start.tsevaluates to false unlessexposureClass === 'loopback'. - Authentication: Even when enabled, the global bearer-auth hook (
src/middleware/auth.ts) protects the endpoint, preventing unauthorized access even if the port is accidentally exposed.
This dual-gating ensures that production deployments binding to LAN or public interfaces cannot accidentally expose internal service methods.
Practical Usage Examples
Enable the debug interface when starting the server:
kimi-code server start --debug-endpoints
List all registered services using curl:
curl -H "Authorization: Bearer $KIMI_TOKEN" \
http://127.0.0.1:58627/api/v1/debug/service/list
Invoke a method on a specific service, such as refreshing the model catalog:
curl -X POST -H "Authorization: Bearer $KIMI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"refresh","params":[],"id":1}' \
http://127.0.0.1:58627/api/v1/debug/modelCatalog/refresh
For WebSocket debugging, the same services are accessible via the legacy ws/v1 protocol implemented in src/transport/ws/v1/registerWsV1.ts, using the bearer token in either the Authorization header or the sec-websocket-protocol field.
Architectural Highlights
- Reflection-Based RPC: New services automatically appear under
/debugonce registered in the DI scope, eliminating the need to write new endpoint code for each service addition. - Unified Event Broadcasting: The
SessionEventBroadcasterandTranscriptService(src/services/transcript/transcriptService.ts) feed both the UI and debug endpoints, ensuring state consistency across interfaces. - Snapshot Subsystem:
SnapshotReader(src/services/snapshot/snapshotReader.ts) provides on-demand, read-only views of persisted session state for debugging complex agent workflows.
Key source files defining this architecture include:
packages/kap-server/src/start.ts– Server bootstrap and exposure class logic.src/transport/registerDebugRoutes.ts– Debug route registration.src/transport/serviceDispatcherRoutes.ts– Core reflective dispatcher.src/transport/channelRegistry.ts– Service ID resolution.src/middleware/auth.ts– Bearer-token authentication.src/middleware/hostnames.ts– Host-check logic for binding restrictions.
Summary
- The kap-server architecture uses a DI-Scope engine (agent-core-v2) and Fastify to expose REST and WebSocket endpoints.
- Debug endpoints are mounted at
/api/v1/debugvia a reflective service dispatcher that automatically exposes all registered services. - Security relies on loopback-only binding (
exposureClass === 'loopback') coupled with mandatory bearer-token authentication. - Core files include
src/start.tsfor bootstrapping andsrc/transport/registerDebugRoutes.tsfor endpoint wiring. - The system supports JSON-RPC over HTTP and WebSocket, with uniform response envelopes and snapshot-based state inspection.
Frequently Asked Questions
How do I enable the debug endpoints in Kimi Code?
Pass the --debug-endpoints flag when starting the server and ensure it binds to localhost (the default). The server validates that exposureClass === 'loopback' before mounting the routes, preventing accidental exposure on network interfaces. You must also provide a valid bearer token for all requests.
What services are accessible through the /api/v1/debug endpoint?
The reflective dispatcher exposes every service registered in the DI scope, including App-scoped, Session-scoped, and Agent-scoped services. There is no hard-coded whitelist; any service method can be invoked via JSON-RPC once the service ID is resolved through the channel registry.
Are the debug endpoints safe to use in production?
No. While the endpoints require authentication, they are designed for local debugging only and are restricted to loopback bindings (127.0.0.1). The architecture explicitly disables these routes when the server is configured with lan or public exposure classes to prevent remote access to internal service methods.
How does the service dispatcher resolve method calls?
The dispatcher uses resolveAnyScopedServiceId from src/transport/channelRegistry.ts to map URL paths to concrete service instances. It then extracts the method name from the JSON-RPC payload and invokes it directly on the resolved instance, wrapping the result in a standardized envelope containing code, msg, data, and request_id.
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 →