konsilio 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +24 -0
- package/README.md +170 -0
- package/build/cli/history.d.ts +2 -0
- package/build/cli/history.js +179 -0
- package/build/cli/history.js.map +1 -0
- package/build/config.d.ts +38 -0
- package/build/config.js +118 -0
- package/build/config.js.map +1 -0
- package/build/container.d.ts +32 -0
- package/build/container.js +102 -0
- package/build/container.js.map +1 -0
- package/build/db/schema.d.ts +1 -0
- package/build/db/schema.js +67 -0
- package/build/db/schema.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +140 -0
- package/build/index.js.map +1 -0
- package/build/konsilio.json +25 -0
- package/build/konsilio.schema.json +140 -0
- package/build/logger.d.ts +84 -0
- package/build/logger.js +121 -0
- package/build/logger.js.map +1 -0
- package/build/personas/expert.d.ts +33 -0
- package/build/personas/expert.js +46 -0
- package/build/personas/expert.js.map +1 -0
- package/build/personas/index.d.ts +9 -0
- package/build/personas/index.js +11 -0
- package/build/personas/index.js.map +1 -0
- package/build/personas/lead.d.ts +33 -0
- package/build/personas/lead.js +51 -0
- package/build/personas/lead.js.map +1 -0
- package/build/personas/schemas.d.ts +313 -0
- package/build/personas/schemas.js +97 -0
- package/build/personas/schemas.js.map +1 -0
- package/build/prompts/consolidation/critique.md +59 -0
- package/build/prompts/consolidation/decision.md +51 -0
- package/build/prompts/consolidation/extraction.md +46 -0
- package/build/prompts/consolidation/synthesis.md +42 -0
- package/build/prompts/expert-rules.md +50 -0
- package/build/prompts/personas/dev-tooling.md +27 -0
- package/build/prompts/personas/devops.md +26 -0
- package/build/prompts/personas/distributed-systems.md +28 -0
- package/build/prompts/personas/graph-dba.md +27 -0
- package/build/prompts/personas/node-fullstack.md +27 -0
- package/build/prompts/personas/performance.md +26 -0
- package/build/prompts/personas/security.md +26 -0
- package/build/prompts/personas/test-architect.md +29 -0
- package/build/prompts/personas/test-quoted.md +14 -0
- package/build/prompts/personas/typescript.md +26 -0
- package/build/prompts/personas/ux-dx.md +29 -0
- package/build/prompts/workflow-rules.md +3 -0
- package/build/server.d.ts +24 -0
- package/build/server.js +181 -0
- package/build/server.js.map +1 -0
- package/build/services/cache.service.d.ts +49 -0
- package/build/services/cache.service.js +85 -0
- package/build/services/cache.service.js.map +1 -0
- package/build/services/council.service.d.ts +111 -0
- package/build/services/council.service.js +361 -0
- package/build/services/council.service.js.map +1 -0
- package/build/services/database.service.d.ts +70 -0
- package/build/services/database.service.js +221 -0
- package/build/services/database.service.js.map +1 -0
- package/build/services/formatter.service.d.ts +52 -0
- package/build/services/formatter.service.js +133 -0
- package/build/services/formatter.service.js.map +1 -0
- package/build/services/index.d.ts +18 -0
- package/build/services/index.js +13 -0
- package/build/services/index.js.map +1 -0
- package/build/services/openrouter.service.d.ts +58 -0
- package/build/services/openrouter.service.js +128 -0
- package/build/services/openrouter.service.js.map +1 -0
- package/build/services/persona.service.d.ts +43 -0
- package/build/services/persona.service.js +93 -0
- package/build/services/persona.service.js.map +1 -0
- package/build/services/prompt.service.d.ts +59 -0
- package/build/services/prompt.service.js +209 -0
- package/build/services/prompt.service.js.map +1 -0
- package/konsilio.schema.json +140 -0
- package/package.json +68 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency Injection Container
|
|
3
|
+
*
|
|
4
|
+
* Composition root that wires up all services with their dependencies.
|
|
5
|
+
* This is the single place where all dependencies are created and connected.
|
|
6
|
+
*/
|
|
7
|
+
import { logger } from './logger.js';
|
|
8
|
+
import { config, validateConfig } from './config.js';
|
|
9
|
+
import { SCHEMA } from './db/schema.js';
|
|
10
|
+
import { OpenRouterService } from './services/openrouter.service.js';
|
|
11
|
+
import { DatabaseService } from './services/database.service.js';
|
|
12
|
+
import { CacheService } from './services/cache.service.js';
|
|
13
|
+
import { PromptService } from './services/prompt.service.js';
|
|
14
|
+
import { PersonaService } from './services/persona.service.js';
|
|
15
|
+
import { CouncilService } from './services/council.service.js';
|
|
16
|
+
import { FormatterService } from './services/formatter.service.js';
|
|
17
|
+
/**
|
|
18
|
+
* Create and wire up all application services (async)
|
|
19
|
+
*/
|
|
20
|
+
export async function createServices() {
|
|
21
|
+
// Validate configuration before creating services
|
|
22
|
+
validateConfig();
|
|
23
|
+
// Create OpenRouter service
|
|
24
|
+
const openRouterService = new OpenRouterService({
|
|
25
|
+
apiKey: config.openrouterApiKey,
|
|
26
|
+
baseUrl: config.openrouterBaseUrl,
|
|
27
|
+
}, logger);
|
|
28
|
+
// Create Database service (async factory due to WASM loading)
|
|
29
|
+
const databaseService = await DatabaseService.create({
|
|
30
|
+
dbPath: config.databasePath,
|
|
31
|
+
maxHistorySessions: config.maxHistorySessions,
|
|
32
|
+
}, logger, SCHEMA);
|
|
33
|
+
// Create Cache service
|
|
34
|
+
const cacheService = new CacheService(config.cacheTtlSeconds * 1000);
|
|
35
|
+
// Create Prompt service
|
|
36
|
+
const promptService = new PromptService(undefined, logger);
|
|
37
|
+
// Create Persona service
|
|
38
|
+
const personaService = new PersonaService({
|
|
39
|
+
promptService,
|
|
40
|
+
cacheService,
|
|
41
|
+
logger,
|
|
42
|
+
});
|
|
43
|
+
// Create Council service with all dependencies
|
|
44
|
+
const councilConfig = {
|
|
45
|
+
enabledPersonaIds: config.enabledPersonas,
|
|
46
|
+
models: config.models,
|
|
47
|
+
personaModels: config.personaModels,
|
|
48
|
+
timeouts: config.timeouts,
|
|
49
|
+
maxTokens: config.maxTokens,
|
|
50
|
+
maxDraftPlanLength: config.maxDraftPlanLength,
|
|
51
|
+
formatterMaxRetries: config.formatterMaxRetries,
|
|
52
|
+
};
|
|
53
|
+
// Create Formatter service
|
|
54
|
+
const formatterConfig = {
|
|
55
|
+
model: config.models.formatter,
|
|
56
|
+
timeoutMs: config.timeouts.formatterMs,
|
|
57
|
+
maxRetries: config.formatterMaxRetries,
|
|
58
|
+
};
|
|
59
|
+
const formatterService = new FormatterService({
|
|
60
|
+
openRouterService,
|
|
61
|
+
logger,
|
|
62
|
+
config: formatterConfig,
|
|
63
|
+
});
|
|
64
|
+
const councilService = new CouncilService({
|
|
65
|
+
logger,
|
|
66
|
+
openRouterService,
|
|
67
|
+
databaseService,
|
|
68
|
+
cacheService,
|
|
69
|
+
promptService,
|
|
70
|
+
personaService,
|
|
71
|
+
formatterService,
|
|
72
|
+
config: councilConfig,
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
openRouterService,
|
|
76
|
+
databaseService,
|
|
77
|
+
cacheService,
|
|
78
|
+
promptService,
|
|
79
|
+
personaService,
|
|
80
|
+
councilService,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Singleton services instance (lazy initialized)
|
|
85
|
+
*/
|
|
86
|
+
let _services = null;
|
|
87
|
+
/**
|
|
88
|
+
* Get the singleton services instance (returns a Promise)
|
|
89
|
+
*/
|
|
90
|
+
export function getServices() {
|
|
91
|
+
if (!_services) {
|
|
92
|
+
_services = createServices();
|
|
93
|
+
}
|
|
94
|
+
return _services;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reset services (useful for testing)
|
|
98
|
+
*/
|
|
99
|
+
export function resetServices() {
|
|
100
|
+
_services = null;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SCHEMA = "\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n draft_plan_summary TEXT,\n tech_stack TEXT,\n constraints TEXT\n);\n\nCREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),\n persona_id TEXT,\n content TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS expert_findings (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n persona_id TEXT NOT NULL,\n persona_name TEXT NOT NULL,\n persona_emoji TEXT,\n severity TEXT NOT NULL CHECK(severity IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW')),\n component TEXT NOT NULL,\n issue TEXT NOT NULL,\n mitigation TEXT NOT NULL,\n accepted BOOLEAN DEFAULT 0,\n rejection_reason TEXT,\n duration_ms INTEGER,\n model_used TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS expert_risks (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n persona_id TEXT NOT NULL,\n category TEXT NOT NULL,\n probability TEXT NOT NULL,\n impact TEXT NOT NULL,\n description TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS consolidation_phases (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n phase_name TEXT NOT NULL CHECK(phase_name IN ('extraction', 'critique', 'decision', 'synthesis')),\n phase_output TEXT NOT NULL,\n duration_ms INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\n\nCREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\nCREATE INDEX IF NOT EXISTS idx_findings_session ON expert_findings(session_id);\nCREATE INDEX IF NOT EXISTS idx_findings_accepted ON expert_findings(accepted);\nCREATE INDEX IF NOT EXISTS idx_risks_session ON expert_risks(session_id);\nCREATE INDEX IF NOT EXISTS idx_phases_session ON consolidation_phases(session_id);\nCREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at DESC);\n";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export const SCHEMA = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
3
|
+
id TEXT PRIMARY KEY,
|
|
4
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
5
|
+
draft_plan_summary TEXT,
|
|
6
|
+
tech_stack TEXT,
|
|
7
|
+
constraints TEXT
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
11
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
12
|
+
session_id TEXT NOT NULL,
|
|
13
|
+
role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),
|
|
14
|
+
persona_id TEXT,
|
|
15
|
+
content TEXT NOT NULL,
|
|
16
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
17
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS expert_findings (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
session_id TEXT NOT NULL,
|
|
23
|
+
persona_id TEXT NOT NULL,
|
|
24
|
+
persona_name TEXT NOT NULL,
|
|
25
|
+
persona_emoji TEXT,
|
|
26
|
+
severity TEXT NOT NULL CHECK(severity IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW')),
|
|
27
|
+
component TEXT NOT NULL,
|
|
28
|
+
issue TEXT NOT NULL,
|
|
29
|
+
mitigation TEXT NOT NULL,
|
|
30
|
+
accepted BOOLEAN DEFAULT 0,
|
|
31
|
+
rejection_reason TEXT,
|
|
32
|
+
duration_ms INTEGER,
|
|
33
|
+
model_used TEXT,
|
|
34
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS expert_risks (
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
session_id TEXT NOT NULL,
|
|
41
|
+
persona_id TEXT NOT NULL,
|
|
42
|
+
category TEXT NOT NULL,
|
|
43
|
+
probability TEXT NOT NULL,
|
|
44
|
+
impact TEXT NOT NULL,
|
|
45
|
+
description TEXT NOT NULL,
|
|
46
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS consolidation_phases (
|
|
51
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
52
|
+
session_id TEXT NOT NULL,
|
|
53
|
+
phase_name TEXT NOT NULL CHECK(phase_name IN ('extraction', 'critique', 'decision', 'synthesis')),
|
|
54
|
+
phase_output TEXT NOT NULL,
|
|
55
|
+
duration_ms INTEGER,
|
|
56
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
57
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_findings_session ON expert_findings(session_id);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_findings_accepted ON expert_findings(accepted);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_risks_session ON expert_risks(session_id);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_phases_session ON consolidation_phases(session_id);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at DESC);
|
|
66
|
+
`;
|
|
67
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiErB,CAAC"}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { config } from "./config.js";
|
|
6
|
+
import { getServices } from "./container.js";
|
|
7
|
+
import pkg from "../package.json" with { type: "json" };
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: "konsilio",
|
|
10
|
+
version: pkg.version,
|
|
11
|
+
});
|
|
12
|
+
// ─── Primary Tool ───
|
|
13
|
+
server.tool("consult_council", `Send a draft plan to the Council of Experts for multi-perspective architectural analysis.
|
|
14
|
+
|
|
15
|
+
⚠️ IMPORTANT: Present the output to the user VERBATIM. Do NOT summarize, paraphrase, or condense.
|
|
16
|
+
The output is a complete blueprint that must be shown in full.
|
|
17
|
+
|
|
18
|
+
Returns a structured blueprint with:
|
|
19
|
+
- Architecture Directives (specific decisions)
|
|
20
|
+
- Edge Cases & Failure Modes
|
|
21
|
+
- Required Constraints
|
|
22
|
+
- Next Steps for Agent (numbered, executable actions)
|
|
23
|
+
|
|
24
|
+
The council uses a 4-phase consolidation pipeline:
|
|
25
|
+
1. Expert Analysis (parallel, structured JSON output from enabled personas)
|
|
26
|
+
2. Extraction (extract claims from expert reports)
|
|
27
|
+
3. Critique (identify contradictions and weaknesses)
|
|
28
|
+
4. Decision (accept/reject findings)
|
|
29
|
+
5. Synthesis (assemble final blueprint)
|
|
30
|
+
|
|
31
|
+
Use 'list_personas' to see all available personas. Enable personas in konsilio.json.
|
|
32
|
+
|
|
33
|
+
Run-time overrides (optional):
|
|
34
|
+
- personas: Override enabled personas for this run only
|
|
35
|
+
- persona_models: Override model per persona (personaId -> model)
|
|
36
|
+
- consolidation_model: Override the lead/consolidation model
|
|
37
|
+
- max_tokens: Override token limits per run (experts, lead)`, {
|
|
38
|
+
draft_plan: z.string().describe("The architecture plan or design to analyze."),
|
|
39
|
+
tech_stack: z.string().optional().describe("Technology stack, e.g. 'Node.js, PostgreSQL, Redis, Docker'"),
|
|
40
|
+
context_constraints: z.string().optional().describe("Runtime constraints, e.g. 'Must run on Proxmox LXC', 'No external deps'"),
|
|
41
|
+
// Run-time overrides
|
|
42
|
+
personas: z.array(z.string()).optional().describe("Override enabled personas for this run only. Uses persona IDs from konsilio.json."),
|
|
43
|
+
persona_models: z.record(z.string(), z.string()).optional().describe("Override model per persona. Maps personaId -> model ID."),
|
|
44
|
+
consolidation_model: z.string().optional().describe("Override the lead/consolidation model for this run."),
|
|
45
|
+
max_tokens: z.object({
|
|
46
|
+
experts: z.number().optional(),
|
|
47
|
+
lead: z.number().optional(),
|
|
48
|
+
}).optional().describe("Override token limits for this run. Experts: per-persona max, Lead: consolidation max."),
|
|
49
|
+
}, async (params) => {
|
|
50
|
+
const draftPlan = params.draft_plan.trim();
|
|
51
|
+
if (!draftPlan) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: "❌ Error: draft_plan cannot be empty." }],
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (draftPlan.length > config.maxDraftPlanLength) {
|
|
58
|
+
return {
|
|
59
|
+
content: [{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: `❌ Error: draft_plan too long (${draftPlan.length}/${config.maxDraftPlanLength} chars).`,
|
|
62
|
+
}],
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const services = await getServices();
|
|
68
|
+
const result = await services.councilService.run({
|
|
69
|
+
draftPlan,
|
|
70
|
+
techStack: params.tech_stack,
|
|
71
|
+
contextConstraints: params.context_constraints,
|
|
72
|
+
}, {
|
|
73
|
+
personaOverride: params.personas,
|
|
74
|
+
personaModelsOverride: params.persona_models,
|
|
75
|
+
consolidationModelOverride: params.consolidation_model,
|
|
76
|
+
maxTokensOverride: params.max_tokens,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: "text", text: result.finalBlueprint }],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: "text", text: `❌ Council error: ${msg}` }],
|
|
86
|
+
isError: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// ─── Session History ───
|
|
91
|
+
server.tool("get_session_history", "Retrieve previous council session summaries.", {
|
|
92
|
+
limit: z.number().min(1).max(50).default(10).describe("Number of sessions to retrieve"),
|
|
93
|
+
}, async (params) => {
|
|
94
|
+
const services = await getServices();
|
|
95
|
+
const sessions = services.databaseService.getRecentSessions(params.limit);
|
|
96
|
+
if (sessions.length === 0) {
|
|
97
|
+
return { content: [{ type: "text", text: "No previous sessions found." }] };
|
|
98
|
+
}
|
|
99
|
+
let output = "# Recent Council Sessions\n\n";
|
|
100
|
+
for (const s of sessions) {
|
|
101
|
+
output += `## ${s.id.slice(0, 8)}… (${s.created_at})\n`;
|
|
102
|
+
if (s.tech_stack)
|
|
103
|
+
output += `**Stack**: ${s.tech_stack}\n`;
|
|
104
|
+
if (s.draft_plan_summary)
|
|
105
|
+
output += `**Plan**: ${s.draft_plan_summary}…\n`;
|
|
106
|
+
output += "\n";
|
|
107
|
+
}
|
|
108
|
+
return { content: [{ type: "text", text: output }] };
|
|
109
|
+
});
|
|
110
|
+
// ─── Persona Listing ───
|
|
111
|
+
server.tool("list_personas", "List all expert personas in the council.", {}, async () => {
|
|
112
|
+
const services = await getServices();
|
|
113
|
+
const personaIds = services.personaService.getAvailablePersonaIds();
|
|
114
|
+
const allPersonas = services.personaService.createExperts(personaIds, 'default');
|
|
115
|
+
let output = "# Council Personas\n\n";
|
|
116
|
+
for (const p of allPersonas) {
|
|
117
|
+
output += `## ${p.emoji} ${p.name}\n`;
|
|
118
|
+
output += `**ID**: \`${p.id}\`\n`;
|
|
119
|
+
output += `**Focus**: ${p.focusAreas.join(", ")}\n\n`;
|
|
120
|
+
}
|
|
121
|
+
return { content: [{ type: "text", text: output }] };
|
|
122
|
+
});
|
|
123
|
+
// ─── Health Check ───
|
|
124
|
+
server.tool("ping", "Test if Council MCP is running.", {}, async () => ({
|
|
125
|
+
content: [{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: "🏓 Council MCP is running! Use 'consult_council' to get expert analysis.",
|
|
128
|
+
}],
|
|
129
|
+
}));
|
|
130
|
+
// ─── Start ───
|
|
131
|
+
async function main() {
|
|
132
|
+
const transport = new StdioServerTransport();
|
|
133
|
+
await server.connect(transport);
|
|
134
|
+
console.error("Konsilio MCP server running on stdio");
|
|
135
|
+
}
|
|
136
|
+
main().catch((err) => {
|
|
137
|
+
console.error("Fatal error:", err);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./konsilio.schema.json",
|
|
3
|
+
"personas": {
|
|
4
|
+
"enabled": ["ux-dx", "performance", "node-fullstack", "devops", "dev-tooling", "test-architect"],
|
|
5
|
+
"_comment": "Available personas: security, performance, ux-dx, devops, typescript, graph-dba, node-fullstack, dev-tooling, distributed-systems, test-architect"
|
|
6
|
+
},
|
|
7
|
+
"constitution": "./constitution.txt",
|
|
8
|
+
"models": {
|
|
9
|
+
"experts": "google/gemini-2.5-flash-lite",
|
|
10
|
+
"lead": "google/gemini-2.5-pro"
|
|
11
|
+
},
|
|
12
|
+
"personaModels": {},
|
|
13
|
+
"timeouts": {
|
|
14
|
+
"expertMs": 90000,
|
|
15
|
+
"leadMs": 120000
|
|
16
|
+
},
|
|
17
|
+
"maxTokens": {
|
|
18
|
+
"experts": 16384,
|
|
19
|
+
"lead": 32768
|
|
20
|
+
},
|
|
21
|
+
"maxDraftPlanLength": 12000,
|
|
22
|
+
"maxHistorySessions": 10,
|
|
23
|
+
"databasePath": "./data/db/konsilio.db",
|
|
24
|
+
"cacheTtlSeconds": 3600
|
|
25
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Konsilio Configuration",
|
|
4
|
+
"description": "Configuration file for the Konsilio Council of Experts MCP server",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"$schema": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Path to this JSON schema file for IDE validation"
|
|
10
|
+
},
|
|
11
|
+
"personas": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"description": "Persona configuration for expert analysis",
|
|
14
|
+
"properties": {
|
|
15
|
+
"enabled": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Persona ID (e.g., security, performance, ux-dx, devops, or custom personas)"
|
|
20
|
+
},
|
|
21
|
+
"minItems": 2,
|
|
22
|
+
"description": "Expert personas to include in council consultations. Must have at least 2. Built-in personas: security, performance, ux-dx, devops, typescript, graph-dba, node-fullstack, dev-tooling, distributed-systems, test-architect"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": ["enabled"],
|
|
26
|
+
"additionalProperties": false
|
|
27
|
+
},
|
|
28
|
+
"constitution": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "Path to optional constitution file with custom workflow rules"
|
|
31
|
+
},
|
|
32
|
+
"models": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"description": "Default model configuration for all personas",
|
|
35
|
+
"properties": {
|
|
36
|
+
"experts": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Default model for expert personas. Override per-persona with personaModels."
|
|
39
|
+
},
|
|
40
|
+
"lead": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Model for consolidation phases (extraction, critique, decision, synthesis)"
|
|
43
|
+
},
|
|
44
|
+
"formatter": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "Model used to format prose into structured JSON"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"additionalProperties": false
|
|
50
|
+
},
|
|
51
|
+
"personaModels": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"description": "Per-persona model defaults. Maps personaId to model ID. Overrides models.experts for specific personas.",
|
|
54
|
+
"additionalProperties": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "OpenRouter model ID for this persona"
|
|
57
|
+
},
|
|
58
|
+
"examples": [
|
|
59
|
+
{
|
|
60
|
+
"security": "openai/gpt-4o",
|
|
61
|
+
"performance": "anthropic/claude-sonnet-4"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"timeouts": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"description": "Timeout configuration for API calls",
|
|
68
|
+
"properties": {
|
|
69
|
+
"expertMs": {
|
|
70
|
+
"type": "integer",
|
|
71
|
+
"minimum": 10000,
|
|
72
|
+
"description": "Timeout for expert analysis in milliseconds"
|
|
73
|
+
},
|
|
74
|
+
"leadMs": {
|
|
75
|
+
"type": "integer",
|
|
76
|
+
"minimum": 30000,
|
|
77
|
+
"description": "Timeout for consolidation phases in milliseconds"
|
|
78
|
+
},
|
|
79
|
+
"formatterMs": {
|
|
80
|
+
"type": "integer",
|
|
81
|
+
"minimum": 10000,
|
|
82
|
+
"description": "Timeout for formatting prose in milliseconds"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"additionalProperties": false
|
|
86
|
+
},
|
|
87
|
+
"maxTokens": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"description": "Token limits for API calls",
|
|
90
|
+
"properties": {
|
|
91
|
+
"experts": {
|
|
92
|
+
"type": "integer",
|
|
93
|
+
"minimum": 100,
|
|
94
|
+
"description": "Max tokens per expert analysis"
|
|
95
|
+
},
|
|
96
|
+
"lead": {
|
|
97
|
+
"type": "integer",
|
|
98
|
+
"minimum": 100,
|
|
99
|
+
"description": "Max tokens for consolidation phases"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"additionalProperties": false
|
|
103
|
+
},
|
|
104
|
+
"maxDraftPlanLength": {
|
|
105
|
+
"type": "integer",
|
|
106
|
+
"minimum": 1000,
|
|
107
|
+
"description": "Maximum length of draft plan input in characters"
|
|
108
|
+
},
|
|
109
|
+
"maxHistorySessions": {
|
|
110
|
+
"type": "integer",
|
|
111
|
+
"minimum": 1,
|
|
112
|
+
"maximum": 100,
|
|
113
|
+
"description": "Maximum number of session history entries to retain"
|
|
114
|
+
},
|
|
115
|
+
"databasePath": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"description": "Path to SQLite database file for session storage"
|
|
118
|
+
},
|
|
119
|
+
"cacheTtlSeconds": {
|
|
120
|
+
"type": "integer",
|
|
121
|
+
"minimum": 60,
|
|
122
|
+
"description": "Cache time-to-live in seconds for persona data"
|
|
123
|
+
},
|
|
124
|
+
"formatter": {
|
|
125
|
+
"type": "object",
|
|
126
|
+
"description": "Formatter service configuration",
|
|
127
|
+
"properties": {
|
|
128
|
+
"maxRetries": {
|
|
129
|
+
"type": "integer",
|
|
130
|
+
"minimum": 0,
|
|
131
|
+
"maximum": 10,
|
|
132
|
+
"description": "Maximum retries for formatting failures"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"additionalProperties": false
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"required": ["personas"],
|
|
139
|
+
"additionalProperties": false
|
|
140
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pino-based Structured Logger with correlation ID support
|
|
3
|
+
*
|
|
4
|
+
* Outputs structured JSON logs to stderr for observability and debugging.
|
|
5
|
+
* IMPORTANT: MCP servers MUST use stderr for logs - stdout is reserved for JSON-RPC protocol.
|
|
6
|
+
*/
|
|
7
|
+
import pino from 'pino';
|
|
8
|
+
import type { LogLevel } from './config.js';
|
|
9
|
+
export type { LogLevel };
|
|
10
|
+
/**
|
|
11
|
+
* LogWriter interface - standard logging methods
|
|
12
|
+
* Used for correlated logger instances
|
|
13
|
+
*/
|
|
14
|
+
export interface LogWriter {
|
|
15
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
16
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
17
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
18
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Logger interface - extends LogWriter with correlation ID support
|
|
22
|
+
*/
|
|
23
|
+
export interface Logger extends LogWriter {
|
|
24
|
+
/**
|
|
25
|
+
* Create a child logger with correlation ID embedded in all logs
|
|
26
|
+
*/
|
|
27
|
+
withCorrelationId(correlationId: string): CorrelatedLogger;
|
|
28
|
+
/**
|
|
29
|
+
* Debug with optional correlation ID (backward compatibility)
|
|
30
|
+
*/
|
|
31
|
+
debug(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Info with optional correlation ID (backward compatibility)
|
|
34
|
+
*/
|
|
35
|
+
info(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Warn with optional correlation ID (backward compatibility)
|
|
38
|
+
*/
|
|
39
|
+
warn(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Error with optional correlation ID (backward compatibility)
|
|
42
|
+
*/
|
|
43
|
+
error(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* CorrelatedLogger - logger that automatically includes correlation ID
|
|
47
|
+
*/
|
|
48
|
+
export interface CorrelatedLogger extends LogWriter {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Pino-backed Logger implementation
|
|
52
|
+
*/
|
|
53
|
+
declare class PinoLogger implements Logger {
|
|
54
|
+
protected readonly pino: pino.Logger;
|
|
55
|
+
constructor(level?: LogLevel);
|
|
56
|
+
debug(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
57
|
+
info(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
58
|
+
warn(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
59
|
+
error(message: string, data?: Record<string, unknown>, correlationId?: string): void;
|
|
60
|
+
withCorrelationId(correlationId: string): CorrelatedLogger;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Singleton logger instance configured from LOG_LEVEL env var
|
|
64
|
+
*/
|
|
65
|
+
export declare const logger: PinoLogger;
|
|
66
|
+
/**
|
|
67
|
+
* Create a logger instance with the specified log level
|
|
68
|
+
* @param level - Optional log level (defaults to LOG_LEVEL env var or 'info')
|
|
69
|
+
*/
|
|
70
|
+
export declare function createLogger(level?: LogLevel): Logger;
|
|
71
|
+
/**
|
|
72
|
+
* Get a child logger with correlation ID embedded in all log entries
|
|
73
|
+
* Convenience function equivalent to logger.withCorrelationId()
|
|
74
|
+
*
|
|
75
|
+
* @param correlationId - The correlation ID to include in all log entries
|
|
76
|
+
* @returns A logger instance with the correlation ID
|
|
77
|
+
*/
|
|
78
|
+
export declare function getLogger(correlationId: string): CorrelatedLogger;
|
|
79
|
+
export declare const log: {
|
|
80
|
+
debug: (message: string, data?: Record<string, unknown>) => void;
|
|
81
|
+
info: (message: string, data?: Record<string, unknown>) => void;
|
|
82
|
+
warn: (message: string, data?: Record<string, unknown>) => void;
|
|
83
|
+
error: (message: string, data?: Record<string, unknown>) => void;
|
|
84
|
+
};
|