harmonica-mcp 0.2.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 ADDED
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harmonica
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # Harmonica MCP Server
2
+
3
+ MCP server enabling AI agents to create and query [Harmonica](https://harmonica.chat) deliberation sessions.
4
+
5
+ [Harmonica](https://harmonica.chat) is a structured deliberation platform where groups coordinate through AI-facilitated async conversations. Create a session with a topic and goal, share a link with participants, and each person has a private 1:1 conversation with an AI facilitator. Responses are synthesized into actionable insights.
6
+
7
+ ## Quick Start
8
+
9
+ ### npx (no install)
10
+
11
+ ```json
12
+ {
13
+ "mcpServers": {
14
+ "harmonica": {
15
+ "command": "npx",
16
+ "args": ["-y", "harmonica-mcp"],
17
+ "env": {
18
+ "HARMONICA_API_KEY": "hm_live_your_key_here"
19
+ }
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ ### From source
26
+
27
+ ```bash
28
+ git clone https://github.com/harmonicabot/harmonica-mcp.git
29
+ cd harmonica-mcp
30
+ npm install && npm run build
31
+ ```
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "harmonica": {
37
+ "command": "node",
38
+ "args": ["/path/to/harmonica-mcp/dist/index.js"],
39
+ "env": {
40
+ "HARMONICA_API_KEY": "hm_live_your_key_here"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ### Get an API key
48
+
49
+ 1. [Sign up for Harmonica](https://app.harmonica.chat) (free)
50
+ 2. Go to [Profile](https://app.harmonica.chat/profile) > **API Keys** > **Generate API Key**
51
+ 3. Copy your `hm_live_...` key — it's only shown once
52
+
53
+ ## Tools
54
+
55
+ | Tool | Description |
56
+ |------|-------------|
57
+ | `create_session` | Create a new deliberation session and get a shareable join URL |
58
+ | `list_sessions` | List your deliberation sessions (filter by status, search) |
59
+ | `get_session` | Get full session details |
60
+ | `get_responses` | Get participant responses |
61
+ | `get_summary` | Get AI-generated summary |
62
+ | `search_sessions` | Search by topic or goal |
63
+
64
+ ## Environment Variables
65
+
66
+ | Variable | Required | Default | Description |
67
+ |----------|----------|---------|-------------|
68
+ | `HARMONICA_API_KEY` | Yes | — | Your Harmonica API key |
69
+ | `HARMONICA_API_URL` | No | `https://app.harmonica.chat` | API base URL |
70
+
71
+ ## License
72
+
73
+ MIT
@@ -0,0 +1,99 @@
1
+ /**
2
+ * HTTP client for the Harmonica REST API v1.
3
+ * All methods throw on HTTP errors.
4
+ */
5
+ export interface HarmonicaClientConfig {
6
+ baseUrl: string;
7
+ apiKey: string;
8
+ }
9
+ export declare class HarmonicaClient {
10
+ private baseUrl;
11
+ private apiKey;
12
+ constructor(config: HarmonicaClientConfig);
13
+ private request;
14
+ getMe(): Promise<{
15
+ id: string;
16
+ email: string;
17
+ name: string | null;
18
+ subscription_status: string;
19
+ }>;
20
+ listSessions(params?: {
21
+ status?: 'active' | 'completed';
22
+ q?: string;
23
+ limit?: number;
24
+ offset?: number;
25
+ }): Promise<{
26
+ data: Array<{
27
+ id: string;
28
+ topic: string;
29
+ goal: string;
30
+ status: string;
31
+ participant_count: number;
32
+ created_at: string;
33
+ updated_at: string;
34
+ }>;
35
+ pagination: {
36
+ total: number;
37
+ limit: number;
38
+ offset: number;
39
+ };
40
+ }>;
41
+ getSession(id: string): Promise<{
42
+ id: string;
43
+ topic: string;
44
+ goal: string;
45
+ critical: string | null;
46
+ context: string | null;
47
+ status: string;
48
+ summary: string | null;
49
+ participant_count: number;
50
+ created_at: string;
51
+ updated_at: string;
52
+ }>;
53
+ getSessionQuestions(sessionId: string): Promise<{
54
+ data: Array<{
55
+ id: string;
56
+ text: string;
57
+ position: number;
58
+ }>;
59
+ }>;
60
+ getSessionResponses(sessionId: string): Promise<{
61
+ data: Array<{
62
+ participant_name: string | null;
63
+ messages: Array<{
64
+ role: "user" | "assistant";
65
+ content: string;
66
+ created_at: string;
67
+ }>;
68
+ }>;
69
+ }>;
70
+ submitResponse(sessionId: string, content: string): Promise<{
71
+ id: string;
72
+ session_id: string;
73
+ content: string;
74
+ created_at: string;
75
+ }>;
76
+ createSession(params: {
77
+ topic: string;
78
+ goal: string;
79
+ context?: string;
80
+ critical?: string;
81
+ prompt?: string;
82
+ template_id?: string;
83
+ cross_pollination?: boolean;
84
+ }): Promise<{
85
+ id: string;
86
+ topic: string;
87
+ goal: string;
88
+ status: string;
89
+ participant_count: number;
90
+ created_at: string;
91
+ updated_at: string;
92
+ join_url: string;
93
+ }>;
94
+ getSessionSummary(sessionId: string): Promise<{
95
+ session_id: string;
96
+ summary: string | null;
97
+ generated_at: string | null;
98
+ }>;
99
+ }
package/dist/client.js ADDED
@@ -0,0 +1,70 @@
1
+ /**
2
+ * HTTP client for the Harmonica REST API v1.
3
+ * All methods throw on HTTP errors.
4
+ */
5
+ export class HarmonicaClient {
6
+ baseUrl;
7
+ apiKey;
8
+ constructor(config) {
9
+ this.baseUrl = config.baseUrl.replace(/\/+$/, '');
10
+ this.apiKey = config.apiKey;
11
+ }
12
+ async request(path, options) {
13
+ const url = `${this.baseUrl}/api/v1${path}`;
14
+ const res = await fetch(url, {
15
+ ...options,
16
+ headers: {
17
+ 'Authorization': `Bearer ${this.apiKey}`,
18
+ 'Content-Type': 'application/json',
19
+ ...options?.headers,
20
+ },
21
+ });
22
+ if (!res.ok) {
23
+ const body = await res.json().catch(() => ({}));
24
+ const message = body?.error?.message || `HTTP ${res.status}`;
25
+ throw new Error(`Harmonica API error: ${message}`);
26
+ }
27
+ return res.json();
28
+ }
29
+ async getMe() {
30
+ return this.request('/me');
31
+ }
32
+ async listSessions(params) {
33
+ const query = new URLSearchParams();
34
+ if (params?.status)
35
+ query.set('status', params.status);
36
+ if (params?.q)
37
+ query.set('q', params.q);
38
+ if (params?.limit)
39
+ query.set('limit', String(params.limit));
40
+ if (params?.offset)
41
+ query.set('offset', String(params.offset));
42
+ const qs = query.toString();
43
+ return this.request(`/sessions${qs ? `?${qs}` : ''}`);
44
+ }
45
+ async getSession(id) {
46
+ return this.request(`/sessions/${id}`);
47
+ }
48
+ async getSessionQuestions(sessionId) {
49
+ return this.request(`/sessions/${sessionId}/questions`);
50
+ }
51
+ async getSessionResponses(sessionId) {
52
+ return this.request(`/sessions/${sessionId}/responses`);
53
+ }
54
+ async submitResponse(sessionId, content) {
55
+ return this.request(`/sessions/${sessionId}/responses`, {
56
+ method: 'POST',
57
+ body: JSON.stringify({ content }),
58
+ });
59
+ }
60
+ async createSession(params) {
61
+ return this.request('/sessions', {
62
+ method: 'POST',
63
+ body: JSON.stringify(params),
64
+ });
65
+ }
66
+ async getSessionSummary(sessionId) {
67
+ return this.request(`/sessions/${sessionId}/summary`);
68
+ }
69
+ }
70
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,127 @@
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 { HarmonicaClient } from './client.js';
6
+ const HARMONICA_API_URL = process.env.HARMONICA_API_URL || 'https://app.harmonica.chat';
7
+ const HARMONICA_API_KEY = process.env.HARMONICA_API_KEY;
8
+ if (!HARMONICA_API_KEY) {
9
+ console.error('Error: HARMONICA_API_KEY environment variable is required.');
10
+ console.error('Generate one at https://app.harmonica.chat (Profile → API Keys)');
11
+ process.exit(1);
12
+ }
13
+ const client = new HarmonicaClient({
14
+ baseUrl: HARMONICA_API_URL,
15
+ apiKey: HARMONICA_API_KEY,
16
+ });
17
+ const server = new McpServer({
18
+ name: 'harmonica',
19
+ version: '0.1.0',
20
+ });
21
+ // ─── Tools ───────────────────────────────────────────────────────────
22
+ server.tool('list_sessions', 'List Harmonica deliberation sessions you have access to', {
23
+ status: z.enum(['active', 'completed']).optional().describe('Filter by status'),
24
+ query: z.string().optional().describe('Search by topic or goal'),
25
+ limit: z.number().min(1).max(100).optional().describe('Results per page (default 20)'),
26
+ }, async ({ status, query, limit }) => {
27
+ const result = await client.listSessions({ status, q: query, limit });
28
+ const lines = result.data.map((s) => `[${s.status}] ${s.topic} (${s.participant_count} participants) — ${s.id}`);
29
+ const text = lines.length
30
+ ? `${result.pagination.total} sessions found:\n\n${lines.join('\n')}`
31
+ : 'No sessions found.';
32
+ return { content: [{ type: 'text', text }] };
33
+ });
34
+ server.tool('get_session', 'Get details of a specific Harmonica session', {
35
+ session_id: z.string().describe('Session ID (UUID)'),
36
+ }, async ({ session_id }) => {
37
+ const s = await client.getSession(session_id);
38
+ const text = [
39
+ `**${s.topic}**`,
40
+ `Status: ${s.status} | Participants: ${s.participant_count}`,
41
+ `Goal: ${s.goal}`,
42
+ s.critical ? `Critical: ${s.critical}` : null,
43
+ s.context ? `Context: ${s.context}` : null,
44
+ s.summary ? `\nSummary:\n${s.summary}` : null,
45
+ `\nCreated: ${s.created_at}`,
46
+ ]
47
+ .filter(Boolean)
48
+ .join('\n');
49
+ return { content: [{ type: 'text', text }] };
50
+ });
51
+ server.tool('get_responses', 'Get participant responses for a Harmonica session', {
52
+ session_id: z.string().describe('Session ID (UUID)'),
53
+ }, async ({ session_id }) => {
54
+ const result = await client.getSessionResponses(session_id);
55
+ if (!result.data.length) {
56
+ return { content: [{ type: 'text', text: 'No responses yet.' }] };
57
+ }
58
+ const sections = result.data.map((p) => {
59
+ const name = p.participant_name || 'Anonymous';
60
+ const msgs = p.messages
61
+ .filter((m) => m.role === 'user')
62
+ .map((m) => ` > ${m.content}`)
63
+ .join('\n');
64
+ return `**${name}:**\n${msgs || ' (no responses)'}`;
65
+ });
66
+ return { content: [{ type: 'text', text: sections.join('\n\n') }] };
67
+ });
68
+ server.tool('get_summary', 'Get the AI-generated summary for a Harmonica session', {
69
+ session_id: z.string().describe('Session ID (UUID)'),
70
+ }, async ({ session_id }) => {
71
+ const result = await client.getSessionSummary(session_id);
72
+ const text = result.summary || 'No summary available yet (session may still be active).';
73
+ return { content: [{ type: 'text', text }] };
74
+ });
75
+ server.tool('search_sessions', 'Search Harmonica sessions by topic or goal keywords', {
76
+ query: z.string().describe('Search keywords'),
77
+ status: z.enum(['active', 'completed']).optional().describe('Filter by status'),
78
+ }, async ({ query, status }) => {
79
+ const result = await client.listSessions({ q: query, status, limit: 20 });
80
+ if (!result.data.length) {
81
+ return { content: [{ type: 'text', text: `No sessions match "${query}".` }] };
82
+ }
83
+ const lines = result.data.map((s) => `- [${s.status}] **${s.topic}** — ${s.goal}\n ID: ${s.id}`);
84
+ return {
85
+ content: [{ type: 'text', text: `Found ${result.pagination.total} sessions:\n\n${lines.join('\n')}` }],
86
+ };
87
+ });
88
+ server.tool('create_session', 'Create a new Harmonica deliberation session and get a shareable join URL', {
89
+ topic: z.string().describe('Session topic'),
90
+ goal: z.string().describe('What this session aims to achieve'),
91
+ context: z.string().optional().describe('Background context for participants'),
92
+ critical: z.string().optional().describe('Critical question or constraint'),
93
+ prompt: z.string().optional().describe('Custom facilitation prompt'),
94
+ template_id: z.string().optional().describe('Template ID to use'),
95
+ cross_pollination: z.boolean().optional().describe('Enable idea sharing between participant threads'),
96
+ }, async ({ topic, goal, context, critical, prompt, template_id, cross_pollination }) => {
97
+ const session = await client.createSession({
98
+ topic,
99
+ goal,
100
+ context,
101
+ critical,
102
+ prompt,
103
+ template_id,
104
+ cross_pollination,
105
+ });
106
+ const text = [
107
+ `Session created!`,
108
+ ``,
109
+ ` Topic: ${session.topic}`,
110
+ ` ID: ${session.id}`,
111
+ ` Status: ${session.status}`,
112
+ ` Join URL: ${session.join_url}`,
113
+ ``,
114
+ `Share the join URL with participants to start the session.`,
115
+ ].join('\n');
116
+ return { content: [{ type: 'text', text }] };
117
+ });
118
+ // ─── Start ───────────────────────────────────────────────────────────
119
+ async function main() {
120
+ const transport = new StdioServerTransport();
121
+ await server.connect(transport);
122
+ }
123
+ main().catch((error) => {
124
+ console.error('Fatal error:', error);
125
+ process.exit(1);
126
+ });
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "harmonica-mcp",
3
+ "version": "0.2.0",
4
+ "description": "MCP server for Harmonica deliberation sessions",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "harmonica-mcp": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepublishOnly": "npm run build",
17
+ "start": "node dist/index.js",
18
+ "dev": "tsc --watch"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "harmonica",
23
+ "deliberation",
24
+ "facilitation",
25
+ "model-context-protocol"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/harmonicabot/harmonica-mcp.git"
30
+ },
31
+ "homepage": "https://github.com/harmonicabot/harmonica-mcp#readme",
32
+ "dependencies": {
33
+ "@modelcontextprotocol/sdk": "^1.12.0",
34
+ "zod": "^3.24.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^20.11.0",
38
+ "typescript": "^5.5.0"
39
+ }
40
+ }