@usewhisper/mcp-server 2.0.0 → 2.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/README.md +16 -0
- package/dist/server.js +164 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,6 +158,12 @@ Print config to stdout:
|
|
|
158
158
|
whisper-context-mcp scope --project my-project --source github --client claude
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
OpenCode project config generation:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
whisper-context-mcp scope --project my-project --source github --client opencode
|
|
165
|
+
```
|
|
166
|
+
|
|
161
167
|
Write the generated config to a file:
|
|
162
168
|
|
|
163
169
|
```text
|
|
@@ -211,6 +217,16 @@ Flow:
|
|
|
211
217
|
1. Run wizard and complete auth/project setup.
|
|
212
218
|
2. Add a source with MCP: `context.add_source`
|
|
213
219
|
3. Ask a grounded question: `context.query` or `context.evidence_answer`
|
|
220
|
+
4. If you selected OpenCode, wizard also updates `opencode.json` and creates `.opencode/plugins/whisper-context.ts`
|
|
221
|
+
|
|
222
|
+
## OpenCode Plugin Notes
|
|
223
|
+
|
|
224
|
+
When using OpenCode, the plugin runtime adds two OpenCode-only helper tools:
|
|
225
|
+
|
|
226
|
+
- `whisper_status`
|
|
227
|
+
- `whisper_flush_session`
|
|
228
|
+
|
|
229
|
+
These are plugin tools, not MCP tools. Continue using Whisper MCP for retrieval and persistence verbs.
|
|
214
230
|
|
|
215
231
|
## License
|
|
216
232
|
|
package/dist/server.js
CHANGED
|
@@ -144,6 +144,7 @@ var RuntimeClient = class {
|
|
|
144
144
|
diagnostics;
|
|
145
145
|
inFlight = /* @__PURE__ */ new Map();
|
|
146
146
|
sendApiKeyHeader;
|
|
147
|
+
fetchImpl;
|
|
147
148
|
constructor(options, diagnostics) {
|
|
148
149
|
if (!options.apiKey) {
|
|
149
150
|
throw new RuntimeClientError({
|
|
@@ -168,6 +169,7 @@ var RuntimeClient = class {
|
|
|
168
169
|
...options.timeouts || {}
|
|
169
170
|
};
|
|
170
171
|
this.sendApiKeyHeader = process.env.WHISPER_SEND_X_API_KEY === "1";
|
|
172
|
+
this.fetchImpl = options.fetchImpl || fetch;
|
|
171
173
|
this.diagnostics = diagnostics || new DiagnosticsStore(1e3);
|
|
172
174
|
}
|
|
173
175
|
getDiagnosticsStore() {
|
|
@@ -288,7 +290,7 @@ var RuntimeClient = class {
|
|
|
288
290
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
289
291
|
try {
|
|
290
292
|
const attachApiKeyHeader = this.shouldAttachApiKeyHeader(normalizedEndpoint);
|
|
291
|
-
const response = await
|
|
293
|
+
const response = await this.fetchImpl(`${this.baseUrl}${normalizedEndpoint}`, {
|
|
292
294
|
method,
|
|
293
295
|
signal: controller.signal,
|
|
294
296
|
keepalive: method !== "GET",
|
|
@@ -774,6 +776,9 @@ var WhisperContext = class _WhisperContext {
|
|
|
774
776
|
if (params.auth_ref) config.auth_ref = params.auth_ref;
|
|
775
777
|
}
|
|
776
778
|
if (params.metadata) config.metadata = params.metadata;
|
|
779
|
+
if (params.ingestion_profile) config.ingestion_profile = params.ingestion_profile;
|
|
780
|
+
if (params.strategy_override) config.strategy_override = params.strategy_override;
|
|
781
|
+
if (params.profile_config) config.profile_config = params.profile_config;
|
|
777
782
|
config.auto_index = params.auto_index ?? true;
|
|
778
783
|
const created = await this.addSource(project, {
|
|
779
784
|
name: params.name || `${params.type}-source-${Date.now()}`,
|
|
@@ -855,15 +860,42 @@ var WhisperContext = class _WhisperContext {
|
|
|
855
860
|
importance: params.importance,
|
|
856
861
|
metadata: params.metadata,
|
|
857
862
|
async: params.async,
|
|
858
|
-
write_mode: params.write_mode
|
|
863
|
+
write_mode: params.write_mode || (params.async === true ? "async" : "sync")
|
|
859
864
|
})
|
|
860
865
|
});
|
|
861
|
-
const
|
|
866
|
+
const mode = direct?.mode === "async" ? "async" : direct?.mode === "sync" ? "sync" : void 0;
|
|
867
|
+
const memoryId = direct?.memory?.id || direct?.memory_id || (mode !== "async" ? direct?.id : void 0);
|
|
868
|
+
const jobId = direct?.job_id || (mode === "async" ? direct?.id : void 0);
|
|
869
|
+
const id2 = memoryId || jobId || "";
|
|
862
870
|
if (id2) {
|
|
863
|
-
return {
|
|
871
|
+
return {
|
|
872
|
+
id: id2,
|
|
873
|
+
success: true,
|
|
874
|
+
path: "sota",
|
|
875
|
+
fallback_used: false,
|
|
876
|
+
mode,
|
|
877
|
+
...memoryId ? { memory_id: memoryId } : {},
|
|
878
|
+
...jobId ? { job_id: jobId } : {},
|
|
879
|
+
...direct?.status_url ? { status_url: direct.status_url } : {},
|
|
880
|
+
...direct?.accepted_at ? { accepted_at: direct.accepted_at } : {},
|
|
881
|
+
...direct?.visibility_sla_ms ? { visibility_sla_ms: direct.visibility_sla_ms } : {},
|
|
882
|
+
...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {},
|
|
883
|
+
...direct?.semantic_status ? { semantic_status: direct.semantic_status } : {}
|
|
884
|
+
};
|
|
864
885
|
}
|
|
865
886
|
if (direct?.success === true) {
|
|
866
|
-
return {
|
|
887
|
+
return {
|
|
888
|
+
id: "",
|
|
889
|
+
success: true,
|
|
890
|
+
path: "sota",
|
|
891
|
+
fallback_used: false,
|
|
892
|
+
mode,
|
|
893
|
+
...direct?.status_url ? { status_url: direct.status_url } : {},
|
|
894
|
+
...direct?.accepted_at ? { accepted_at: direct.accepted_at } : {},
|
|
895
|
+
...direct?.visibility_sla_ms ? { visibility_sla_ms: direct.visibility_sla_ms } : {},
|
|
896
|
+
...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {},
|
|
897
|
+
...direct?.semantic_status ? { semantic_status: direct.semantic_status } : {}
|
|
898
|
+
};
|
|
867
899
|
}
|
|
868
900
|
} catch (error) {
|
|
869
901
|
if (params.allow_legacy_fallback === false) {
|
|
@@ -891,7 +923,15 @@ var WhisperContext = class _WhisperContext {
|
|
|
891
923
|
message: "Memory create succeeded but no memory id was returned by the API"
|
|
892
924
|
});
|
|
893
925
|
}
|
|
894
|
-
return {
|
|
926
|
+
return {
|
|
927
|
+
id,
|
|
928
|
+
success: true,
|
|
929
|
+
path: "legacy",
|
|
930
|
+
fallback_used: true,
|
|
931
|
+
mode: "sync",
|
|
932
|
+
memory_id: id,
|
|
933
|
+
semantic_status: "ready"
|
|
934
|
+
};
|
|
895
935
|
});
|
|
896
936
|
}
|
|
897
937
|
async addMemoriesBulk(params) {
|
|
@@ -1408,15 +1448,25 @@ var BASE_URL = process.env.WHISPER_BASE_URL;
|
|
|
1408
1448
|
var RUNTIME_MODE = (process.env.WHISPER_MCP_MODE || "remote").toLowerCase();
|
|
1409
1449
|
var CLI_ARGS = process.argv.slice(2);
|
|
1410
1450
|
var IS_MANAGEMENT_ONLY = CLI_ARGS.includes("--print-tool-map") || CLI_ARGS[0] === "scope";
|
|
1411
|
-
|
|
1412
|
-
apiKey
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1451
|
+
function createWhisperMcpClient(options) {
|
|
1452
|
+
const apiKey = options?.apiKey ?? API_KEY;
|
|
1453
|
+
if (!apiKey || IS_MANAGEMENT_ONLY) {
|
|
1454
|
+
return null;
|
|
1455
|
+
}
|
|
1456
|
+
return new WhisperContext({
|
|
1457
|
+
apiKey,
|
|
1458
|
+
project: options?.project ?? DEFAULT_PROJECT,
|
|
1459
|
+
...(options?.baseUrl ?? BASE_URL) && { baseUrl: options?.baseUrl ?? BASE_URL }
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
var whisper = createWhisperMcpClient();
|
|
1416
1463
|
var server = new McpServer({
|
|
1417
1464
|
name: "whisper-context",
|
|
1418
1465
|
version: "0.2.8"
|
|
1419
1466
|
});
|
|
1467
|
+
function createMcpServer() {
|
|
1468
|
+
return server;
|
|
1469
|
+
}
|
|
1420
1470
|
var STATE_DIR = join(homedir(), ".whisper-mcp");
|
|
1421
1471
|
var STATE_PATH = join(STATE_DIR, "state.json");
|
|
1422
1472
|
var AUDIT_LOG_PATH = join(STATE_DIR, "forget-audit.log");
|
|
@@ -1877,6 +1927,9 @@ async function createSourceByType(params) {
|
|
|
1877
1927
|
if (params.max_chunks !== void 0) config.max_chunks = params.max_chunks;
|
|
1878
1928
|
}
|
|
1879
1929
|
if (params.metadata) config.metadata = params.metadata;
|
|
1930
|
+
if (params.ingestion_profile) config.ingestion_profile = params.ingestion_profile;
|
|
1931
|
+
if (params.strategy_override) config.strategy_override = params.strategy_override;
|
|
1932
|
+
if (params.profile_config) config.profile_config = params.profile_config;
|
|
1880
1933
|
config.auto_index = params.auto_index ?? true;
|
|
1881
1934
|
const created = await whisper.addSource(params.project, {
|
|
1882
1935
|
name: params.name || `${params.type}-source-${Date.now()}`,
|
|
@@ -1921,11 +1974,17 @@ async function learnFromInput(input) {
|
|
|
1921
1974
|
throw new Error("No project resolved. Set WHISPER_PROJECT or provide project.");
|
|
1922
1975
|
}
|
|
1923
1976
|
if (input.content) {
|
|
1977
|
+
const mergedMetadata = {
|
|
1978
|
+
...input.metadata || {},
|
|
1979
|
+
...input.ingestion_profile ? { ingestion_profile: input.ingestion_profile } : {},
|
|
1980
|
+
...input.strategy_override ? { strategy_override: input.strategy_override } : {},
|
|
1981
|
+
...input.profile_config ? { profile_config: input.profile_config } : {}
|
|
1982
|
+
};
|
|
1924
1983
|
const result = await whisper.addContext({
|
|
1925
1984
|
project: resolvedProject,
|
|
1926
1985
|
content: input.content,
|
|
1927
1986
|
title: input.title || "Learned Context",
|
|
1928
|
-
metadata:
|
|
1987
|
+
metadata: mergedMetadata
|
|
1929
1988
|
});
|
|
1930
1989
|
return {
|
|
1931
1990
|
mode: "text",
|
|
@@ -1942,7 +2001,10 @@ async function learnFromInput(input) {
|
|
|
1942
2001
|
branch: input.branch,
|
|
1943
2002
|
name: input.name,
|
|
1944
2003
|
auto_index: true,
|
|
1945
|
-
metadata: input.metadata
|
|
2004
|
+
metadata: input.metadata,
|
|
2005
|
+
ingestion_profile: input.ingestion_profile,
|
|
2006
|
+
strategy_override: input.strategy_override,
|
|
2007
|
+
profile_config: input.profile_config
|
|
1946
2008
|
});
|
|
1947
2009
|
}
|
|
1948
2010
|
if (input.path) {
|
|
@@ -1953,7 +2015,10 @@ async function learnFromInput(input) {
|
|
|
1953
2015
|
glob: input.glob,
|
|
1954
2016
|
max_files: input.max_files,
|
|
1955
2017
|
name: input.name,
|
|
1956
|
-
metadata: input.metadata
|
|
2018
|
+
metadata: input.metadata,
|
|
2019
|
+
ingestion_profile: input.ingestion_profile,
|
|
2020
|
+
strategy_override: input.strategy_override,
|
|
2021
|
+
profile_config: input.profile_config
|
|
1957
2022
|
});
|
|
1958
2023
|
}
|
|
1959
2024
|
if (input.file_path) {
|
|
@@ -1962,7 +2027,10 @@ async function learnFromInput(input) {
|
|
|
1962
2027
|
type: "pdf",
|
|
1963
2028
|
file_path: input.file_path,
|
|
1964
2029
|
name: input.name,
|
|
1965
|
-
metadata: input.metadata
|
|
2030
|
+
metadata: input.metadata,
|
|
2031
|
+
ingestion_profile: input.ingestion_profile,
|
|
2032
|
+
strategy_override: input.strategy_override,
|
|
2033
|
+
profile_config: input.profile_config
|
|
1966
2034
|
});
|
|
1967
2035
|
}
|
|
1968
2036
|
if (input.url) {
|
|
@@ -1972,6 +2040,9 @@ async function learnFromInput(input) {
|
|
|
1972
2040
|
url: input.url,
|
|
1973
2041
|
name: input.name,
|
|
1974
2042
|
metadata: input.metadata,
|
|
2043
|
+
ingestion_profile: input.ingestion_profile,
|
|
2044
|
+
strategy_override: input.strategy_override,
|
|
2045
|
+
profile_config: input.profile_config,
|
|
1975
2046
|
crawl_depth: input.crawl_depth,
|
|
1976
2047
|
channel_ids: input.channel_ids,
|
|
1977
2048
|
token: input.token,
|
|
@@ -1982,7 +2053,7 @@ async function learnFromInput(input) {
|
|
|
1982
2053
|
}
|
|
1983
2054
|
throw new Error("Provide content, owner+repo, path, file_path, or url.");
|
|
1984
2055
|
}
|
|
1985
|
-
function
|
|
2056
|
+
function renderScopedMcpConfig(project, source, client) {
|
|
1986
2057
|
const serverDef = {
|
|
1987
2058
|
command: "npx",
|
|
1988
2059
|
args: ["-y", "@usewhisper/mcp-server"],
|
|
@@ -2445,7 +2516,13 @@ server.tool(
|
|
|
2445
2516
|
agent_id,
|
|
2446
2517
|
importance
|
|
2447
2518
|
});
|
|
2448
|
-
|
|
2519
|
+
const memoryId = result?.memory_id || result.id;
|
|
2520
|
+
const jobId = result?.job_id;
|
|
2521
|
+
const mode = result?.mode;
|
|
2522
|
+
const semanticStatus = result?.semantic_status;
|
|
2523
|
+
const typeLabel = memory_type || "factual";
|
|
2524
|
+
const text = mode === "async" || jobId ? `Memory queued (job_id: ${jobId || result.id}, type: ${typeLabel}).` : `Memory stored (id: ${memoryId}, type: ${typeLabel}${semanticStatus ? `, semantic_status: ${semanticStatus}` : ""}).`;
|
|
2525
|
+
return { content: [{ type: "text", text }] };
|
|
2449
2526
|
} catch (error) {
|
|
2450
2527
|
return { content: [{ type: "text", text: `Error: ${error.message}` }] };
|
|
2451
2528
|
}
|
|
@@ -2522,6 +2599,9 @@ server.tool(
|
|
|
2522
2599
|
name: z.string().optional(),
|
|
2523
2600
|
auto_index: z.boolean().optional().default(true),
|
|
2524
2601
|
metadata: z.record(z.string()).optional(),
|
|
2602
|
+
ingestion_profile: z.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
2603
|
+
strategy_override: z.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
2604
|
+
profile_config: z.record(z.any()).optional(),
|
|
2525
2605
|
owner: z.string().optional(),
|
|
2526
2606
|
repo: z.string().optional(),
|
|
2527
2607
|
branch: z.string().optional(),
|
|
@@ -2557,6 +2637,9 @@ server.tool(
|
|
|
2557
2637
|
name: input.name,
|
|
2558
2638
|
auto_index: input.auto_index,
|
|
2559
2639
|
metadata: input.metadata,
|
|
2640
|
+
ingestion_profile: input.ingestion_profile,
|
|
2641
|
+
strategy_override: input.strategy_override,
|
|
2642
|
+
profile_config: input.profile_config,
|
|
2560
2643
|
owner: input.owner,
|
|
2561
2644
|
repo: input.repo,
|
|
2562
2645
|
branch: input.branch,
|
|
@@ -2607,14 +2690,22 @@ server.tool(
|
|
|
2607
2690
|
{
|
|
2608
2691
|
project: z.string().optional().describe("Project name or slug"),
|
|
2609
2692
|
title: z.string().describe("Title for this content"),
|
|
2610
|
-
content: z.string().describe("The text content to index")
|
|
2693
|
+
content: z.string().describe("The text content to index"),
|
|
2694
|
+
ingestion_profile: z.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
2695
|
+
strategy_override: z.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
2696
|
+
profile_config: z.record(z.any()).optional()
|
|
2611
2697
|
},
|
|
2612
|
-
async ({ project, title, content }) => {
|
|
2698
|
+
async ({ project, title, content, ingestion_profile, strategy_override, profile_config }) => {
|
|
2613
2699
|
try {
|
|
2614
2700
|
await whisper.addContext({
|
|
2615
2701
|
project,
|
|
2616
2702
|
title,
|
|
2617
|
-
content
|
|
2703
|
+
content,
|
|
2704
|
+
metadata: {
|
|
2705
|
+
...ingestion_profile ? { ingestion_profile } : {},
|
|
2706
|
+
...strategy_override ? { strategy_override } : {},
|
|
2707
|
+
...profile_config ? { profile_config } : {}
|
|
2708
|
+
}
|
|
2618
2709
|
});
|
|
2619
2710
|
return { content: [{ type: "text", text: `Indexed "${title}" (${content.length} chars).` }] };
|
|
2620
2711
|
} catch (error) {
|
|
@@ -2634,9 +2725,12 @@ server.tool(
|
|
|
2634
2725
|
auto_sync: z.boolean().optional().default(true),
|
|
2635
2726
|
tags: z.array(z.string()).optional(),
|
|
2636
2727
|
platform: z.enum(["youtube", "loom", "generic"]).optional(),
|
|
2637
|
-
language: z.string().optional()
|
|
2728
|
+
language: z.string().optional(),
|
|
2729
|
+
ingestion_profile: z.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
2730
|
+
strategy_override: z.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
2731
|
+
profile_config: z.record(z.any()).optional()
|
|
2638
2732
|
},
|
|
2639
|
-
async ({ project, source_type, title, content, url, auto_sync, tags, platform, language }) => {
|
|
2733
|
+
async ({ project, source_type, title, content, url, auto_sync, tags, platform, language, ingestion_profile, strategy_override, profile_config }) => {
|
|
2640
2734
|
try {
|
|
2641
2735
|
const resolvedProject = await resolveProjectRef(project);
|
|
2642
2736
|
if (!resolvedProject) {
|
|
@@ -2652,7 +2746,10 @@ server.tool(
|
|
|
2652
2746
|
auto_sync,
|
|
2653
2747
|
tags,
|
|
2654
2748
|
platform,
|
|
2655
|
-
language
|
|
2749
|
+
language,
|
|
2750
|
+
ingestion_profile,
|
|
2751
|
+
strategy_override,
|
|
2752
|
+
profile_config
|
|
2656
2753
|
});
|
|
2657
2754
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2658
2755
|
}
|
|
@@ -2663,7 +2760,13 @@ server.tool(
|
|
|
2663
2760
|
project: resolvedProject,
|
|
2664
2761
|
title: title || "Document",
|
|
2665
2762
|
content,
|
|
2666
|
-
metadata: {
|
|
2763
|
+
metadata: {
|
|
2764
|
+
source: "mcp:add_document",
|
|
2765
|
+
tags: tags || [],
|
|
2766
|
+
...ingestion_profile ? { ingestion_profile } : {},
|
|
2767
|
+
...strategy_override ? { strategy_override } : {},
|
|
2768
|
+
...profile_config ? { profile_config } : {}
|
|
2769
|
+
}
|
|
2667
2770
|
});
|
|
2668
2771
|
return { content: [{ type: "text", text: `Indexed "${title || "Document"}" (${content.length} chars).` }] };
|
|
2669
2772
|
} catch (error) {
|
|
@@ -2725,16 +2828,21 @@ server.tool(
|
|
|
2725
2828
|
},
|
|
2726
2829
|
async ({ project, session_id, user_id, messages }) => {
|
|
2727
2830
|
try {
|
|
2831
|
+
const normalizedMessages = messages.map((message) => ({
|
|
2832
|
+
role: message.role,
|
|
2833
|
+
content: message.content,
|
|
2834
|
+
timestamp: message.timestamp
|
|
2835
|
+
}));
|
|
2728
2836
|
const result = await whisper.ingestSession({
|
|
2729
2837
|
project,
|
|
2730
2838
|
session_id,
|
|
2731
2839
|
user_id,
|
|
2732
|
-
messages
|
|
2840
|
+
messages: normalizedMessages
|
|
2733
2841
|
});
|
|
2734
2842
|
return {
|
|
2735
2843
|
content: [{
|
|
2736
2844
|
type: "text",
|
|
2737
|
-
text: `Processed ${
|
|
2845
|
+
text: `Processed ${normalizedMessages.length} messages:
|
|
2738
2846
|
- Created ${result.memories_created} memories
|
|
2739
2847
|
- Detected ${result.relations_created} relations
|
|
2740
2848
|
- Updated ${result.memories_invalidated} outdated memories` + (result.errors && result.errors.length > 0 ? `
|
|
@@ -4016,11 +4124,17 @@ server.tool(
|
|
|
4016
4124
|
async ({ project, content, memory_type, user_id, session_id, agent_id, importance }) => {
|
|
4017
4125
|
try {
|
|
4018
4126
|
const result = await whisper.addMemory({ project, content, memory_type, user_id, session_id, agent_id, importance });
|
|
4127
|
+
const memoryId = result?.memory_id || (result.mode === "sync" ? result.id : null);
|
|
4128
|
+
const jobId = result?.job_id || (result.mode === "async" ? result.id : null);
|
|
4019
4129
|
return primaryToolSuccess({
|
|
4020
4130
|
tool: "remember",
|
|
4021
|
-
id:
|
|
4131
|
+
id: memoryId || jobId || null,
|
|
4132
|
+
memory_id: memoryId,
|
|
4133
|
+
job_id: jobId,
|
|
4134
|
+
mode: result?.mode || null,
|
|
4022
4135
|
memory_type,
|
|
4023
|
-
stored: result.success === true
|
|
4136
|
+
stored: result.success === true,
|
|
4137
|
+
queued: result?.mode === "async" || Boolean(jobId)
|
|
4024
4138
|
});
|
|
4025
4139
|
} catch (error) {
|
|
4026
4140
|
return primaryToolError(error.message);
|
|
@@ -4045,7 +4159,16 @@ server.tool(
|
|
|
4045
4159
|
},
|
|
4046
4160
|
async ({ project, session_id, user_id, messages, role, content, timestamp }) => {
|
|
4047
4161
|
try {
|
|
4048
|
-
const normalizedMessages = normalizeRecordMessages({
|
|
4162
|
+
const normalizedMessages = normalizeRecordMessages({
|
|
4163
|
+
messages: messages?.map((message) => ({
|
|
4164
|
+
role: message.role,
|
|
4165
|
+
content: message.content,
|
|
4166
|
+
timestamp: message.timestamp
|
|
4167
|
+
})),
|
|
4168
|
+
role,
|
|
4169
|
+
content,
|
|
4170
|
+
timestamp
|
|
4171
|
+
});
|
|
4049
4172
|
const result = await whisper.ingestSession({ project, session_id, user_id, messages: normalizedMessages });
|
|
4050
4173
|
return primaryToolSuccess({
|
|
4051
4174
|
tool: "record",
|
|
@@ -4074,6 +4197,9 @@ server.tool(
|
|
|
4074
4197
|
file_path: z.string().optional().describe("Single file path to learn from"),
|
|
4075
4198
|
name: z.string().optional().describe("Optional source name"),
|
|
4076
4199
|
metadata: z.record(z.string()).optional(),
|
|
4200
|
+
ingestion_profile: z.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
4201
|
+
strategy_override: z.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
4202
|
+
profile_config: z.record(z.any()).optional(),
|
|
4077
4203
|
max_files: z.number().optional(),
|
|
4078
4204
|
glob: z.string().optional(),
|
|
4079
4205
|
crawl_depth: z.number().optional()
|
|
@@ -4130,7 +4256,7 @@ async function main() {
|
|
|
4130
4256
|
const source = readArg("--source") || "source-or-type";
|
|
4131
4257
|
const client = readArg("--client") || "json";
|
|
4132
4258
|
const outPath = readArg("--write");
|
|
4133
|
-
const rendered =
|
|
4259
|
+
const rendered = renderScopedMcpConfig(project, source, client);
|
|
4134
4260
|
if (outPath) {
|
|
4135
4261
|
const backup = existsSync(outPath) ? `${outPath}.bak-${Date.now()}` : void 0;
|
|
4136
4262
|
if (backup) writeFileSync(backup, readFileSync(outPath, "utf-8"), "utf-8");
|
|
@@ -4151,4 +4277,11 @@ async function main() {
|
|
|
4151
4277
|
await server.connect(transport);
|
|
4152
4278
|
console.error("Whisper Context MCP server running on stdio");
|
|
4153
4279
|
}
|
|
4154
|
-
|
|
4280
|
+
if (process.argv[1] && /server\.(mjs|cjs|js|ts)$/.test(process.argv[1])) {
|
|
4281
|
+
main().catch(console.error);
|
|
4282
|
+
}
|
|
4283
|
+
export {
|
|
4284
|
+
createMcpServer,
|
|
4285
|
+
createWhisperMcpClient,
|
|
4286
|
+
renderScopedMcpConfig
|
|
4287
|
+
};
|