← Back to Kontasks
Konsole-Claude Communication Architecture
How konsole service communicates with Claude - CLI subprocess, not API
Output
Konsole → Claude Communication
Answer: CLI Subprocess (not API)
Konsole spawns the claude Linux CLI client as a child process using Deno.Command. It does NOT use the Anthropic API directly.
Architecture Flow
Dashboard → HTTP POST → Konsole → spawn() → claude CLI → Anthropic API ↑ ↓ └──────────────── SSE stream ←───────── stdout JSON
Key Code: claude.ts:43-88
export function spawnClaude(sessionId, prompt, claudeSessionId) { // Build command args const args = [ "--print", // Print mode for structured output "--output-format", "stream-json", // JSON events on stdout "--verbose", // Required for stream-json ]; // Resume existing session if available if (claudeSessionId) { args.push("--resume", claudeSessionId); } args.push(prompt); // Prompt as positional arg // Spawn the claude CLI as subprocess const cmd = new Deno.Command("claude", { args, cwd: config.workingDir, stdin: "null", stdout: "piped", // Capture JSON events stderr: "piped", // Capture errors }); return cmd.spawn(); }
Output Parsing: stream.ts:348-509
Claude CLI outputs JSON lines on stdout:
{"type":"system","session_id":"abc123"} // Session init
{"type":"assistant","message":{...}} // Tool calls, text
{"type":"user","message":{...}} // Tool results
{"type":"result","result":"..."} // Final output
Configuration: config.ts:57
claudeCommand: env.KONSOLE_CLAUDE_COMMAND || "claude" claudeArgs: "--dangerously-skip-permissions" // Default args
Why CLI Instead of API?
- Tool execution: Claude CLI can run Bash, Read/Write files, etc.
- Session resumption:
--resumemaintains conversation context - MCP servers: CLI has access to configured MCP tools (like kontasks)
- Auto-compaction: CLI handles context management automatically
What's Next?
Choose an action:
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
konsolearchitectureclaude
Created
3 Jan 2026, 12:26 pm
Updated
3 Jan 2026, 12:26 pm
Created By
claude
Raw Data
{
"id": "6c25475f-95e2-460e-ad97-f3e198479dab",
"type": "general",
"status": "completed",
"title": "Konsole-Claude Communication Architecture",
"description": "How konsole service communicates with Claude - CLI subprocess, not API",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\">\n<h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">Konsole → Claude Communication</h2>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#98c379;margin:0 0 12px 0;\">Answer: CLI Subprocess (not API)</h3>\n<p style=\"margin:0;line-height:1.6;\">Konsole spawns the <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">claude</code> <strong>Linux CLI client</strong> as a child process using <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">Deno.Command</code>. It does NOT use the Anthropic API directly.</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#61afef;margin:0 0 12px 0;\">Architecture Flow</h3>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;overflow-x:auto;margin:0;line-height:1.6;\">\n<span style=\"color:#e5c07b;\">Dashboard</span> → <span style=\"color:#c678dd;\">HTTP POST</span> → <span style=\"color:#98c379;\">Konsole</span> → <span style=\"color:#c678dd;\">spawn()</span> → <span style=\"color:#56b6c2;\">claude CLI</span> → <span style=\"color:#e5c07b;\">Anthropic API</span>\n ↑ ↓\n └──────────────── <span style=\"color:#c678dd;\">SSE stream</span> ←───────── <span style=\"color:#61afef;\">stdout JSON</span>\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#e5c07b;margin:0 0 12px 0;\">Key Code: <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">claude.ts:43-88</code></h3>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;overflow-x:auto;margin:0;font-size:0.9em;line-height:1.5;\">\n<span style=\"color:#c678dd;\">export function</span> <span style=\"color:#61afef;\">spawnClaude</span>(sessionId, prompt, claudeSessionId) {\n <span style=\"color:#7f848e;\">// Build command args</span>\n <span style=\"color:#c678dd;\">const</span> args = [\n <span style=\"color:#98c379;\">\"--print\"</span>, <span style=\"color:#7f848e;\">// Print mode for structured output</span>\n <span style=\"color:#98c379;\">\"--output-format\"</span>, <span style=\"color:#98c379;\">\"stream-json\"</span>, <span style=\"color:#7f848e;\">// JSON events on stdout</span>\n <span style=\"color:#98c379;\">\"--verbose\"</span>, <span style=\"color:#7f848e;\">// Required for stream-json</span>\n ];\n \n <span style=\"color:#7f848e;\">// Resume existing session if available</span>\n <span style=\"color:#c678dd;\">if</span> (claudeSessionId) {\n args.<span style=\"color:#61afef;\">push</span>(<span style=\"color:#98c379;\">\"--resume\"</span>, claudeSessionId);\n }\n \n args.<span style=\"color:#61afef;\">push</span>(prompt); <span style=\"color:#7f848e;\">// Prompt as positional arg</span>\n \n <span style=\"color:#7f848e;\">// Spawn the claude CLI as subprocess</span>\n <span style=\"color:#c678dd;\">const</span> cmd = <span style=\"color:#c678dd;\">new</span> <span style=\"color:#e5c07b;\">Deno.Command</span>(<span style=\"color:#98c379;\">\"claude\"</span>, {\n args,\n cwd: config.workingDir,\n stdin: <span style=\"color:#98c379;\">\"null\"</span>,\n stdout: <span style=\"color:#98c379;\">\"piped\"</span>, <span style=\"color:#7f848e;\">// Capture JSON events</span>\n stderr: <span style=\"color:#98c379;\">\"piped\"</span>, <span style=\"color:#7f848e;\">// Capture errors</span>\n });\n \n <span style=\"color:#c678dd;\">return</span> cmd.<span style=\"color:#61afef;\">spawn</span>();\n}\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#c678dd;margin:0 0 12px 0;\">Output Parsing: <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">stream.ts:348-509</code></h3>\n<p style=\"margin:0 0 12px 0;line-height:1.6;\">Claude CLI outputs JSON lines on stdout:</p>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;overflow-x:auto;margin:0;font-size:0.85em;line-height:1.5;\">\n{<span style=\"color:#98c379;\">\"type\"</span>:<span style=\"color:#98c379;\">\"system\"</span>,<span style=\"color:#98c379;\">\"session_id\"</span>:<span style=\"color:#98c379;\">\"abc123\"</span>} <span style=\"color:#7f848e;\">// Session init</span>\n{<span style=\"color:#98c379;\">\"type\"</span>:<span style=\"color:#98c379;\">\"assistant\"</span>,<span style=\"color:#98c379;\">\"message\"</span>:{...}} <span style=\"color:#7f848e;\">// Tool calls, text</span>\n{<span style=\"color:#98c379;\">\"type\"</span>:<span style=\"color:#98c379;\">\"user\"</span>,<span style=\"color:#98c379;\">\"message\"</span>:{...}} <span style=\"color:#7f848e;\">// Tool results</span>\n{<span style=\"color:#98c379;\">\"type\"</span>:<span style=\"color:#98c379;\">\"result\"</span>,<span style=\"color:#98c379;\">\"result\"</span>:<span style=\"color:#98c379;\">\"...\"</span>} <span style=\"color:#7f848e;\">// Final output</span>\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#56b6c2;margin:0 0 12px 0;\">Configuration: <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">config.ts:57</code></h3>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;overflow-x:auto;margin:0;font-size:0.9em;line-height:1.5;\">\nclaudeCommand: env.KONSOLE_CLAUDE_COMMAND || <span style=\"color:#98c379;\">\"claude\"</span>\nclaudeArgs: <span style=\"color:#98c379;\">\"--dangerously-skip-permissions\"</span> <span style=\"color:#7f848e;\">// Default args</span>\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;\">\n<h3 style=\"color:#fff;margin:0 0 12px 0;\">Why CLI Instead of API?</h3>\n<ul style=\"margin:0;padding-left:20px;line-height:1.8;\">\n<li><strong>Tool execution:</strong> Claude CLI can run Bash, Read/Write files, etc.</li>\n<li><strong>Session resumption:</strong> <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:3px;\">--resume</code> maintains conversation context</li>\n<li><strong>MCP servers:</strong> CLI has access to configured MCP tools (like kontasks)</li>\n<li><strong>Auto-compaction:</strong> CLI handles context management automatically</li>\n</ul>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:16px;font-family:sans-serif;\">\n<h4 style=\"margin:0 0 8px 0;color:#fff;\">What's Next?</h4>\n<p style=\"color:#9ca3af;margin:0;\">Choose an action:</p>\n</div>\n</div>",
"requestedAt": "2026-01-03T00:00:00.000Z",
"requestId": "cff46f0f-5481-40d5-8276-0b380f02a4c9",
"choices": [
{
"label": "Show session flow",
"value": "Show me how sessions work in konsole - creation, resumption, and cleanup",
"primary": true
},
{
"label": "View stream parsing",
"value": "Explain how stream.ts parses Claude's JSON output in detail"
},
{
"label": "Show config options",
"value": "List all konsole configuration options and their defaults"
}
]
},
"createdBy": "claude",
"createdAt": "2026-01-03T02:26:25.652Z",
"updatedAt": "2026-01-03T02:26:25.805Z",
"requestId": "cff46f0f-5481-40d5-8276-0b380f02a4c9",
"scope": "vibetools",
"tags": [
"konsole",
"architecture",
"claude"
],
"targetUser": "claude"
}