This document covers the current MCP server surface: how to run it, how to configure clients, and what the exposed tools actually accept today.
LLM Conclave exposes four MCP tools:
llm_conclave_consultllm_conclave_discussllm_conclave_continuellm_conclave_sessions
The server supports two transport modes:
stdiofor normal MCP client launchesSSEfor shared HTTP transport, with an additional REST endpoint for discussion requests
npm installOutput artifact:
dist/src/mcp/server.js
npm install also runs the build automatically via postinstall.
For the shortest first-run path, use:
npm install
npm run setupnpm run setup creates .env from .env.example if missing, validates that the checked-in .mcp.json points to scripts/mcp-stdio.js, builds the server, smoke-tests the MCP stdio launcher with an initialize request, and prints Claude Code next steps.
For Claude Code, prefer a project-local .mcp.json in the repository root.
This repository now includes one by default:
{
"mcpServers": {
"llm-conclave": {
"command": "node",
"args": ["scripts/mcp-stdio.js"]
}
}
}That launcher reads provider keys from the repo's .env file before starting the built server.
{
"mcpServers": {
"llm-conclave": {
"command": "node",
"args": ["/absolute/path/to/llm_conclave/dist/src/mcp/server.js"],
"env": {
"OPENAI_API_KEY": "sk-...",
"ANTHROPIC_API_KEY": "sk-ant-...",
"GOOGLE_API_KEY": "AIza...",
"XAI_API_KEY": "xai-...",
"MISTRAL_API_KEY": "..."
}
}
}
}- Use an absolute path to
dist/src/mcp/server.js - If you use the checked-in
.mcp.json,scripts/mcp-stdio.jshandles.envloading for you - Only include API keys for providers you intend to use
stdiois the normal MCP launch mode; do not add--ssefor direct MCP client launches- After rebuilding or changing config, restart or start a fresh MCP client session
- If the client prompts for MCP server approval, approve
llm-conclave - When Anthropic, OpenAI, and Google are all configured, the default zero-config discussion panel is mixed-provider:
Primary:claude-sonnet-4-5Validator:gpt-4oReviewer:gemini-2.5-pro- Judge default:
gemini-2.5-flash
- If only a subset of provider keys is present, defaults are selected from the available providers automatically
Structured consultation with a fixed 1-4 round flow.
| Parameter | Type | Required | Notes |
|---|---|---|---|
question |
string | Yes | Main prompt |
context |
string | No | File paths or a directory path |
personas |
string | No | Comma-separated personas or configured persona sets |
rounds |
number | No | 1 to 4 |
quick |
boolean | No | Uses 2 consult rounds |
format |
string | No | markdown, json, or both |
judge_model |
string | No | Overrides the consult judge model |
Consult defaults to a three-agent panel if no personas are provided:
- Security Expert
- Systems Architect
- Pragmatic Engineer
Free-form collaborative discussion with persisted sessions.
| Parameter | Type | Required | Notes |
|---|---|---|---|
task |
string | Yes | Main topic |
project |
string | No | File or directory context |
personas |
string | No | Comma-separated personas |
config |
string | No | .llm-conclave.json path or inline JSON |
rounds |
number | No | Default 4 |
min_rounds |
number | No | Default 2; cannot exceed rounds |
dynamic |
boolean | No | Enables LLM-selected speaker order |
selector_model |
string | No | Defaults to gpt-4o-mini |
judge_model |
string | No | Overrides the judge model |
timeout |
number | No | Seconds; 0 disables timeout |
format |
string | No | markdown, json, or both |
judge_instructions |
string | No | Appended to the judge prompt |
context_optimization |
boolean | No | Structured reasoning/position split for lower context cost |
Continue a previous discussion session.
| Parameter | Type | Required | Notes |
|---|---|---|---|
task |
string | Yes | Follow-up request |
session_id |
string | No | Defaults to most recent saved session |
reset |
boolean | No | Reuse only a summary of the prior session |
List recent sessions.
| Parameter | Type | Required | Notes |
|---|---|---|---|
limit |
number | No | Default 10 |
mode |
string | No | consensus, orchestrated, or iterative |
Canonical built-ins:
securityperformancearchitecturecreativeskepticpragmatictestingdevopsaccessibilitydocumentation
Accepted aliases include:
architect,arch->architectureqa,tester,testing,quality->testingsec->securityperf->performancedocs->documentationa11y->accessibilitydevil,devils-advocate->skeptic
Custom personas and persona sets are loaded from ~/.llm-conclave/config.json.
Example:
{
"custom_personas": {
"healthCoach": {
"name": "Health Coach",
"model": "claude-sonnet-4-5",
"systemPrompt": "You are a certified health coach..."
}
},
"persona_sets": {
"health": ["healthCoach", "security"]
}
}Then call personas: "@health" or personas: "@health,architecture".
~/.llm-conclave/config.json
Used for custom personas and persona sets.
.llm-conclave.json
Used for custom agent definitions in discuss mode.
Minimal example:
{
"agents": {
"Architect": {
"model": "gpt-4o",
"prompt": "You are a senior software architect..."
},
"Reviewer": {
"model": "claude-sonnet-4-5",
"prompt": "You challenge assumptions and identify risks..."
}
}
}The config parameter on llm_conclave_discuss also accepts inline JSON.
node dist/src/mcp/server.js --sseEndpoints exposed in SSE mode:
GET /ssePOST /messagesPOST /api/discussGET /health
POST /api/discuss accepts the same discussion parameters as llm_conclave_discuss, with two differences:
- The response is always JSON
configmust be inline JSON, not a file path
Example:
curl -X POST http://localhost:3100/api/discuss \
-H 'Content-Type: application/json' \
-d '{"task":"Review this architecture decision","rounds":2}'Optional auth:
- If
CONCLAVE_API_KEYis unset, no auth is required - If
CONCLAVE_API_KEYis set, sendAuthorization: Bearer <key>
Human-readable summary with structured sections.
Structured payload for programmatic consumers, including fields such as:
summarykey_decisionsaction_itemsdissentconfidenceagentsper_agent_positions— array of{ agent, model?, final_turn_excerpt, truncated }, one entry per participating agent in first-speak order.final_turn_excerptis the last non-error assistant turn, truncated to 800 chars +"..."when longer;truncatedis the pre-truncation length flag. Empty array when no qualifying turns exist.section_order— fixed literal["summary", "agent_positions", "dissent", "key_decisions", "action_items"]. Describes the canonical render layout so JSON consumers can reproduce the markdown's dissent-above-actions ordering without parsing text.session_id
per_agent_positions and section_order are additive fields (AUDIT-01, AUDIT-02) — no pre-existing JSON key was renamed or removed.
The markdown output emitted by llm_conclave_discuss renders sections in this fixed order:
## Summary## Agent Positions— one### <agent>sub-block per participating agent, rendered in first-speak order with the agent's final non-error turn (800-char cap +...). Judge and System speakers are excluded; entries markederror: trueare skipped.## Dissenting Views(rendered whendissent.length > 0)## Key Decisions## Action Items## Discussion Transcript
## Dissenting Views appears above ## Key Decisions and ## Action Items so users see disagreement before recommendations. ## Agent Positions is always-on (not gated on judge failure), so callers can cross-check the judge's synthesis against each agent's raw position on every run.
A separate ## Agent Positions (Last Round) block continues to appear only on the judge-failed fallback path — distinct from the always-on ## Agent Positions section above.
JSON plus a markdown_summary field.
Round numbering is unified across the three surfaces callers observe:
| Surface | Field | Notes |
|---|---|---|
session.json (SessionManifest) |
currentRound |
Session-level counter; written at save time. |
session.json → conversationHistory[] (SessionMessage) |
roundNumber |
Stamped at push time on every production entry. Authoritative per-turn round. |
llm_conclave_sessions listing (SessionSummary) |
roundCount |
Derived from the same stamp as currentRound. |
llm_conclave_status active output |
**Round:** N/max |
1-indexed display. Fresh runs report 1; continuations report the real resume round from the first write. |
DiscussionHistoryEntry.roundNumber (in-memory, pre-save) is typed as optional so legacy test fixtures without stamps still compile, but production push sites in ConversationManager and AgentTurnExecutor always stamp it.
When a session is resumed, the counter is derived from max(priorHistory[*].roundNumber) whenever any entry in the prior history carries a stamp. A legacy Judge-delimiter count is retained as the fallback only for pre-Phase-18 session files with zero stamps. The resume round propagates through:
- The continuation marker entry pushed by
ContinuationHandler.mergeContinuationContext - The follow-up user message (
max + 1) - The reset-branch summary written by
prepareForContinuation(inheritssession.currentRound) - The initial
llm_conclave_statuswrite fromDiscussionRunner— continuations no longer briefly renderRound: 1before the first heartbeat; the correct resume round appears from the first status write
For a session-level round count, read SessionManifest.currentRound (or SessionSummary.roundCount in listings). For per-turn attribution, read SessionMessage.roundNumber on the individual history entry. All three agree by construction; a drift invariant in SessionManager.createSessionManifest throws under Jest (NODE_ENV=test) or when LLM_CONCLAVE_STRICT_ROUND_COUNTER=1 is set, and warns via console.warn in production.
npm run mcp-devruns the server throughts-node- For local test runs in constrained environments, use
--watchman=false - The current tests cover the MCP server handlers and transport paths directly