minutes-mcp 0.13.2 → 0.13.3

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/dist/index.d.ts CHANGED
@@ -32,4 +32,5 @@ export type KnowledgeConfigStatus = {
32
32
  adapter: string;
33
33
  engine: string;
34
34
  };
35
+ export declare function shouldRunMainEntry(argv1: string | null | undefined, moduleFilename: string): boolean;
35
36
  export declare function parseKnowledgeConfig(configContent: string): KnowledgeConfigStatus | null;
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, EXTENSION_ID,
37
37
  import { z } from "zod";
38
38
  import { execFile, spawn } from "child_process";
39
39
  import { promisify } from "util";
40
- import { existsSync } from "fs";
40
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, realpathSync } from "fs";
41
41
  import { mkdir, readFile, rm, writeFile } from "fs/promises";
42
42
  import { delimiter, dirname, join, resolve } from "path";
43
43
  import { fileURLToPath } from "url";
@@ -45,6 +45,73 @@ import { homedir } from "os";
45
45
  import * as reader from "minutes-sdk";
46
46
  import { canonicalizeRoot, expandHomeLikePath, validatePathInDirectories, validatePathInDirectory, } from "./paths.js";
47
47
  crashTrace("imports-complete");
48
+ // ── Demo mode (--demo flag) ────────────────────────────────
49
+ // `npx minutes-mcp --demo` is a one-shot setup: copies bundled fixture
50
+ // meetings to ~/.minutes/demo/, prints the MCP config snippet with an explicit
51
+ // MEETINGS_DIR env override, prints suggested questions, and exits 0.
52
+ //
53
+ // The printed config uses env:{ MEETINGS_DIR } pointing at the demo dir. No
54
+ // separate --demo flag at runtime. The MCP host just launches standard
55
+ // `minutes-mcp`; the env override is what routes it at the demo corpus. This
56
+ // avoids the TTY-detection ambiguity that an earlier dual-mode design had.
57
+ //
58
+ // Guarded on `--demo` AND on being the actual entry point so importers don't
59
+ // trigger disk side effects by mistake.
60
+ const IS_ENTRY_POINT = Boolean(process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url));
61
+ if (IS_ENTRY_POINT && process.argv.includes("--demo")) {
62
+ handleDemoSetup();
63
+ }
64
+ function handleDemoSetup() {
65
+ const demoDir = join(homedir(), ".minutes", "demo");
66
+ const here = dirname(fileURLToPath(import.meta.url));
67
+ // Package layout after build: dist/index.js; fixtures live at
68
+ // <pkg>/fixtures/demo/ next to dist/.
69
+ const fixturesSrc = resolve(here, "..", "fixtures", "demo");
70
+ if (!existsSync(fixturesSrc)) {
71
+ console.error(`[minutes-mcp --demo] bundled fixtures not found at ${fixturesSrc}. ` +
72
+ `This build of minutes-mcp is missing the demo corpus. ` +
73
+ `Try upgrading with: npm install -g minutes-mcp@latest`);
74
+ process.exit(1);
75
+ }
76
+ mkdirSync(demoDir, { recursive: true });
77
+ for (const entry of readdirSync(fixturesSrc)) {
78
+ if (!entry.endsWith(".md"))
79
+ continue;
80
+ copyFileSync(join(fixturesSrc, entry), join(demoDir, entry));
81
+ }
82
+ // The config snippet embeds the fully-resolved demoDir so users don't have
83
+ // to fill it in manually. MCP hosts inject this env when launching the
84
+ // server; the server's existing MEETINGS_DIR logic (line ~800) picks it up.
85
+ const configSnippet = JSON.stringify({
86
+ mcpServers: {
87
+ "minutes-demo": {
88
+ command: "npx",
89
+ args: ["minutes-mcp"],
90
+ env: {
91
+ MEETINGS_DIR: demoDir,
92
+ },
93
+ },
94
+ },
95
+ }, null, 2);
96
+ console.log("");
97
+ console.log("Demo corpus ready at: " + demoDir);
98
+ console.log("5 fixture meetings with a pricing reversal, a customer commitment that slips, and a feature cut.");
99
+ console.log("");
100
+ console.log("═══ MCP config (paste into Claude Desktop, Cursor, Claude Code, or any MCP client) ═══");
101
+ console.log(configSnippet);
102
+ console.log("");
103
+ console.log("═══ Try asking your agent ═══");
104
+ console.log(" • List the meetings in this corpus.");
105
+ console.log(" • What did we decide about pricing? Which decision is current?");
106
+ console.log(" • What got killed in the last product prioritization meeting?");
107
+ console.log(" • What action items are still open, and who owns each?");
108
+ console.log(" • Summarize the Northwind customer thread.");
109
+ console.log("");
110
+ console.log("Note: some structured tools (consistency report, person profile) auto-install the Minutes CLI on first use.");
111
+ console.log("Full setup (real audio capture, transcription, real meetings): https://useminutes.app");
112
+ console.log("");
113
+ process.exit(0);
114
+ }
48
115
  const UI_RESOURCE_URI = "ui://minutes/dashboard";
