@debatetalk/mcp 1.0.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 +21 -0
- package/README.md +191 -0
- package/dist/chunk-MEP3QJFT.js +133 -0
- package/dist/chunk-MEP3QJFT.js.map +1 -0
- package/dist/cli/index.js +232 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/mcp/server.js +301 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DebateTalk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# DebateTalk MCP
|
|
2
|
+
|
|
3
|
+
> Official MCP server and CLI for [DebateTalk](https://debatetalk.ai) — run structured multi-model AI debates from your AI assistant or terminal.
|
|
4
|
+
|
|
5
|
+
DebateTalk makes multiple AI models argue a question independently, challenge each other's reasoning, and converge on a structured synthesis: **Strong Ground, Fault Lines, Blind Spots, and Your Call.**
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **MCP server** — connect Claude Desktop, Cursor, or any MCP-compatible client to DebateTalk
|
|
12
|
+
- **CLI** — run debates and check model status from the terminal
|
|
13
|
+
- **Streaming output** — debates stream in real time via SSE
|
|
14
|
+
- **5 tools:** `run_debate`, `get_model_status`, `recommend_models`, `estimate_cost`, `get_history`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Quickstart
|
|
19
|
+
|
|
20
|
+
### MCP (Claude Desktop / Cursor)
|
|
21
|
+
|
|
22
|
+
**1. Get an API key**
|
|
23
|
+
|
|
24
|
+
Create a key at [console.debatetalk.ai/api-keys](https://console.debatetalk.ai/api-keys). Requires a Pro or Enterprise plan. Free tier: 5 debates/day.
|
|
25
|
+
|
|
26
|
+
**2. Add to your MCP client config**
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"debatetalk": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "@debatetalk/mcp"],
|
|
34
|
+
"env": {
|
|
35
|
+
"DEBATETALK_API_KEY": "dt_your_key_here"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Config file locations:
|
|
43
|
+
- **Claude Desktop (Mac):** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
44
|
+
- **Claude Desktop (Windows):** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
45
|
+
- **Cursor:** `.cursor/mcp.json` in your project root
|
|
46
|
+
|
|
47
|
+
**3. Ask Claude to run a debate**
|
|
48
|
+
|
|
49
|
+
> *"Use DebateTalk to debate whether we should rewrite our backend in Go."*
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### CLI
|
|
54
|
+
|
|
55
|
+
Install globally:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install -g @debatetalk/mcp
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Set your API key:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
export DEBATETALK_API_KEY=dt_your_key_here
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Run a debate:**
|
|
68
|
+
```bash
|
|
69
|
+
debatetalk debate "Should we adopt microservices?"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Check which models are online:**
|
|
73
|
+
```bash
|
|
74
|
+
debatetalk models
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Get a recommended model panel for your question:**
|
|
78
|
+
```bash
|
|
79
|
+
debatetalk recommend "Is Rust worth learning in 2026?"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Estimate cost before running:**
|
|
83
|
+
```bash
|
|
84
|
+
debatetalk cost "Should we raise our Series A now?"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**View past debates:**
|
|
88
|
+
```bash
|
|
89
|
+
debatetalk history
|
|
90
|
+
debatetalk history --limit 5
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## MCP Tools Reference
|
|
96
|
+
|
|
97
|
+
| Tool | Auth required | Description |
|
|
98
|
+
|------|--------------|-------------|
|
|
99
|
+
| `run_debate` | Yes | Run a structured multi-model debate (streaming) |
|
|
100
|
+
| `get_model_status` | No | Real-time health and latency for all models |
|
|
101
|
+
| `recommend_models` | No | Get the best model panel for your question |
|
|
102
|
+
| `estimate_cost` | Yes | Estimate credit cost before running |
|
|
103
|
+
| `get_history` | Yes | List your past debates |
|
|
104
|
+
|
|
105
|
+
### `run_debate`
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
question string required The question or topic to debate
|
|
109
|
+
models array optional Specific model IDs to use (omit for smart routing)
|
|
110
|
+
rounds number optional Number of deliberation rounds (default: 2)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `get_model_status`
|
|
114
|
+
|
|
115
|
+
No parameters. Returns live health, latency, and uptime per model.
|
|
116
|
+
|
|
117
|
+
### `recommend_models`
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
question string required The question — routing picks the strongest panel
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `estimate_cost`
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
question string required
|
|
127
|
+
models array optional
|
|
128
|
+
rounds number optional
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `get_history`
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
limit number optional Number of debates to return (default: 20, max: 100)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Configuration
|
|
140
|
+
|
|
141
|
+
| Variable | Required | Description |
|
|
142
|
+
|----------|----------|-------------|
|
|
143
|
+
| `DEBATETALK_API_KEY` | For authenticated tools | Your API key from console.debatetalk.ai |
|
|
144
|
+
|
|
145
|
+
Public tools (`get_model_status`, `recommend_models`) work without an API key.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Plans & Limits
|
|
150
|
+
|
|
151
|
+
| Plan | Debates/day | API keys | Debaters |
|
|
152
|
+
|------|-------------|----------|---------|
|
|
153
|
+
| Free | 5 | — | 3 |
|
|
154
|
+
| Pro | Unlimited | 2 | 5 |
|
|
155
|
+
| Enterprise | Unlimited | Unlimited | 10 |
|
|
156
|
+
|
|
157
|
+
[Full pricing →](https://debatetalk.ai/resources/plans-and-limits)
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Development
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
git clone https://github.com/DebateTalk-AI/mcp
|
|
165
|
+
cd debatetalk-mcp
|
|
166
|
+
npm install
|
|
167
|
+
npm run build
|
|
168
|
+
npm test
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Run MCP server locally:**
|
|
172
|
+
```bash
|
|
173
|
+
DEBATETALK_API_KEY=dt_your_key npm run dev:mcp
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Run CLI locally:**
|
|
177
|
+
```bash
|
|
178
|
+
DEBATETALK_API_KEY=dt_your_key npm run dev:cli -- debate "your question"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Contributing
|
|
184
|
+
|
|
185
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md). Issues and PRs welcome.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
import { EventSourceParserStream } from "eventsource-parser/stream";
|
|
5
|
+
var BASE_URL = "https://engine.debatetalk.ai";
|
|
6
|
+
var DebateTalkError = class extends Error {
|
|
7
|
+
constructor(status, message, code) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = "DebateTalkError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var DebateTalkClient = class {
|
|
15
|
+
apiKey;
|
|
16
|
+
constructor(apiKey) {
|
|
17
|
+
this.apiKey = apiKey ?? process.env["DEBATETALK_API_KEY"];
|
|
18
|
+
}
|
|
19
|
+
get authHeaders() {
|
|
20
|
+
if (!this.apiKey) return {};
|
|
21
|
+
return { Authorization: `Bearer ${this.apiKey}` };
|
|
22
|
+
}
|
|
23
|
+
get baseHeaders() {
|
|
24
|
+
return { "Content-Type": "application/json", ...this.authHeaders };
|
|
25
|
+
}
|
|
26
|
+
requireAuth() {
|
|
27
|
+
if (!this.apiKey) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
"DEBATETALK_API_KEY is required for this operation. Create one at https://console.debatetalk.ai/api-keys"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async request(method, path, body) {
|
|
34
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
35
|
+
method,
|
|
36
|
+
headers: this.baseHeaders,
|
|
37
|
+
...body !== void 0 && { body: JSON.stringify(body) }
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const payload = await res.json().catch(() => ({
|
|
41
|
+
error: { code: "unknown", message: res.statusText }
|
|
42
|
+
}));
|
|
43
|
+
throw new DebateTalkError(
|
|
44
|
+
res.status,
|
|
45
|
+
payload.error?.message ?? res.statusText,
|
|
46
|
+
payload.error?.code
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return res.json();
|
|
50
|
+
}
|
|
51
|
+
// ── Public endpoints (no auth required) ──────────────────────────────────
|
|
52
|
+
async getModelStatus() {
|
|
53
|
+
return this.request("GET", "/v1/public/model-status");
|
|
54
|
+
}
|
|
55
|
+
async recommendModels(question) {
|
|
56
|
+
return this.request("POST", "/v1/models/recommend", {
|
|
57
|
+
question
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// ── Authenticated endpoints ───────────────────────────────────────────────
|
|
61
|
+
async estimateCost(params) {
|
|
62
|
+
this.requireAuth();
|
|
63
|
+
return this.request("POST", "/v1/user/estimate-cost", params);
|
|
64
|
+
}
|
|
65
|
+
async getHistory(limit = 20) {
|
|
66
|
+
this.requireAuth();
|
|
67
|
+
return this.request(
|
|
68
|
+
"GET",
|
|
69
|
+
`/v1/user/history?limit=${limit}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
async *streamDebate(params) {
|
|
73
|
+
this.requireAuth();
|
|
74
|
+
const res = await fetch(`${BASE_URL}/debate`, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: { ...this.baseHeaders, Accept: "text/event-stream" },
|
|
77
|
+
body: JSON.stringify(params)
|
|
78
|
+
});
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
const payload = await res.json().catch(() => ({
|
|
81
|
+
error: { code: "unknown", message: res.statusText }
|
|
82
|
+
}));
|
|
83
|
+
throw new DebateTalkError(
|
|
84
|
+
res.status,
|
|
85
|
+
payload.error?.message ?? res.statusText,
|
|
86
|
+
payload.error?.code
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
if (!res.body) throw new DebateTalkError(0, "No response body");
|
|
90
|
+
const stream = res.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream());
|
|
91
|
+
for await (const event of stream) {
|
|
92
|
+
if (!event.data || event.data === "[DONE]") continue;
|
|
93
|
+
try {
|
|
94
|
+
yield JSON.parse(event.data);
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async runDebate(params) {
|
|
100
|
+
const events = [];
|
|
101
|
+
let debateId = "";
|
|
102
|
+
let questionType = "";
|
|
103
|
+
let models = [];
|
|
104
|
+
let synthesis = null;
|
|
105
|
+
for await (const event of this.streamDebate(params)) {
|
|
106
|
+
events.push(event);
|
|
107
|
+
if (event.type === "debate_start") {
|
|
108
|
+
debateId = event.data["debate_id"] ?? "";
|
|
109
|
+
models = event.data["models"] ?? [];
|
|
110
|
+
}
|
|
111
|
+
if (event.type === "classification") {
|
|
112
|
+
questionType = event.data["question_type"] ?? "";
|
|
113
|
+
}
|
|
114
|
+
if (event.type === "synthesis") {
|
|
115
|
+
synthesis = event.data;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
debate_id: debateId,
|
|
120
|
+
question: params.question,
|
|
121
|
+
question_type: questionType,
|
|
122
|
+
models,
|
|
123
|
+
synthesis,
|
|
124
|
+
events
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
DebateTalkError,
|
|
131
|
+
DebateTalkClient
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=chunk-MEP3QJFT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport type {\n ModelStatusResponse,\n RecommendResponse,\n EstimateCostParams,\n CostEstimate,\n HistoryResponse,\n DebateParams,\n DebateEvent,\n DebateResult,\n ApiErrorBody,\n SynthesisData,\n} from \"./types.js\";\n\nconst BASE_URL = \"https://engine.debatetalk.ai\";\n\nexport class DebateTalkError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly code?: string\n ) {\n super(message);\n this.name = \"DebateTalkError\";\n }\n}\n\nexport class DebateTalkClient {\n private readonly apiKey: string | undefined;\n\n constructor(apiKey?: string) {\n this.apiKey = apiKey ?? process.env[\"DEBATETALK_API_KEY\"];\n }\n\n private get authHeaders(): Record<string, string> {\n if (!this.apiKey) return {};\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n private get baseHeaders(): Record<string, string> {\n return { \"Content-Type\": \"application/json\", ...this.authHeaders };\n }\n\n private requireAuth(): void {\n if (!this.apiKey) {\n throw new Error(\n \"DEBATETALK_API_KEY is required for this operation. \" +\n \"Create one at https://console.debatetalk.ai/api-keys\"\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const res = await fetch(`${BASE_URL}${path}`, {\n method,\n headers: this.baseHeaders,\n ...(body !== undefined && { body: JSON.stringify(body) }),\n });\n\n if (!res.ok) {\n const payload = await res.json().catch(() => ({\n error: { code: \"unknown\", message: res.statusText },\n })) as ApiErrorBody;\n throw new DebateTalkError(\n res.status,\n payload.error?.message ?? res.statusText,\n payload.error?.code\n );\n }\n\n return res.json() as Promise<T>;\n }\n\n // ── Public endpoints (no auth required) ──────────────────────────────────\n\n async getModelStatus(): Promise<ModelStatusResponse> {\n return this.request<ModelStatusResponse>(\"GET\", \"/v1/public/model-status\");\n }\n\n async recommendModels(question: string): Promise<RecommendResponse> {\n return this.request<RecommendResponse>(\"POST\", \"/v1/models/recommend\", {\n question,\n });\n }\n\n // ── Authenticated endpoints ───────────────────────────────────────────────\n\n async estimateCost(params: EstimateCostParams): Promise<CostEstimate> {\n this.requireAuth();\n return this.request<CostEstimate>(\"POST\", \"/v1/user/estimate-cost\", params);\n }\n\n async getHistory(limit = 20): Promise<HistoryResponse> {\n this.requireAuth();\n return this.request<HistoryResponse>(\n \"GET\",\n `/v1/user/history?limit=${limit}`\n );\n }\n\n async *streamDebate(params: DebateParams): AsyncGenerator<DebateEvent> {\n this.requireAuth();\n\n const res = await fetch(`${BASE_URL}/debate`, {\n method: \"POST\",\n headers: { ...this.baseHeaders, Accept: \"text/event-stream\" },\n body: JSON.stringify(params),\n });\n\n if (!res.ok) {\n const payload = await res.json().catch(() => ({\n error: { code: \"unknown\", message: res.statusText },\n })) as ApiErrorBody;\n throw new DebateTalkError(\n res.status,\n payload.error?.message ?? res.statusText,\n payload.error?.code\n );\n }\n\n if (!res.body) throw new DebateTalkError(0, \"No response body\");\n\n const stream = res.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream());\n\n for await (const event of stream) {\n if (!event.data || event.data === \"[DONE]\") continue;\n try {\n yield JSON.parse(event.data) as DebateEvent;\n } catch {\n // skip malformed events\n }\n }\n }\n\n async runDebate(params: DebateParams): Promise<DebateResult> {\n const events: DebateEvent[] = [];\n let debateId = \"\";\n let questionType = \"\";\n let models: string[] = [];\n let synthesis: SynthesisData | null = null;\n\n for await (const event of this.streamDebate(params)) {\n events.push(event);\n\n if (event.type === \"debate_start\") {\n debateId = (event.data[\"debate_id\"] as string | undefined) ?? \"\";\n models = (event.data[\"models\"] as string[] | undefined) ?? [];\n }\n if (event.type === \"classification\") {\n questionType =\n (event.data[\"question_type\"] as string | undefined) ?? \"\";\n }\n if (event.type === \"synthesis\") {\n synthesis = event.data as unknown as SynthesisData;\n }\n }\n\n return {\n debate_id: debateId,\n question: params.question,\n question_type: questionType,\n models,\n synthesis,\n events,\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DebateTalkClient,
|
|
4
|
+
DebateTalkError
|
|
5
|
+
} from "../chunk-MEP3QJFT.js";
|
|
6
|
+
|
|
7
|
+
// src/cli/index.ts
|
|
8
|
+
import { Command as Command6 } from "commander";
|
|
9
|
+
|
|
10
|
+
// src/cli/commands/debate.ts
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import chalk2 from "chalk";
|
|
13
|
+
import ora from "ora";
|
|
14
|
+
|
|
15
|
+
// src/cli/utils.ts
|
|
16
|
+
import chalk from "chalk";
|
|
17
|
+
function handleError(err) {
|
|
18
|
+
if (err instanceof DebateTalkError) {
|
|
19
|
+
if (err.status === 401 || err.status === 403) {
|
|
20
|
+
console.error(chalk.red("Authentication failed."));
|
|
21
|
+
console.error(
|
|
22
|
+
chalk.dim(
|
|
23
|
+
"Set DEBATETALK_API_KEY or create a key at https://console.debatetalk.ai/api-keys"
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
} else if (err.status === 429) {
|
|
27
|
+
console.error(chalk.red("Rate limit reached."));
|
|
28
|
+
console.error(chalk.dim("Free plan: 5 debates/day. Upgrade at https://debatetalk.ai"));
|
|
29
|
+
} else {
|
|
30
|
+
console.error(chalk.red(`API error (${err.status}): ${err.message}`));
|
|
31
|
+
}
|
|
32
|
+
} else if (err instanceof Error) {
|
|
33
|
+
console.error(chalk.red(err.message));
|
|
34
|
+
} else {
|
|
35
|
+
console.error(chalk.red("An unexpected error occurred."));
|
|
36
|
+
}
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/cli/commands/debate.ts
|
|
41
|
+
function debateCommand() {
|
|
42
|
+
return new Command("debate").description("Run a structured multi-model AI debate").argument("<question>", "The question or topic to debate").option(
|
|
43
|
+
"--models <ids>",
|
|
44
|
+
"Comma-separated model IDs (omit for smart routing)"
|
|
45
|
+
).option("--rounds <n>", "Number of deliberation rounds (default: 2)").action(
|
|
46
|
+
async (question, opts) => {
|
|
47
|
+
const client = new DebateTalkClient();
|
|
48
|
+
const params = {
|
|
49
|
+
question,
|
|
50
|
+
...opts.models && { models: opts.models.split(",").map((s) => s.trim()) },
|
|
51
|
+
...opts.rounds && { rounds: parseInt(opts.rounds, 10) }
|
|
52
|
+
};
|
|
53
|
+
const spinner = ora("Starting debate\u2026").start();
|
|
54
|
+
try {
|
|
55
|
+
let currentPhase = "";
|
|
56
|
+
for await (const event of client.streamDebate(params)) {
|
|
57
|
+
const phase = getPhaseLabel(event);
|
|
58
|
+
if (phase && phase !== currentPhase) {
|
|
59
|
+
currentPhase = phase;
|
|
60
|
+
spinner.text = phase;
|
|
61
|
+
}
|
|
62
|
+
if (event.type === "synthesis") {
|
|
63
|
+
spinner.succeed("Debate complete");
|
|
64
|
+
printSynthesis(question, event);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
spinner.fail("Debate ended without synthesis");
|
|
69
|
+
} catch (err) {
|
|
70
|
+
spinner.fail("Debate failed");
|
|
71
|
+
handleError(err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
function getPhaseLabel(event) {
|
|
77
|
+
switch (event.type) {
|
|
78
|
+
case "debate_start":
|
|
79
|
+
return "Debate starting\u2026";
|
|
80
|
+
case "classification":
|
|
81
|
+
return `Classifying question (${event.data["question_type"] ?? "\u2026"})`;
|
|
82
|
+
case "round_start":
|
|
83
|
+
return `Round ${event.data["round"] ?? "?"} \u2014 models deliberating\u2026`;
|
|
84
|
+
case "consensus":
|
|
85
|
+
return "Checking consensus\u2026";
|
|
86
|
+
case "synthesis":
|
|
87
|
+
return "Generating synthesis\u2026";
|
|
88
|
+
default:
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function printSynthesis(question, event) {
|
|
93
|
+
const d = event.data;
|
|
94
|
+
console.log();
|
|
95
|
+
console.log(chalk2.bold(`"${question}"`));
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(chalk2.bold.green("\u2501\u2501\u2501 STRONG GROUND \u2501\u2501\u2501"));
|
|
98
|
+
console.log(d["strong_ground"] ?? "");
|
|
99
|
+
console.log();
|
|
100
|
+
console.log(chalk2.bold.yellow("\u2501\u2501\u2501 FAULT LINES \u2501\u2501\u2501"));
|
|
101
|
+
console.log(d["fault_lines"] ?? "");
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(chalk2.bold.magenta("\u2501\u2501\u2501 BLIND SPOTS \u2501\u2501\u2501"));
|
|
104
|
+
console.log(d["blind_spots"] ?? "");
|
|
105
|
+
console.log();
|
|
106
|
+
console.log(chalk2.bold.cyan("\u2501\u2501\u2501 YOUR CALL \u2501\u2501\u2501"));
|
|
107
|
+
console.log(d["your_call"] ?? "");
|
|
108
|
+
console.log();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/cli/commands/models.ts
|
|
112
|
+
import { Command as Command2 } from "commander";
|
|
113
|
+
import chalk3 from "chalk";
|
|
114
|
+
function modelsCommand() {
|
|
115
|
+
return new Command2("models").description("Show real-time health and latency for all DebateTalk models").action(async () => {
|
|
116
|
+
const client = new DebateTalkClient();
|
|
117
|
+
try {
|
|
118
|
+
const { models, updated_at } = await client.getModelStatus();
|
|
119
|
+
const online = models.filter((m) => m.status === "online").length;
|
|
120
|
+
console.log(
|
|
121
|
+
chalk3.bold(`Model Status`) + chalk3.dim(` \u2014 ${online}/${models.length} online (updated ${updated_at})`)
|
|
122
|
+
);
|
|
123
|
+
console.log();
|
|
124
|
+
for (const m of models) {
|
|
125
|
+
const icon = m.status === "online" ? chalk3.green("\u2713") : m.status === "degraded" ? chalk3.yellow("\u26A0") : chalk3.red("\u2717");
|
|
126
|
+
const latency = m.latency_ms != null ? chalk3.dim(` ${m.latency_ms}ms`) : "";
|
|
127
|
+
console.log(` ${icon} ${m.display_name}${latency}`);
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
handleError(err);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/cli/commands/recommend.ts
|
|
136
|
+
import { Command as Command3 } from "commander";
|
|
137
|
+
import chalk4 from "chalk";
|
|
138
|
+
function recommendCommand() {
|
|
139
|
+
return new Command3("recommend").description("Get the best model panel for a question").argument("<question>", "The question to get recommendations for").action(async (question) => {
|
|
140
|
+
const client = new DebateTalkClient();
|
|
141
|
+
try {
|
|
142
|
+
const rec = await client.recommendModels(question);
|
|
143
|
+
console.log(chalk4.bold(`Recommended panel`) + chalk4.dim(` for "${question}"`));
|
|
144
|
+
console.log(chalk4.dim(`Question type: ${rec.question_type}`));
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(` ${chalk4.cyan("Debaters:")} ${rec.debaters.join(", ")}`);
|
|
147
|
+
console.log(` ${chalk4.cyan("Synthesizer:")} ${rec.synthesizer}`);
|
|
148
|
+
console.log(` ${chalk4.cyan("Adjudicator:")} ${rec.adjudicator}`);
|
|
149
|
+
} catch (err) {
|
|
150
|
+
handleError(err);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/cli/commands/cost.ts
|
|
156
|
+
import { Command as Command4 } from "commander";
|
|
157
|
+
import chalk5 from "chalk";
|
|
158
|
+
function costCommand() {
|
|
159
|
+
return new Command4("cost").description("Estimate the credit cost of a debate before running it").argument("<question>", "The question to estimate cost for").option("--rounds <n>", "Number of deliberation rounds", "2").action(async (question, opts) => {
|
|
160
|
+
const client = new DebateTalkClient();
|
|
161
|
+
try {
|
|
162
|
+
const est = await client.estimateCost({
|
|
163
|
+
question,
|
|
164
|
+
rounds: parseInt(opts.rounds, 10)
|
|
165
|
+
});
|
|
166
|
+
console.log(chalk5.bold(`Cost estimate`));
|
|
167
|
+
console.log();
|
|
168
|
+
console.log(
|
|
169
|
+
` ${chalk5.cyan("Total:")} ${est.estimated_credits} credits` + chalk5.dim(` (~$${est.estimated_usd.toFixed(2)} USD)`)
|
|
170
|
+
);
|
|
171
|
+
console.log();
|
|
172
|
+
console.log(chalk5.dim(" Breakdown:"));
|
|
173
|
+
for (const b of est.breakdown) {
|
|
174
|
+
console.log(
|
|
175
|
+
chalk5.dim(
|
|
176
|
+
` \u2022 ${b.model} (${b.role}): ~${b.estimated_tokens.toLocaleString()} tokens = ${b.estimated_credits} credits`
|
|
177
|
+
)
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
} catch (err) {
|
|
181
|
+
handleError(err);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/cli/commands/history.ts
|
|
187
|
+
import { Command as Command5 } from "commander";
|
|
188
|
+
import chalk6 from "chalk";
|
|
189
|
+
function historyCommand() {
|
|
190
|
+
return new Command5("history").description("List your past debates").option("--limit <n>", "Number of debates to show", "20").action(async (opts) => {
|
|
191
|
+
const client = new DebateTalkClient();
|
|
192
|
+
try {
|
|
193
|
+
const { debates, total } = await client.getHistory(
|
|
194
|
+
parseInt(opts.limit, 10)
|
|
195
|
+
);
|
|
196
|
+
if (debates.length === 0) {
|
|
197
|
+
console.log(chalk6.dim('No debates yet. Run: debatetalk debate "your question"'));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
console.log(
|
|
201
|
+
chalk6.bold(`Debate history`) + chalk6.dim(` \u2014 showing ${debates.length} of ${total}`)
|
|
202
|
+
);
|
|
203
|
+
console.log();
|
|
204
|
+
for (const d of debates) {
|
|
205
|
+
const date = new Date(d.created_at).toLocaleDateString("en-US", {
|
|
206
|
+
year: "numeric",
|
|
207
|
+
month: "short",
|
|
208
|
+
day: "numeric"
|
|
209
|
+
});
|
|
210
|
+
const share = d.share_token ? chalk6.dim(` \u2192 https://console.debatetalk.ai/share/${d.share_token}`) : "";
|
|
211
|
+
console.log(
|
|
212
|
+
` ${chalk6.dim(date)} ${d.title}` + chalk6.dim(` (${d.model_count} models)`) + share
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
handleError(err);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/cli/index.ts
|
|
222
|
+
var program = new Command6();
|
|
223
|
+
program.name("debatetalk").description(
|
|
224
|
+
"DebateTalk CLI \u2014 run structured multi-model AI debates from your terminal.\nDocs: https://debatetalk.ai/resources/api-reference"
|
|
225
|
+
).version("1.0.0");
|
|
226
|
+
program.addCommand(debateCommand());
|
|
227
|
+
program.addCommand(modelsCommand());
|
|
228
|
+
program.addCommand(recommendCommand());
|
|
229
|
+
program.addCommand(costCommand());
|
|
230
|
+
program.addCommand(historyCommand());
|
|
231
|
+
program.parse();
|
|
232
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/debate.ts","../../src/cli/utils.ts","../../src/cli/commands/models.ts","../../src/cli/commands/recommend.ts","../../src/cli/commands/cost.ts","../../src/cli/commands/history.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { debateCommand } from \"./commands/debate.js\";\nimport { modelsCommand } from \"./commands/models.js\";\nimport { recommendCommand } from \"./commands/recommend.js\";\nimport { costCommand } from \"./commands/cost.js\";\nimport { historyCommand } from \"./commands/history.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"debatetalk\")\n .description(\n \"DebateTalk CLI — run structured multi-model AI debates from your terminal.\\n\" +\n \"Docs: https://debatetalk.ai/resources/api-reference\"\n )\n .version(\"1.0.0\");\n\nprogram.addCommand(debateCommand());\nprogram.addCommand(modelsCommand());\nprogram.addCommand(recommendCommand());\nprogram.addCommand(costCommand());\nprogram.addCommand(historyCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { DebateTalkClient } from \"../../client.js\";\nimport { handleError } from \"../utils.js\";\nimport type { DebateEvent } from \"../../types.js\";\n\nexport function debateCommand(): Command {\n return new Command(\"debate\")\n .description(\"Run a structured multi-model AI debate\")\n .argument(\"<question>\", \"The question or topic to debate\")\n .option(\n \"--models <ids>\",\n \"Comma-separated model IDs (omit for smart routing)\"\n )\n .option(\"--rounds <n>\", \"Number of deliberation rounds (default: 2)\")\n .action(\n async (\n question: string,\n opts: { models?: string; rounds?: string }\n ) => {\n const client = new DebateTalkClient();\n const params = {\n question,\n ...(opts.models && { models: opts.models.split(\",\").map((s) => s.trim()) }),\n ...(opts.rounds && { rounds: parseInt(opts.rounds, 10) }),\n };\n\n const spinner = ora(\"Starting debate…\").start();\n\n try {\n let currentPhase = \"\";\n\n for await (const event of client.streamDebate(params)) {\n const phase = getPhaseLabel(event);\n if (phase && phase !== currentPhase) {\n currentPhase = phase;\n spinner.text = phase;\n }\n\n if (event.type === \"synthesis\") {\n spinner.succeed(\"Debate complete\");\n printSynthesis(question, event);\n return;\n }\n }\n\n spinner.fail(\"Debate ended without synthesis\");\n } catch (err) {\n spinner.fail(\"Debate failed\");\n handleError(err);\n }\n }\n );\n}\n\nfunction getPhaseLabel(event: DebateEvent): string | null {\n switch (event.type) {\n case \"debate_start\":\n return \"Debate starting…\";\n case \"classification\":\n return `Classifying question (${(event.data[\"question_type\"] as string | undefined) ?? \"…\"})`;\n case \"round_start\":\n return `Round ${(event.data[\"round\"] as number | undefined) ?? \"?\"} — models deliberating…`;\n case \"consensus\":\n return \"Checking consensus…\";\n case \"synthesis\":\n return \"Generating synthesis…\";\n default:\n return null;\n }\n}\n\nfunction printSynthesis(question: string, event: DebateEvent): void {\n const d = event.data as Record<string, string>;\n console.log();\n console.log(chalk.bold(`\"${question}\"`));\n console.log();\n console.log(chalk.bold.green(\"━━━ STRONG GROUND ━━━\"));\n console.log(d[\"strong_ground\"] ?? \"\");\n console.log();\n console.log(chalk.bold.yellow(\"━━━ FAULT LINES ━━━\"));\n console.log(d[\"fault_lines\"] ?? \"\");\n console.log();\n console.log(chalk.bold.magenta(\"━━━ BLIND SPOTS ━━━\"));\n console.log(d[\"blind_spots\"] ?? \"\");\n console.log();\n console.log(chalk.bold.cyan(\"━━━ YOUR CALL ━━━\"));\n console.log(d[\"your_call\"] ?? \"\");\n console.log();\n}\n","import chalk from \"chalk\";\nimport { DebateTalkError } from \"../client.js\";\n\nexport function handleError(err: unknown): never {\n if (err instanceof DebateTalkError) {\n if (err.status === 401 || err.status === 403) {\n console.error(chalk.red(\"Authentication failed.\"));\n console.error(\n chalk.dim(\n \"Set DEBATETALK_API_KEY or create a key at https://console.debatetalk.ai/api-keys\"\n )\n );\n } else if (err.status === 429) {\n console.error(chalk.red(\"Rate limit reached.\"));\n console.error(chalk.dim(\"Free plan: 5 debates/day. Upgrade at https://debatetalk.ai\"));\n } else {\n console.error(chalk.red(`API error (${err.status}): ${err.message}`));\n }\n } else if (err instanceof Error) {\n console.error(chalk.red(err.message));\n } else {\n console.error(chalk.red(\"An unexpected error occurred.\"));\n }\n process.exit(1);\n}\n\nexport function requireApiKey(): string {\n const key = process.env[\"DEBATETALK_API_KEY\"];\n if (!key) {\n console.error(chalk.red(\"DEBATETALK_API_KEY is not set.\"));\n console.error(\n chalk.dim(\"Create a key at https://console.debatetalk.ai/api-keys\")\n );\n process.exit(1);\n }\n return key;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { DebateTalkClient } from \"../../client.js\";\nimport { handleError } from \"../utils.js\";\n\nexport function modelsCommand(): Command {\n return new Command(\"models\")\n .description(\"Show real-time health and latency for all DebateTalk models\")\n .action(async () => {\n const client = new DebateTalkClient();\n try {\n const { models, updated_at } = await client.getModelStatus();\n const online = models.filter((m) => m.status === \"online\").length;\n console.log(\n chalk.bold(`Model Status`) +\n chalk.dim(` — ${online}/${models.length} online (updated ${updated_at})`)\n );\n console.log();\n for (const m of models) {\n const icon =\n m.status === \"online\"\n ? chalk.green(\"✓\")\n : m.status === \"degraded\"\n ? chalk.yellow(\"⚠\")\n : chalk.red(\"✗\");\n const latency =\n m.latency_ms != null ? chalk.dim(` ${m.latency_ms}ms`) : \"\";\n console.log(` ${icon} ${m.display_name}${latency}`);\n }\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { DebateTalkClient } from \"../../client.js\";\nimport { handleError } from \"../utils.js\";\n\nexport function recommendCommand(): Command {\n return new Command(\"recommend\")\n .description(\"Get the best model panel for a question\")\n .argument(\"<question>\", \"The question to get recommendations for\")\n .action(async (question: string) => {\n const client = new DebateTalkClient();\n try {\n const rec = await client.recommendModels(question);\n console.log(chalk.bold(`Recommended panel`) + chalk.dim(` for \"${question}\"`));\n console.log(chalk.dim(`Question type: ${rec.question_type}`));\n console.log();\n console.log(` ${chalk.cyan(\"Debaters:\")} ${rec.debaters.join(\", \")}`);\n console.log(` ${chalk.cyan(\"Synthesizer:\")} ${rec.synthesizer}`);\n console.log(` ${chalk.cyan(\"Adjudicator:\")} ${rec.adjudicator}`);\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { DebateTalkClient } from \"../../client.js\";\nimport { handleError } from \"../utils.js\";\n\nexport function costCommand(): Command {\n return new Command(\"cost\")\n .description(\"Estimate the credit cost of a debate before running it\")\n .argument(\"<question>\", \"The question to estimate cost for\")\n .option(\"--rounds <n>\", \"Number of deliberation rounds\", \"2\")\n .action(async (question: string, opts: { rounds: string }) => {\n const client = new DebateTalkClient();\n try {\n const est = await client.estimateCost({\n question,\n rounds: parseInt(opts.rounds, 10),\n });\n console.log(chalk.bold(`Cost estimate`));\n console.log();\n console.log(\n ` ${chalk.cyan(\"Total:\")} ${est.estimated_credits} credits` +\n chalk.dim(` (~$${est.estimated_usd.toFixed(2)} USD)`)\n );\n console.log();\n console.log(chalk.dim(\" Breakdown:\"));\n for (const b of est.breakdown) {\n console.log(\n chalk.dim(\n ` • ${b.model} (${b.role}): ~${b.estimated_tokens.toLocaleString()} tokens = ${b.estimated_credits} credits`\n )\n );\n }\n } catch (err) {\n handleError(err);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { DebateTalkClient } from \"../../client.js\";\nimport { handleError } from \"../utils.js\";\n\nexport function historyCommand(): Command {\n return new Command(\"history\")\n .description(\"List your past debates\")\n .option(\"--limit <n>\", \"Number of debates to show\", \"20\")\n .action(async (opts: { limit: string }) => {\n const client = new DebateTalkClient();\n try {\n const { debates, total } = await client.getHistory(\n parseInt(opts.limit, 10)\n );\n if (debates.length === 0) {\n console.log(chalk.dim('No debates yet. Run: debatetalk debate \"your question\"'));\n return;\n }\n console.log(\n chalk.bold(`Debate history`) +\n chalk.dim(` — showing ${debates.length} of ${total}`)\n );\n console.log();\n for (const d of debates) {\n const date = new Date(d.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n const share = d.share_token\n ? chalk.dim(` → https://console.debatetalk.ai/share/${d.share_token}`)\n : \"\";\n console.log(\n ` ${chalk.dim(date)} ${d.title}` +\n chalk.dim(` (${d.model_count} models)`) +\n share\n );\n }\n } catch (err) {\n handleError(err);\n }\n });\n}\n"],"mappings":"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","names":["Command","chalk","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command"]}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DebateTalkClient
|
|
4
|
+
} from "../chunk-MEP3QJFT.js";
|
|
5
|
+
|
|
6
|
+
// src/mcp/server.ts
|
|
7
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import {
|
|
10
|
+
CallToolRequestSchema,
|
|
11
|
+
ListToolsRequestSchema
|
|
12
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
|
|
14
|
+
// src/mcp/tools/run_debate.ts
|
|
15
|
+
var runDebateTool = {
|
|
16
|
+
name: "run_debate",
|
|
17
|
+
description: "Run a structured multi-model AI debate on any question. Multiple AI models argue independently in a blind round, deliberate, and converge on a 4-part synthesis: Strong Ground (what all models agree on), Fault Lines (genuine disagreements), Blind Spots (what all models missed), and Your Call (actionable recommendation). Requires an API key (Pro or Enterprise plan). Free tier: 5 debates/day.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
question: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "The question or topic to debate. Can be a decision, prediction, factual question, or open-ended topic."
|
|
24
|
+
},
|
|
25
|
+
models: {
|
|
26
|
+
type: "array",
|
|
27
|
+
items: { type: "string" },
|
|
28
|
+
description: 'Specific model IDs to use as debaters (e.g. ["claude-opus-4-6", "gpt-5.4"]). Omit to let DebateTalk smart routing pick the best panel automatically.'
|
|
29
|
+
},
|
|
30
|
+
rounds: {
|
|
31
|
+
type: "number",
|
|
32
|
+
description: "Number of deliberation rounds (default: 2, max depends on plan)"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
required: ["question"]
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
async function handleRunDebate(client, args) {
|
|
39
|
+
const result = await client.runDebate(args);
|
|
40
|
+
if (!result.synthesis) {
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: "text",
|
|
45
|
+
text: `debate completed \u2014 ${result.debate_id} \u2014 but synthesis was not produced. Check your plan limits at https://console.debatetalk.ai`
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const { strong_ground, fault_lines, blind_spots, your_call } = result.synthesis;
|
|
51
|
+
const modelList = result.models.length > 0 ? result.models.join(", ") : "smart routing";
|
|
52
|
+
return {
|
|
53
|
+
content: [
|
|
54
|
+
{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: [
|
|
57
|
+
`DebateTalk \u2014 ${result.question_type} question`,
|
|
58
|
+
`Question: "${result.question}"`,
|
|
59
|
+
`Models: ${modelList}`,
|
|
60
|
+
`Debate ID: ${result.debate_id}`,
|
|
61
|
+
``,
|
|
62
|
+
`\u2501\u2501\u2501 Strong Ground \u2501\u2501\u2501`,
|
|
63
|
+
`What all models agreed on:`,
|
|
64
|
+
strong_ground,
|
|
65
|
+
``,
|
|
66
|
+
`\u2501\u2501\u2501 Fault Lines \u2501\u2501\u2501`,
|
|
67
|
+
`Where models genuinely disagreed:`,
|
|
68
|
+
fault_lines,
|
|
69
|
+
``,
|
|
70
|
+
`\u2501\u2501\u2501 Blind Spots \u2501\u2501\u2501`,
|
|
71
|
+
`What all models missed:`,
|
|
72
|
+
blind_spots,
|
|
73
|
+
``,
|
|
74
|
+
`\u2501\u2501\u2501 Your Call \u2501\u2501\u2501`,
|
|
75
|
+
your_call
|
|
76
|
+
].join("\n")
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/mcp/tools/get_model_status.ts
|
|
83
|
+
var getModelStatusTool = {
|
|
84
|
+
name: "get_model_status",
|
|
85
|
+
description: "Get real-time health, latency, and uptime for all DebateTalk models. Use this before running a debate to check which models are currently online. No API key required.",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
async function handleGetModelStatus(client) {
|
|
92
|
+
const { models, updated_at } = await client.getModelStatus();
|
|
93
|
+
const rows = models.map((m) => {
|
|
94
|
+
const latency = m.latency_ms != null ? `${m.latency_ms}ms` : "\u2014";
|
|
95
|
+
const uptime = m.uptime_pct != null ? `${m.uptime_pct.toFixed(1)}%` : "\u2014";
|
|
96
|
+
const statusIcon = m.status === "online" ? "\u2713" : m.status === "degraded" ? "\u26A0" : "\u2717";
|
|
97
|
+
return `${statusIcon} ${m.display_name} (${m.provider}) \u2014 ${m.status}, latency: ${latency}, uptime: ${uptime}`;
|
|
98
|
+
}).join("\n");
|
|
99
|
+
const online = models.filter((m) => m.status === "online").length;
|
|
100
|
+
const total = models.length;
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: `Model Status \u2014 ${online}/${total} online (updated ${updated_at})
|
|
106
|
+
|
|
107
|
+
${rows}`
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/mcp/tools/recommend_models.ts
|
|
114
|
+
var recommendModelsTool = {
|
|
115
|
+
name: "recommend_models",
|
|
116
|
+
description: "Get the best model panel recommended by DebateTalk smart routing for a specific question. Returns the ideal debaters, synthesizer, and adjudicator based on the question type. No API key required.",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: {
|
|
120
|
+
question: {
|
|
121
|
+
type: "string",
|
|
122
|
+
description: "The question or topic you want to debate"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
required: ["question"]
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
async function handleRecommendModels(client, args) {
|
|
129
|
+
const rec = await client.recommendModels(args.question);
|
|
130
|
+
const debaterList = rec.debaters.join(", ");
|
|
131
|
+
return {
|
|
132
|
+
content: [
|
|
133
|
+
{
|
|
134
|
+
type: "text",
|
|
135
|
+
text: [
|
|
136
|
+
`Recommended panel for "${args.question}"`,
|
|
137
|
+
`Question type: ${rec.question_type}`,
|
|
138
|
+
``,
|
|
139
|
+
`Debaters: ${debaterList}`,
|
|
140
|
+
`Synthesizer: ${rec.synthesizer}`,
|
|
141
|
+
`Adjudicator: ${rec.adjudicator}`,
|
|
142
|
+
``,
|
|
143
|
+
`To use this panel, run a debate with models: ${rec.debaters.join(", ")}`
|
|
144
|
+
].join("\n")
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/mcp/tools/estimate_cost.ts
|
|
151
|
+
var estimateCostTool = {
|
|
152
|
+
name: "estimate_cost",
|
|
153
|
+
description: "Estimate the credit cost of a debate before running it. Returns total credits, USD cost, and a per-model breakdown. Requires an API key (Pro or Enterprise plan).",
|
|
154
|
+
inputSchema: {
|
|
155
|
+
type: "object",
|
|
156
|
+
properties: {
|
|
157
|
+
question: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "The question to estimate cost for"
|
|
160
|
+
},
|
|
161
|
+
models: {
|
|
162
|
+
type: "array",
|
|
163
|
+
items: { type: "string" },
|
|
164
|
+
description: "Specific model IDs to use (omit for smart routing)"
|
|
165
|
+
},
|
|
166
|
+
rounds: {
|
|
167
|
+
type: "number",
|
|
168
|
+
description: "Number of deliberation rounds (default: 2)"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
required: ["question"]
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
async function handleEstimateCost(client, args) {
|
|
175
|
+
const estimate = await client.estimateCost(args);
|
|
176
|
+
const breakdownRows = estimate.breakdown.map(
|
|
177
|
+
(b) => ` \u2022 ${b.model} (${b.role}): ~${b.estimated_tokens.toLocaleString()} tokens = ${b.estimated_credits} credits`
|
|
178
|
+
).join("\n");
|
|
179
|
+
return {
|
|
180
|
+
content: [
|
|
181
|
+
{
|
|
182
|
+
type: "text",
|
|
183
|
+
text: [
|
|
184
|
+
`Cost estimate for "${args.question}"`,
|
|
185
|
+
``,
|
|
186
|
+
`Total: ${estimate.estimated_credits} credits (~$${estimate.estimated_usd.toFixed(2)} USD)`,
|
|
187
|
+
``,
|
|
188
|
+
`Breakdown:`,
|
|
189
|
+
breakdownRows,
|
|
190
|
+
``,
|
|
191
|
+
`Credits refill automatically on Pro plans. View balance at https://console.debatetalk.ai`
|
|
192
|
+
].join("\n")
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/mcp/tools/get_history.ts
|
|
199
|
+
var getHistoryTool = {
|
|
200
|
+
name: "get_history",
|
|
201
|
+
description: "Retrieve your past DebateTalk debates. Returns debate titles, dates, model counts, and share links. Requires an API key (Pro or Enterprise plan).",
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: "object",
|
|
204
|
+
properties: {
|
|
205
|
+
limit: {
|
|
206
|
+
type: "number",
|
|
207
|
+
description: "Number of debates to return (default: 20, max: 100)"
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
async function handleGetHistory(client, args) {
|
|
213
|
+
const limit = args.limit ?? 20;
|
|
214
|
+
const { debates, total } = await client.getHistory(limit);
|
|
215
|
+
if (debates.length === 0) {
|
|
216
|
+
return {
|
|
217
|
+
content: [
|
|
218
|
+
{
|
|
219
|
+
type: "text",
|
|
220
|
+
text: "No debates found. Run your first debate at https://console.debatetalk.ai"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const rows = debates.map((d) => {
|
|
226
|
+
const date = new Date(d.created_at).toLocaleDateString("en-US", {
|
|
227
|
+
year: "numeric",
|
|
228
|
+
month: "short",
|
|
229
|
+
day: "numeric"
|
|
230
|
+
});
|
|
231
|
+
const shareLink = d.share_token ? ` \u2014 https://console.debatetalk.ai/share/${d.share_token}` : "";
|
|
232
|
+
return `\u2022 [${date}] ${d.title} (${d.model_count} models, ${d.status})${shareLink}`;
|
|
233
|
+
});
|
|
234
|
+
return {
|
|
235
|
+
content: [
|
|
236
|
+
{
|
|
237
|
+
type: "text",
|
|
238
|
+
text: [
|
|
239
|
+
`Debate history \u2014 showing ${debates.length} of ${total}`,
|
|
240
|
+
``,
|
|
241
|
+
...rows
|
|
242
|
+
].join("\n")
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/mcp/server.ts
|
|
249
|
+
var ALL_TOOLS = [
|
|
250
|
+
runDebateTool,
|
|
251
|
+
getModelStatusTool,
|
|
252
|
+
recommendModelsTool,
|
|
253
|
+
estimateCostTool,
|
|
254
|
+
getHistoryTool
|
|
255
|
+
];
|
|
256
|
+
function createServer(client) {
|
|
257
|
+
const server = new Server(
|
|
258
|
+
{ name: "debatetalk", version: "1.0.0" },
|
|
259
|
+
{ capabilities: { tools: {} } }
|
|
260
|
+
);
|
|
261
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
262
|
+
tools: ALL_TOOLS
|
|
263
|
+
}));
|
|
264
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
265
|
+
const { name, arguments: args = {} } = request.params;
|
|
266
|
+
switch (name) {
|
|
267
|
+
case "run_debate":
|
|
268
|
+
return handleRunDebate(client, args);
|
|
269
|
+
case "get_model_status":
|
|
270
|
+
return handleGetModelStatus(client);
|
|
271
|
+
case "recommend_models":
|
|
272
|
+
return handleRecommendModels(client, args);
|
|
273
|
+
case "estimate_cost":
|
|
274
|
+
return handleEstimateCost(client, args);
|
|
275
|
+
case "get_history":
|
|
276
|
+
return handleGetHistory(client, args);
|
|
277
|
+
default:
|
|
278
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
return server;
|
|
282
|
+
}
|
|
283
|
+
async function main() {
|
|
284
|
+
const client = new DebateTalkClient();
|
|
285
|
+
const server = createServer(client);
|
|
286
|
+
const transport = new StdioServerTransport();
|
|
287
|
+
await server.connect(transport);
|
|
288
|
+
}
|
|
289
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
290
|
+
main().catch((err) => {
|
|
291
|
+
process.stderr.write(
|
|
292
|
+
`DebateTalk MCP server error: ${err instanceof Error ? err.message : String(err)}
|
|
293
|
+
`
|
|
294
|
+
);
|
|
295
|
+
process.exit(1);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
export {
|
|
299
|
+
ALL_TOOLS
|
|
300
|
+
};
|
|
301
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/server.ts","../../src/mcp/tools/run_debate.ts","../../src/mcp/tools/get_model_status.ts","../../src/mcp/tools/recommend_models.ts","../../src/mcp/tools/estimate_cost.ts","../../src/mcp/tools/get_history.ts"],"sourcesContent":["// Server is the low-level class needed for JSON Schema tool definitions.\n// McpServer (the replacement) requires Zod schemas — not compatible with our Tool[] approach.\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { DebateTalkClient } from \"../client.js\";\nimport { runDebateTool, handleRunDebate } from \"./tools/run_debate.js\";\nimport { getModelStatusTool, handleGetModelStatus } from \"./tools/get_model_status.js\";\nimport { recommendModelsTool, handleRecommendModels } from \"./tools/recommend_models.js\";\nimport { estimateCostTool, handleEstimateCost } from \"./tools/estimate_cost.js\";\nimport { getHistoryTool, handleGetHistory } from \"./tools/get_history.js\";\n\nexport const ALL_TOOLS = [\n runDebateTool,\n getModelStatusTool,\n recommendModelsTool,\n estimateCostTool,\n getHistoryTool,\n];\n\nfunction createServer(client: DebateTalkClient): Server {\n const server = new Server(\n { name: \"debatetalk\", version: \"1.0.0\" },\n { capabilities: { tools: {} } }\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: ALL_TOOLS,\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n switch (name) {\n case \"run_debate\":\n return handleRunDebate(client, args as Parameters<typeof handleRunDebate>[1]);\n case \"get_model_status\":\n return handleGetModelStatus(client);\n case \"recommend_models\":\n return handleRecommendModels(client, args as Parameters<typeof handleRecommendModels>[1]);\n case \"estimate_cost\":\n return handleEstimateCost(client, args as Parameters<typeof handleEstimateCost>[1]);\n case \"get_history\":\n return handleGetHistory(client, args as Parameters<typeof handleGetHistory>[1]);\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n });\n\n return server;\n}\n\nasync function main() {\n const client = new DebateTalkClient();\n const server = createServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n// Only start the server when run directly, not when imported in tests\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((err: unknown) => {\n process.stderr.write(\n `DebateTalk MCP server error: ${err instanceof Error ? err.message : String(err)}\\n`\n );\n process.exit(1);\n });\n}\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { DebateTalkClient } from \"../../client.js\";\n\nexport const runDebateTool: Tool = {\n name: \"run_debate\",\n description:\n \"Run a structured multi-model AI debate on any question. \" +\n \"Multiple AI models argue independently in a blind round, deliberate, and converge on a 4-part synthesis: \" +\n \"Strong Ground (what all models agree on), Fault Lines (genuine disagreements), \" +\n \"Blind Spots (what all models missed), and Your Call (actionable recommendation). \" +\n \"Requires an API key (Pro or Enterprise plan). Free tier: 5 debates/day.\",\n inputSchema: {\n type: \"object\",\n properties: {\n question: {\n type: \"string\",\n description:\n \"The question or topic to debate. Can be a decision, prediction, factual question, or open-ended topic.\",\n },\n models: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Specific model IDs to use as debaters (e.g. [\\\"claude-opus-4-6\\\", \\\"gpt-5.4\\\"]). \" +\n \"Omit to let DebateTalk smart routing pick the best panel automatically.\",\n },\n rounds: {\n type: \"number\",\n description: \"Number of deliberation rounds (default: 2, max depends on plan)\",\n },\n },\n required: [\"question\"],\n },\n};\n\nexport async function handleRunDebate(\n client: DebateTalkClient,\n args: { question: string; models?: string[]; rounds?: number }\n) {\n const result = await client.runDebate(args);\n\n if (!result.synthesis) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `debate completed — ${result.debate_id} — but synthesis was not produced. Check your plan limits at https://console.debatetalk.ai`,\n },\n ],\n };\n }\n\n const { strong_ground, fault_lines, blind_spots, your_call } =\n result.synthesis;\n\n const modelList =\n result.models.length > 0 ? result.models.join(\", \") : \"smart routing\";\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `DebateTalk — ${result.question_type} question`,\n `Question: \"${result.question}\"`,\n `Models: ${modelList}`,\n `Debate ID: ${result.debate_id}`,\n ``,\n `━━━ Strong Ground ━━━`,\n `What all models agreed on:`,\n strong_ground,\n ``,\n `━━━ Fault Lines ━━━`,\n `Where models genuinely disagreed:`,\n fault_lines,\n ``,\n `━━━ Blind Spots ━━━`,\n `What all models missed:`,\n blind_spots,\n ``,\n `━━━ Your Call ━━━`,\n your_call,\n ].join(\"\\n\"),\n },\n ],\n };\n}\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { DebateTalkClient } from \"../../client.js\";\n\nexport const getModelStatusTool: Tool = {\n name: \"get_model_status\",\n description:\n \"Get real-time health, latency, and uptime for all DebateTalk models. \" +\n \"Use this before running a debate to check which models are currently online. \" +\n \"No API key required.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n};\n\nexport async function handleGetModelStatus(client: DebateTalkClient) {\n const { models, updated_at } = await client.getModelStatus();\n\n const rows = models\n .map((m) => {\n const latency = m.latency_ms != null ? `${m.latency_ms}ms` : \"—\";\n const uptime =\n m.uptime_pct != null ? `${m.uptime_pct.toFixed(1)}%` : \"—\";\n const statusIcon =\n m.status === \"online\" ? \"✓\" : m.status === \"degraded\" ? \"⚠\" : \"✗\";\n return `${statusIcon} ${m.display_name} (${m.provider}) — ${m.status}, latency: ${latency}, uptime: ${uptime}`;\n })\n .join(\"\\n\");\n\n const online = models.filter((m) => m.status === \"online\").length;\n const total = models.length;\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Model Status — ${online}/${total} online (updated ${updated_at})\\n\\n${rows}`,\n },\n ],\n };\n}\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { DebateTalkClient } from \"../../client.js\";\n\nexport const recommendModelsTool: Tool = {\n name: \"recommend_models\",\n description:\n \"Get the best model panel recommended by DebateTalk smart routing for a specific question. \" +\n \"Returns the ideal debaters, synthesizer, and adjudicator based on the question type. \" +\n \"No API key required.\",\n inputSchema: {\n type: \"object\",\n properties: {\n question: {\n type: \"string\",\n description: \"The question or topic you want to debate\",\n },\n },\n required: [\"question\"],\n },\n};\n\nexport async function handleRecommendModels(\n client: DebateTalkClient,\n args: { question: string }\n) {\n const rec = await client.recommendModels(args.question);\n\n const debaterList = rec.debaters.join(\", \");\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Recommended panel for \"${args.question}\"`,\n `Question type: ${rec.question_type}`,\n ``,\n `Debaters: ${debaterList}`,\n `Synthesizer: ${rec.synthesizer}`,\n `Adjudicator: ${rec.adjudicator}`,\n ``,\n `To use this panel, run a debate with models: ${rec.debaters.join(\", \")}`,\n ].join(\"\\n\"),\n },\n ],\n };\n}\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { DebateTalkClient } from \"../../client.js\";\n\nexport const estimateCostTool: Tool = {\n name: \"estimate_cost\",\n description:\n \"Estimate the credit cost of a debate before running it. \" +\n \"Returns total credits, USD cost, and a per-model breakdown. \" +\n \"Requires an API key (Pro or Enterprise plan).\",\n inputSchema: {\n type: \"object\",\n properties: {\n question: {\n type: \"string\",\n description: \"The question to estimate cost for\",\n },\n models: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Specific model IDs to use (omit for smart routing)\",\n },\n rounds: {\n type: \"number\",\n description: \"Number of deliberation rounds (default: 2)\",\n },\n },\n required: [\"question\"],\n },\n};\n\nexport async function handleEstimateCost(\n client: DebateTalkClient,\n args: { question: string; models?: string[]; rounds?: number }\n) {\n const estimate = await client.estimateCost(args);\n\n const breakdownRows = estimate.breakdown\n .map(\n (b) =>\n ` • ${b.model} (${b.role}): ~${b.estimated_tokens.toLocaleString()} tokens = ${b.estimated_credits} credits`\n )\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Cost estimate for \"${args.question}\"`,\n ``,\n `Total: ${estimate.estimated_credits} credits (~$${estimate.estimated_usd.toFixed(2)} USD)`,\n ``,\n `Breakdown:`,\n breakdownRows,\n ``,\n `Credits refill automatically on Pro plans. View balance at https://console.debatetalk.ai`,\n ].join(\"\\n\"),\n },\n ],\n };\n}\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { DebateTalkClient } from \"../../client.js\";\n\nexport const getHistoryTool: Tool = {\n name: \"get_history\",\n description:\n \"Retrieve your past DebateTalk debates. \" +\n \"Returns debate titles, dates, model counts, and share links. \" +\n \"Requires an API key (Pro or Enterprise plan).\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: {\n type: \"number\",\n description: \"Number of debates to return (default: 20, max: 100)\",\n },\n },\n },\n};\n\nexport async function handleGetHistory(\n client: DebateTalkClient,\n args: { limit?: number }\n) {\n const limit = args.limit ?? 20;\n const { debates, total } = await client.getHistory(limit);\n\n if (debates.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No debates found. Run your first debate at https://console.debatetalk.ai\",\n },\n ],\n };\n }\n\n const rows = debates.map((d) => {\n const date = new Date(d.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n const shareLink = d.share_token\n ? ` — https://console.debatetalk.ai/share/${d.share_token}`\n : \"\";\n return `• [${date}] ${d.title} (${d.model_count} models, ${d.status})${shareLink}`;\n });\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Debate history — showing ${debates.length} of ${total}`,\n ``,\n ...rows,\n ].join(\"\\n\"),\n },\n ],\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@debatetalk/mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official MCP server and CLI for DebateTalk — run structured multi-model AI debates from your AI assistant or terminal.",
|
|
5
|
+
"keywords": ["mcp", "ai", "debate", "debatetalk", "claude", "llm"],
|
|
6
|
+
"homepage": "https://debatetalk.ai",
|
|
7
|
+
"bugs": "https://github.com/DebateTalk-AI/mcp/issues",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/DebateTalk-AI/mcp.git"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "DebateTalk <support@debatetalk.ai>",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/mcp/server.js",
|
|
16
|
+
"bin": {
|
|
17
|
+
"debatetalk": "./dist/cli/index.js",
|
|
18
|
+
"debatetalk-mcp": "./dist/mcp/server.js"
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev:mcp": "tsx src/mcp/server.ts",
|
|
24
|
+
"dev:cli": "tsx src/cli/index.ts",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
32
|
+
"chalk": "^5.3.0",
|
|
33
|
+
"commander": "^12.1.0",
|
|
34
|
+
"eventsource-parser": "^3.0.0",
|
|
35
|
+
"ora": "^8.1.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"tsup": "^8.3.0",
|
|
40
|
+
"tsx": "^4.19.0",
|
|
41
|
+
"typescript": "^5.7.0",
|
|
42
|
+
"vitest": "^2.1.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|