49
116
  const MCP_TOOLS_DOCS_BASE_URL = "https://useminutes.app/docs/mcp/tools";
50
117
  export const MEETING_INSIGHT_KINDS = ["decision", "commitment", "question"];
@@ -146,6 +213,22 @@ async function triggerQmdIndex() {
146
213
  // ESM-compatible __dirname
147
214
  const __filename = fileURLToPath(import.meta.url);
148
215
  const __dirname = dirname(__filename);
216
+ function canonicalEntrypointPath(filePath) {
217
+ if (!filePath)
218
+ return null;
219
+ const resolved = resolve(filePath);
220
+ try {
221
+ return realpathSync(resolved);
222
+ }
223
+ catch {
224
+ return resolved;
225
+ }
226
+ }
227
+ export function shouldRunMainEntry(argv1, moduleFilename) {
228
+ const entryPath = canonicalEntrypointPath(argv1);
229
+ const modulePath = canonicalEntrypointPath(moduleFilename);
230
+ return !!entryPath && !!modulePath && entryPath === modulePath;
231
+ }
149
232
  // ── Extension runtime detection ───────────────────────────────
150
233
  // When running as a Claude Desktop extension (.mcpb), Claude uses its built-in
151
234
  // Node.js runtime. Child processes spawned from that runtime land in a
@@ -199,7 +282,7 @@ function findMinutesBinary() {
199
282
  }
200
283
  let MINUTES_BIN = findMinutesBinary();
201
284
  // ── Expected CLI version (must match this MCP server release) ──
202
- const MCP_SERVER_VERSION = "0.13.2";
285
+ const MCP_SERVER_VERSION = "0.13.3";
203
286
  const EXPECTED_CLI_VERSION = MCP_SERVER_VERSION;
204
287
  export function parseKnowledgeConfig(configContent) {
205
288
  const knowledgeMatch = configContent.match(/\[knowledge\][\s\S]*?(?=\n\[|$)/);
@@ -2134,9 +2217,9 @@ crashTrace("pre-main-guard", {
2134
2217
  argv1: process.argv[1] ?? null,
2135
2218
  resolvedArgv1: process.argv[1] ? resolve(process.argv[1]) : null,
2136
2219
  __filename,
2137
- match: process.argv[1] ? resolve(process.argv[1]) === __filename : false,
2220
+ match: shouldRunMainEntry(process.argv[1], __filename),
2138
2221
  });
2139
- if (process.argv[1] && resolve(process.argv[1]) === __filename) {
2222
+ if (shouldRunMainEntry(process.argv[1], __filename)) {
2140
2223
  main().catch((error) => {
2141
2224
  crashTrace("main-rejected", error);
2142
2225
  console.error("Fatal error:", error);
@@ -0,0 +1,47 @@
1
+ ---
2
+ title: Pricing Strategy — Monthly Billing Test
3
+ type: meeting
4
+ minutes_demo: true
5
+ date: 2026-02-28T10:00:00-07:00
6
+ duration: 48m
7
+ attendees: [Mat S., Alex K., Jordan M.]
8
+ people: [mat, alex, jordan]
9
+ tags: [pricing, gtm, experiment]
10
+ decisions:
11
+ - text: Launch monthly billing alongside annual, starting with the next three consultant signups
12
+ topic: pricing
13
+ authority: high
14
+ action_items:
15
+ - assignee: jordan
16
+ task: Draft monthly billing landing copy
17
+ due: 2026-03-07
18
+ status: open
19
+ - assignee: alex
20
+ task: Wire monthly price into Stripe
21
+ due: 2026-03-10
22
+ status: open
23
+ speaker_map:
24
+ - speaker_label: SPEAKER_0
25
+ name: mat
26
+ confidence: high
27
+ source: manual
28
+ - speaker_label: SPEAKER_1
29
+ name: alex
30
+ confidence: high
31
+ source: manual
32
+ - speaker_label: SPEAKER_2
33
+ name: jordan
34
+ confidence: high
35
+ source: manual
36
+ ---
37
+
38
+ ## Summary
39
+
40
+ - Seven consultants pushed back on annual this month. Testing monthly for the segment.
41
+ - Decision: monthly billing for the next three consultant signups. Annual stays default for enterprise.
42
+
43
+ ## Transcript
44
+
45
+ [SPEAKER_0 0:00] Let's talk pricing. Seven consultants this month pushed back on annual.
46
+ [SPEAKER_1 0:31] Monthly kills payback. Breakeven moves from 11 months to 14.
47
+ [SPEAKER_0 1:02] Run it narrow. Next three consultant signups get monthly. Annual stays default for enterprise. Reassess Q2.
@@ -0,0 +1,43 @@
1
+ ---
2
+ title: Northwind Customer Call — SSO Friction
3
+ type: meeting
4
+ minutes_demo: true
5
+ date: 2026-03-04T15:30:00-07:00
6
+ duration: 31m
7
+ attendees: [Mat S., Riley B.]
8
+ people: [mat, riley]
9
+ tags: [customer, northwind, onboarding, retention]
10
+ decisions:
11
+ - text: Ship SSO nested-groups fix for Northwind-shaped accounts before end of Q1 (2026-03-31)
12
+ topic: sso
13
+ authority: high
14
+ action_items:
15
+ - assignee: mat
16
+ task: Fix SSO nested-groups onboarding for Northwind
17
+ due: 2026-03-31
18
+ status: open
19
+ promised_to: riley
20
+ speaker_map:
21
+ - speaker_label: SPEAKER_0
22
+ name: mat
23
+ confidence: high
24
+ source: manual
25
+ - speaker_label: SPEAKER_1
26
+ name: riley
27
+ confidence: high
28
+ source: manual
29
+ ---
30
+
31
+ ## Summary
32
+
33
+ - Riley (Northwind, Director of Ops) frustrated. SSO nested-groups failing for their Okta setup.
34
+ - Mat personally committed to ship the fix before 2026-03-31.
35
+ - Riley used the word "churn" twice unprompted.
36
+
37
+ ## Transcript
38
+
39
+ [SPEAKER_1 0:00] Half of our eighteen people bounced at SSO this month. I can't keep selling this.
40
+ [SPEAKER_0 0:22] What's the failure point?
41
+ [SPEAKER_1 0:29] Okta nested groups. Your product expects flat users.
42
+ [SPEAKER_0 0:49] End of the quarter. March 31. That's a personal commitment from me.
43
+ [SPEAKER_1 1:02] If it slips, we're going to have a different conversation in Q2.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: Eng Standup — Alex Takes SSO
3
+ type: meeting
4
+ minutes_demo: true
5
+ date: 2026-03-11T09:30:00-07:00
6
+ duration: 22m
7
+ attendees: [Mat S., Alex K., Sam W.]
8
+ people: [mat, alex, sam]
9
+ tags: [engineering, sso, standup]
10
+ decisions:
11
+ - text: Alex owns SSO nested-groups support, targeting ship by 2026-03-25
12
+ topic: sso
13
+ authority: high
14
+ action_items:
15
+ - assignee: alex
16
+ task: Ship SSO nested-groups support
17
+ due: 2026-03-25
18
+ status: open
19
+ speaker_map:
20
+ - speaker_label: SPEAKER_0
21
+ name: mat
22
+ confidence: high
23
+ source: manual
24
+ - speaker_label: SPEAKER_1
25
+ name: alex
26
+ confidence: high
27
+ source: manual
28
+ ---
29
+
30
+ ## Summary
31
+
32
+ - Alex took SSO nested-groups. Target ship 2026-03-25, buffer before the Northwind-promised 2026-03-31.
33
+
34
+ ## Transcript
35
+
36
+ [SPEAKER_0 0:00] I need status on SSO nested groups. Committed to Riley, March 31.
37
+ [SPEAKER_1 0:11] I can take it. Week of work. Target March 25, gives a week of slack.
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: Pricing Follow-up — Reverse the Monthly Experiment
3
+ type: meeting
4
+ minutes_demo: true
5
+ date: 2026-03-25T10:00:00-07:00
6
+ duration: 34m
7
+ attendees: [Mat S., Alex K., Jordan M.]
8
+ people: [mat, alex, jordan]
9
+ tags: [pricing, gtm, decision-reversal]
10
+ decisions:
11
+ - text: Revert to annual-only billing across all segments. Monthly billing experiment did not generate enough signups to justify the payback hit.
12
+ topic: pricing
13
+ authority: high
14
+ supersedes: "2026-02-28 monthly billing decision"
15
+ action_items:
16
+ - assignee: jordan
17
+ task: Pull monthly billing from the landing page
18
+ due: 2026-03-27
19
+ status: open
20
+ speaker_map:
21
+ - speaker_label: SPEAKER_0
22
+ name: mat
23
+ confidence: high
24
+ source: manual
25
+ - speaker_label: SPEAKER_1
26
+ name: alex
27
+ confidence: high
28
+ source: manual
29
+ - speaker_label: SPEAKER_2
30
+ name: jordan
31
+ confidence: high
32
+ source: manual
33
+ ---
34
+
35
+ ## Summary
36
+
37
+ - Four monthly signups in three weeks, below the 12 threshold. Churn on the four tracking worse than baseline.
38
+ - Decision: revert to annual-only. Explicitly supersedes the 2026-02-28 launch decision.
39
+
40
+ ## Transcript
41
+
42
+ [SPEAKER_2 0:00] Four monthly signups in three weeks. The threshold was twelve.
43
+ [SPEAKER_1 0:14] Churn on the four is worse than annual baseline. Two of four canceled before month two.
44
+ [SPEAKER_0 0:47] To be clear: we are reversing the 2026-02-28 decision. Going annual-only, effective immediately.
@@ -0,0 +1,52 @@
1
+ ---
2
+ title: Product Prioritization — Q2 Cut Lines
3
+ type: meeting
4
+ minutes_demo: true
5
+ date: 2026-04-17T13:00:00-07:00
6
+ duration: 58m
7
+ attendees: [Mat S., Alex K., Sam W., Jordan M.]
8
+ people: [mat, alex, sam, jordan]
9
+ tags: [product, prioritization, q2, roadmap]
10
+ decisions:
11
+ - text: Kill the advanced analytics feature. It was on the Q2 roadmap; it is no longer.
12
+ topic: advanced-analytics
13
+ authority: high
14
+ - text: Keep team billing as the primary Q2 engineering investment
15
+ topic: team-billing
16
+ authority: high
17
+ - text: Ship a scoped reporting-exports fix in Q2. Date-ranged CSV export, no dashboard, no visualizations.
18
+ topic: reporting-exports
19
+ authority: high
20
+ action_items:
21
+ - assignee: sam
22
+ task: Remove advanced analytics mockups from the product roadmap page
23
+ due: 2026-04-18
24
+ status: open
25
+ - assignee: alex
26
+ task: Ship scoped reporting-exports (date-ranged CSV) by 2026-05-02
27
+ due: 2026-05-02
28
+ status: open
29
+ speaker_map:
30
+ - speaker_label: SPEAKER_0
31
+ name: mat
32
+ confidence: high
33
+ source: manual
34
+ - speaker_label: SPEAKER_1
35
+ name: alex
36
+ confidence: high
37
+ source: manual
38
+ ---
39
+
40
+ ## Summary
41
+
42
+ - Advanced analytics cut from Q2 roadmap.
43
+ - Team billing stays as primary Q2 investment.
44
+ - Reporting exports get a scoped green-light: date-ranged CSV only, two weeks of engineering, ship 2026-05-02.
45
+
46
+ ## Transcript
47
+
48
+ [SPEAKER_0 0:00] Three things on the table. Advanced analytics, team billing, reporting exports.
49
+ [SPEAKER_1 0:08] Kill analytics. No customer pulling for it.
50
+ [SPEAKER_0 0:34] Killed. Team billing stays, on track for April 15. Reporting exports scoped: date-ranged CSV, no dashboard.
51
+ [SPEAKER_1 1:02] Two weeks if it's literally date filter + CSV.
52
+ [SPEAKER_0 1:14] Scope locked. Ship by May 2.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minutes-mcp",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "MCP server for minutes — conversation memory for AI assistants. Works with Claude Desktop, Mistral Vibe, Cursor, Windsurf, and any MCP client.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -10,6 +10,7 @@
10
10
  "files": [
11
11
  "dist/",
12
12
  "dist-ui/",
13
+ "fixtures/",
13
14
  "LICENSE"
14
15
  ],
15
16
  "keywords": [
@@ -40,7 +41,7 @@
40
41
  "dependencies": {
41
42
  "@modelcontextprotocol/ext-apps": "^1.6.0",
42
43
  "@modelcontextprotocol/sdk": "^1.29.0",
43
- "minutes-sdk": "^0.13.1",
44
+ "minutes-sdk": "^0.13.3",
44
45
  "yaml": "^2.8.3",
45
46
  "zod": "^3.25 || ^4.0"
46
47
  },