record_safer_pro_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.
Files changed (78) hide show
  1. package/README.md +205 -0
  2. package/dist/api-client.d.ts +159 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +991 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +4 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/prompts/index.d.ts +12 -0
  11. package/dist/prompts/index.d.ts.map +1 -0
  12. package/dist/prompts/index.js +235 -0
  13. package/dist/prompts/index.js.map +1 -0
  14. package/dist/resources/index.d.ts +7 -0
  15. package/dist/resources/index.d.ts.map +1 -0
  16. package/dist/resources/index.js +59 -0
  17. package/dist/resources/index.js.map +1 -0
  18. package/dist/resources/mixing-guide-content.d.ts +8 -0
  19. package/dist/resources/mixing-guide-content.d.ts.map +1 -0
  20. package/dist/resources/mixing-guide-content.js +194 -0
  21. package/dist/resources/mixing-guide-content.js.map +1 -0
  22. package/dist/runtime.d.ts +39 -0
  23. package/dist/runtime.d.ts.map +1 -0
  24. package/dist/runtime.js +320 -0
  25. package/dist/runtime.js.map +1 -0
  26. package/dist/telemetry-schema.d.ts +39 -0
  27. package/dist/telemetry-schema.d.ts.map +1 -0
  28. package/dist/telemetry-schema.js +15 -0
  29. package/dist/telemetry-schema.js.map +1 -0
  30. package/dist/tools/core.d.ts +4 -0
  31. package/dist/tools/core.d.ts.map +1 -0
  32. package/dist/tools/core.js +360 -0
  33. package/dist/tools/core.js.map +1 -0
  34. package/dist/tools/devices.d.ts +10 -0
  35. package/dist/tools/devices.d.ts.map +1 -0
  36. package/dist/tools/devices.js +53 -0
  37. package/dist/tools/devices.js.map +1 -0
  38. package/dist/tools/levels.d.ts +11 -0
  39. package/dist/tools/levels.d.ts.map +1 -0
  40. package/dist/tools/levels.js +25 -0
  41. package/dist/tools/levels.js.map +1 -0
  42. package/dist/tools/markers.d.ts +17 -0
  43. package/dist/tools/markers.d.ts.map +1 -0
  44. package/dist/tools/markers.js +142 -0
  45. package/dist/tools/markers.js.map +1 -0
  46. package/dist/tools/monitor.d.ts +19 -0
  47. package/dist/tools/monitor.d.ts.map +1 -0
  48. package/dist/tools/monitor.js +232 -0
  49. package/dist/tools/monitor.js.map +1 -0
  50. package/dist/tools/recording.d.ts +12 -0
  51. package/dist/tools/recording.d.ts.map +1 -0
  52. package/dist/tools/recording.js +85 -0
  53. package/dist/tools/recording.js.map +1 -0
  54. package/dist/tools/settings.d.ts +10 -0
  55. package/dist/tools/settings.d.ts.map +1 -0
  56. package/dist/tools/settings.js +43 -0
  57. package/dist/tools/settings.js.map +1 -0
  58. package/dist/tools/storage.d.ts +10 -0
  59. package/dist/tools/storage.d.ts.map +1 -0
  60. package/dist/tools/storage.js +20 -0
  61. package/dist/tools/storage.js.map +1 -0
  62. package/dist/tools/system.d.ts +10 -0
  63. package/dist/tools/system.d.ts.map +1 -0
  64. package/dist/tools/system.js +53 -0
  65. package/dist/tools/system.js.map +1 -0
  66. package/dist/tools/tool-metadata.d.ts +19 -0
  67. package/dist/tools/tool-metadata.d.ts.map +1 -0
  68. package/dist/tools/tool-metadata.js +25 -0
  69. package/dist/tools/tool-metadata.js.map +1 -0
  70. package/dist/types.d.ts +456 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +4 -0
  73. package/dist/types.js.map +1 -0
  74. package/dist/utils.d.ts +80 -0
  75. package/dist/utils.d.ts.map +1 -0
  76. package/dist/utils.js +336 -0
  77. package/dist/utils.js.map +1 -0
  78. package/package.json +40 -0
@@ -0,0 +1,142 @@
1
+ /**
2
+ * 轨道与标记 Tools — 轨道管理与标记点操作
3
+ * Track & Marker Tools — Track management and marker operations
4
+ *
5
+ * 【MCP 高价值场景】
6
+ * 录音中添加标记是 MCP 最自然的使用场景之一:
7
+ * - 用户说"标记一下,这是副歌" → add_marker(label: "副歌")
8
+ * - 用户说"加个标记" → add_marker()(自动编号)
9
+ * 比在 GUI 上点击按钮再输入名称更快。
10
+ *
11
+ * 【前置依赖】标记操作需要录音正在进行中。
12
+ * 通道重命名和颜色设置需要会话已初始化。
13
+ */
14
+ import { z } from "zod";
15
+ import { RecordSaferClient } from "../api-client.js";
16
+ import { handleToolCall } from "../utils.js";
17
+ const NAMED_CHANNEL_COLORS = {
18
+ green: "#32CD32",
19
+ "绿色": "#32CD32",
20
+ blue: "#1E90FF",
21
+ "蓝色": "#1E90FF",
22
+ red: "#FF3B30",
23
+ "红色": "#FF3B30",
24
+ yellow: "#FFD60A",
25
+ "黄色": "#FFD60A",
26
+ orange: "#FF9500",
27
+ "橙色": "#FF9500",
28
+ purple: "#AF52DE",
29
+ "紫色": "#AF52DE",
30
+ };
31
+ function toHexByte(value) {
32
+ return value.toString(16).toUpperCase().padStart(2, "0");
33
+ }
34
+ export function normalizeChannelColorInput(input) {
35
+ const trimmed = input.trim();
36
+ if (!trimmed) {
37
+ throw new Error("Unsupported color value. Please provide a concrete #RRGGBB color.");
38
+ }
39
+ const lowered = trimmed.toLowerCase();
40
+ if (lowered === "clear" ||
41
+ lowered === "clear color" ||
42
+ lowered === "none" ||
43
+ lowered === "no color" ||
44
+ trimmed === "清除颜色" ||
45
+ trimmed === "无颜色") {
46
+ throw new Error("Clearing channel color is not supported by this API. Please provide a concrete #RRGGBB color.");
47
+ }
48
+ const namedColor = NAMED_CHANNEL_COLORS[lowered] ?? NAMED_CHANNEL_COLORS[trimmed];
49
+ if (namedColor) {
50
+ return namedColor;
51
+ }
52
+ if (/^#?[0-9a-fA-F]{6}$/.test(trimmed)) {
53
+ return `#${trimmed.replace(/^#/, "").toUpperCase()}`;
54
+ }
55
+ const rgbMatch = /^rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i.exec(trimmed);
56
+ if (rgbMatch) {
57
+ const rgb = rgbMatch.slice(1).map(Number);
58
+ if (rgb.every((value) => value >= 0 && value <= 255)) {
59
+ return `#${rgb.map(toHexByte).join("")}`;
60
+ }
61
+ }
62
+ throw new Error("Unsupported color value. Use a named color, #RRGGBB hex, or rgb(r, g, b).");
63
+ }
64
+ export function registerMarkerTools(server) {
65
+ const client = new RecordSaferClient();
66
+ server.tool("list_tracks", `[Recording Phase] List available tracks [read].
67
+ Prerequisite: recording is in progress or already completed.`, {}, async () => handleToolCall("list_tracks", "read", () => client.listTracks(), client));
68
+ server.tool("stop_track", "[Recording Phase] Stop a track [write]. ⚠️ This stops the specified track and requires explicit user confirmation.", { trackId: z.string().min(1).describe("Track ID") }, async ({ trackId }) => handleToolCall("stop_track", "write", () => client.stopTrack(trackId), client));
69
+ server.tool("list_markers", "[Recording Phase] List all markers [read]. Returns all marker points in the current recording session.", {}, async () => handleToolCall("list_markers", "read", () => client.listMarkers(), client));
70
+ server.tool("add_marker", `[Recording Phase] Add a marker [write].
71
+ ⚠️ This adds a marker at the current recording position and requires explicit user confirmation.
72
+ Prerequisite: recording must be active.
73
+ Use case: "add a marker", or "mark this as XXX".
74
+ label is optional; if omitted, the system auto-generates a label.`, { label: z.string().optional().describe("Marker label") }, async ({ label }) => handleToolCall("add_marker", "write", () => client.addMarker(label), client));
75
+ server.tool("sync_markers", "[Recording Phase] Sync markers to file [write]. ⚠️ This writes the full marker list into recording metadata/files and requires explicit user confirmation.", {
76
+ markers: z.array(z.object({
77
+ id: z.number().int().positive(),
78
+ timestamp: z.number().nonnegative(),
79
+ label: z.string(),
80
+ time: z.string().optional(),
81
+ })).min(1).describe("Complete marker list to persist"),
82
+ }, async ({ markers }) => handleToolCall("sync_markers", "write", () => client.syncMarkers(markers), client));
83
+ server.tool("rename_marker", "Rename a marker [write]. You can target by marker ID or current marker name. ⚠️ This modifies marker metadata and requires explicit user confirmation.", {
84
+ identifier: z.string().min(1).describe("Marker ID or current marker name"),
85
+ name: z.string().min(1).describe("New name"),
86
+ }, async ({ identifier, name }) => handleToolCall("rename_marker", "write", async () => {
87
+ // 先获取目前所有的 markers 进行匹配
88
+ const markers = await client.listMarkers();
89
+ let targetId = identifier;
90
+ // 尝试通过名称匹配
91
+ const markerByName = markers.find(m => m.label === identifier);
92
+ if (markerByName) {
93
+ targetId = markerByName.id.toString();
94
+ }
95
+ else {
96
+ // 如果名称不匹配,作为 ID 处理
97
+ const markerById = markers.find(m => m.id.toString() === identifier);
98
+ if (markerById) {
99
+ targetId = markerById.id.toString();
100
+ }
101
+ else {
102
+ throw new Error(`Marker not found: ${identifier}`);
103
+ }
104
+ }
105
+ // 继续调用底层的 rename API (ID 此时已确保存在并通过验证)
106
+ return client.renameMarker(targetId, name);
107
+ }, client));
108
+ server.tool("rename_channel", `Rename a channel [write].
109
+ ⚠️ This changes channel name (and related recording file naming) and requires explicit user confirmation.
110
+ Prerequisite: user must be on the recording console page.
111
+
112
+ How to get channel ID and current name:
113
+ Call get_channels first. The channels array contains:
114
+ {
115
+ ready: true,
116
+ recording: true,
117
+ deviceName: "Schoeps BLC",
118
+ channels: [
119
+ {"id": 1, "name": "Kick", "deviceChannelLabel": "ADAT 1"},
120
+ {"id": 2, "name": "Snare", "deviceChannelLabel": "ADAT 2"}
121
+ ]
122
+ }
123
+
124
+ Use channels[].id as the required channel ID (stringified number). deviceChannelLabel is the physical interface label.
125
+
126
+ Parameter notes:
127
+ - id: channel ID as numeric string (for example "1", "2"), from channels[].id
128
+ - name: new channel name (max 63 chars; cannot include / \\ : * ? " < > |)
129
+
130
+ Batch hint: if user requests multiple renames, call this tool once per channel.
131
+ Example: "rename channel 1 to Vocal" -> call get_channels, map ID, then call rename_channel(id: "1", name: "Vocal")`, {
132
+ id: z.string().min(1).describe("Channel ID (numeric string from sessionConfig.channels[].id)"),
133
+ name: z.string().min(1).describe("New name (max 63 chars)"),
134
+ }, async ({ id, name }) => handleToolCall("rename_channel", "write", () => client.renameChannel(id, name), client));
135
+ server.tool("set_channel_color", `Set channel color [write].
136
+ ⚠️ This changes channel display color and requires explicit user confirmation.
137
+ Prerequisite: user must be on the recording console page.`, {
138
+ id: z.string().min(1).describe("Channel ID"),
139
+ color: z.string().min(1).describe("Color value"),
140
+ }, async ({ id, color }) => handleToolCall("set_channel_color", "write", () => client.setChannelColor(id, normalizeChannelColorInput(color)), client));
141
+ }
142
+ //# sourceMappingURL=markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.js","sourceRoot":"","sources":["../../src/tools/markers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 监听/DSP 控制 Tools — 监听混音器与通道控制
3
+ * Monitor/DSP Control Tools — Monitor mixer and channel controls
4
+ *
5
+ * 【前置条件】所有工具统一由 handleToolCall 内的 ensureReady 检查:
6
+ * 1. 后端连接预检(端口 token)
7
+ * 2. 录音控制台页面检查
8
+ * 安全模式录音中禁止监听与混音工具操作。
9
+ *
10
+ * 【MCP 高价值场景】
11
+ * 批量操作是 MCP 的优势所在,例如:
12
+ * - "把所有通道音量设到 0.8" → 循环调用 set_channel_volume
13
+ * - "静音通道 3、4、5" → 循环调用 set_channel_mute
14
+ * - "只听通道 1 和 2" → 对通道 1、2 调用 set_channel_solo
15
+ * 这些操作在 GUI 上需要逐个点击,但 MCP 可以一句话批量完成。
16
+ */
17
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
18
+ export declare function registerMonitorTools(server: McpServer): void;
19
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/tools/monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QA0TrD"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * 监听/DSP 控制 Tools — 监听混音器与通道控制
3
+ * Monitor/DSP Control Tools — Monitor mixer and channel controls
4
+ *
5
+ * 【前置条件】所有工具统一由 handleToolCall 内的 ensureReady 检查:
6
+ * 1. 后端连接预检(端口 token)
7
+ * 2. 录音控制台页面检查
8
+ * 安全模式录音中禁止监听与混音工具操作。
9
+ *
10
+ * 【MCP 高价值场景】
11
+ * 批量操作是 MCP 的优势所在,例如:
12
+ * - "把所有通道音量设到 0.8" → 循环调用 set_channel_volume
13
+ * - "静音通道 3、4、5" → 循环调用 set_channel_mute
14
+ * - "只听通道 1 和 2" → 对通道 1、2 调用 set_channel_solo
15
+ * 这些操作在 GUI 上需要逐个点击,但 MCP 可以一句话批量完成。
16
+ */
17
+ import { z } from "zod";
18
+ import { RecordSaferClient } from "../api-client.js";
19
+ import { handleToolCall, checkMixPrecondition } from "../utils.js";
20
+ const channelIndexSchema = {
21
+ index: z.number().int().min(0).max(255).describe("Channel index (0-based)"),
22
+ };
23
+ export function registerMonitorTools(server) {
24
+ const client = new RecordSaferClient();
25
+ server.tool("set_channels_mix", `Batch update mix parameters for multiple channels [write].
26
+ ⚠️ This applies changes to multiple channels and requires explicit user confirmation.`, {
27
+ indices: z.array(z.number().int().min(0).max(255)).min(1).describe("Channel indices (0-based)"),
28
+ volume: z.number().optional().describe("Channel volume"),
29
+ pan: z
30
+ .number()
31
+ .min(-1)
32
+ .max(1)
33
+ .optional()
34
+ .describe("Channel pan (-1.0 to 1.0)"),
35
+ solo: z.boolean().optional().describe("Solo state"),
36
+ mute: z.boolean().optional().describe("Mute state"),
37
+ msProcess: z.boolean().optional().describe("Enable M/S processing"),
38
+ phaseInvert: z.boolean().optional().describe("Phase invert state"),
39
+ }, async ({ indices, volume, pan, solo, mute, msProcess, phaseInvert }) => {
40
+ const mixErr = await checkMixPrecondition(client, "set_channels_mix");
41
+ if (mixErr) {
42
+ return { content: [{ type: "text", text: mixErr }], isError: true };
43
+ }
44
+ const targets = Array.from(new Set(indices)).sort((a, b) => a - b);
45
+ const applied = {};
46
+ if (typeof volume === "number") {
47
+ applied.volume = volume;
48
+ for (const index of targets) {
49
+ await client.setChannelVolume(index, volume);
50
+ }
51
+ }
52
+ if (typeof pan === "number") {
53
+ applied.pan = pan;
54
+ for (const index of targets) {
55
+ await client.setChannelPan(index, pan);
56
+ }
57
+ }
58
+ if (typeof solo === "boolean") {
59
+ applied.solo = solo;
60
+ for (const index of targets) {
61
+ await client.setChannelSolo(index, solo);
62
+ }
63
+ }
64
+ if (typeof mute === "boolean") {
65
+ applied.mute = mute;
66
+ for (const index of targets) {
67
+ await client.setChannelMute(index, mute);
68
+ }
69
+ }
70
+ if (typeof msProcess === "boolean") {
71
+ applied.msProcess = msProcess;
72
+ for (const index of targets) {
73
+ await client.setChannelMsProcess(index, msProcess);
74
+ }
75
+ }
76
+ if (typeof phaseInvert === "boolean") {
77
+ applied.phaseInvert = phaseInvert;
78
+ for (const index of targets) {
79
+ await client.setChannelPhaseInvert(index, phaseInvert);
80
+ }
81
+ }
82
+ if (Object.keys(applied).length === 0) {
83
+ return {
84
+ content: [{ type: "text", text: "At least one target field is required." }],
85
+ isError: true,
86
+ };
87
+ }
88
+ return handleToolCall("set_channels_mix", "write", async () => ({
89
+ channels: targets,
90
+ channelCount: targets.length,
91
+ applied,
92
+ }), client);
93
+ });
94
+ server.tool("get_monitor_status", "Get monitor status [read]. Returns the current monitor-engine state, selected input/output devices, buffer size, sample rate, and health flags.", {}, async () => handleToolCall("get_monitor_status", "read", () => client.getMonitorStatus(), client));
95
+ server.tool("start_monitor", `Start monitoring [recording_control].
96
+ ⚠️ This enables monitor output and requires explicit user confirmation.`, {
97
+ inputDeviceId: z.string().min(1).describe("Input device ID"),
98
+ outputDeviceId: z.string().min(1).describe("Output device ID"),
99
+ outputLeftChannel: z.number().int().positive().optional().describe("Optional output left channel (1-based)"),
100
+ outputRightChannel: z.number().int().positive().optional().describe("Optional output right channel (1-based)"),
101
+ bufferSize: z.number().int().positive().optional().describe("Optional monitor buffer size in frames"),
102
+ }, async ({ inputDeviceId, outputDeviceId, outputLeftChannel, outputRightChannel, bufferSize }) => handleToolCall("start_monitor", "recording_control", () => client.startMonitor({ inputDeviceId, outputDeviceId, outputLeftChannel, outputRightChannel, bufferSize }), client));
103
+ server.tool("stop_monitor", "Stop monitoring [recording_control]. ⚠️ This disables monitor output and requires explicit user confirmation.", {}, async () => handleToolCall("stop_monitor", "recording_control", () => client.stopMonitor(), client));
104
+ server.tool("set_master_volume", "Set master volume [write]. ⚠️ This changes monitor master output level and requires explicit user confirmation.", {
105
+ volume: z.number().describe("Master volume"),
106
+ pan: z
107
+ .number()
108
+ .min(-1)
109
+ .max(1)
110
+ .optional()
111
+ .describe("Master pan (-1.0 to 1.0)"),
112
+ }, async ({ volume, pan }) => {
113
+ const mixErr = await checkMixPrecondition(client, "set_master_volume");
114
+ if (mixErr)
115
+ return { content: [{ type: "text", text: mixErr }], isError: true };
116
+ return handleToolCall("set_master_volume", "write", () => client.setMasterVolume(volume, pan), client);
117
+ });
118
+ server.tool("get_mix_levels", "Get current mix output levels [read]. Returns aggregate mix and left/right meter levels, not per-channel mixer settings.", {}, async () => handleToolCall("get_mix_levels", "read", () => client.getMixLevels(), client));
119
+ server.tool("set_channel_volume", `Set channel volume [write].
120
+ ⚠️ This changes monitor volume for a channel and requires explicit user confirmation.
121
+ Batch hint: if multiple channels are requested, call this tool once per channel.`, {
122
+ ...channelIndexSchema,
123
+ volume: z.number().describe("Channel volume"),
124
+ }, async ({ index, volume }) => {
125
+ const mixErr = await checkMixPrecondition(client, "set_channel_volume");
126
+ if (mixErr)
127
+ return { content: [{ type: "text", text: mixErr }], isError: true };
128
+ return handleToolCall("set_channel_volume", "write", () => client.setChannelVolume(index, volume), client);
129
+ });
130
+ server.tool("set_channel_pan", `Set channel pan [write]. ⚠️ This changes channel pan position and requires explicit user confirmation.
131
+ Pan conversion rules: range is -1.0 (hard left) to 1.0 (hard right), and 0.0 is center.
132
+ - "L 10" -> -0.1
133
+ - "R 50" -> 0.5
134
+ - "hard left" or "L 100" -> -1.0
135
+ - "hard right" or "R 100" -> 1.0
136
+ - "center" or "C" -> 0.0`, {
137
+ ...channelIndexSchema,
138
+ pan: z
139
+ .number()
140
+ .min(-1)
141
+ .max(1)
142
+ .describe("Channel pan (-1.0 to 1.0). Negative is left (L), positive is right (R), 0 is center. Example: if user says 'L 10', pass -0.1, not 10."),
143
+ }, async ({ index, pan }) => {
144
+ const mixErr = await checkMixPrecondition(client, "set_channel_pan");
145
+ if (mixErr)
146
+ return { content: [{ type: "text", text: mixErr }], isError: true };
147
+ return handleToolCall("set_channel_pan", "write", () => client.setChannelPan(index, pan), client);
148
+ });
149
+ server.tool("set_channel_solo", `Set channel solo [write].
150
+ ⚠️ This changes channel solo state and requires explicit user confirmation.
151
+ Hint: "listen only to channel X" maps to enabling solo on channel X.`, {
152
+ ...channelIndexSchema,
153
+ solo: z.boolean().describe("Solo state"),
154
+ }, async ({ index, solo }) => {
155
+ const mixErr = await checkMixPrecondition(client, "set_channel_solo");
156
+ if (mixErr)
157
+ return { content: [{ type: "text", text: mixErr }], isError: true };
158
+ return handleToolCall("set_channel_solo", "write", () => client.setChannelSolo(index, solo), client);
159
+ });
160
+ server.tool("set_channel_mute", `Set channel mute [write].
161
+ ⚠️ This changes channel mute state and requires explicit user confirmation.`, {
162
+ ...channelIndexSchema,
163
+ mute: z.boolean().describe("Mute state"),
164
+ }, async ({ index, mute }) => {
165
+ const mixErr = await checkMixPrecondition(client, "set_channel_mute");
166
+ if (mixErr)
167
+ return { content: [{ type: "text", text: mixErr }], isError: true };
168
+ return handleToolCall("set_channel_mute", "write", () => client.setChannelMute(index, mute), client);
169
+ });
170
+ server.tool("set_channel_ms_process", "Set channel M/S processing [write]. ⚠️ This changes Mid/Side mode and requires explicit user confirmation.", {
171
+ ...channelIndexSchema,
172
+ enabled: z.boolean().describe("Enable or disable"),
173
+ }, async ({ index, enabled }) => {
174
+ const mixErr = await checkMixPrecondition(client, "set_channel_ms_process");
175
+ if (mixErr)
176
+ return { content: [{ type: "text", text: mixErr }], isError: true };
177
+ return handleToolCall("set_channel_ms_process", "write", () => client.setChannelMsProcess(index, enabled), client);
178
+ });
179
+ server.tool("set_channel_phase_invert", "Set channel phase invert [write]. ⚠️ This toggles channel phase inversion and requires explicit user confirmation.", {
180
+ ...channelIndexSchema,
181
+ inverted: z.boolean().describe("Phase invert state"),
182
+ }, async ({ index, inverted }) => {
183
+ const mixErr = await checkMixPrecondition(client, "set_channel_phase_invert");
184
+ if (mixErr)
185
+ return { content: [{ type: "text", text: mixErr }], isError: true };
186
+ return handleToolCall("set_channel_phase_invert", "write", () => client.setChannelPhaseInvert(index, inverted), client);
187
+ });
188
+ server.tool("merge_channels_stereo", `Merge two mono channels into a stereo pair [write].
189
+ ⚠️ This changes pan settings for both channels and requires explicit user confirmation.`, {
190
+ leftIndex: z.number().int().min(0).max(255).describe("Left channel index (0-based)"),
191
+ rightIndex: z.number().int().min(0).max(255).describe("Right channel index (0-based)"),
192
+ }, async ({ leftIndex, rightIndex }) => {
193
+ if (leftIndex === rightIndex) {
194
+ return {
195
+ content: [{ type: "text", text: "Error: leftIndex and rightIndex must be different." }],
196
+ isError: true,
197
+ };
198
+ }
199
+ const mixErr = await checkMixPrecondition(client, "merge_channels_stereo");
200
+ if (mixErr)
201
+ return { content: [{ type: "text", text: mixErr }], isError: true };
202
+ return handleToolCall("merge_channels_stereo", "write", () => client.mergeChannelsStereo(leftIndex, rightIndex), client);
203
+ });
204
+ server.tool("split_stereo_channel", `Split a stereo pair back into two mono channels [write].
205
+ ⚠️ This resets both channel pan values and disables M/S processing. Explicit user confirmation is required.`, {
206
+ leftIndex: z.number().int().min(0).max(255).describe("Left channel index (0-based)"),
207
+ rightIndex: z.number().int().min(0).max(255).describe("Right channel index (0-based)"),
208
+ }, async ({ leftIndex, rightIndex }) => {
209
+ const mixErr = await checkMixPrecondition(client, "split_stereo_channel");
210
+ if (mixErr)
211
+ return { content: [{ type: "text", text: mixErr }], isError: true };
212
+ return handleToolCall("split_stereo_channel", "write", () => client.splitStereoChannel(leftIndex, rightIndex), client);
213
+ });
214
+ // ===== 监听音量独立控制 =====
215
+ server.tool("set_monitor_volume", `Set monitor volume independently [write].
216
+ ⚠️ This changes monitoring engine output volume and requires explicit user confirmation.
217
+ Note: this tool adjusts only volume, not pan.
218
+ Range is 0.0 to 2.0, where 1.0 = 0 dB (unity gain) and 2.0 = +6 dB.
219
+ Common values: 0.0 = mute, 0.5 ≈ -6 dB, 1.0 = 0 dB, 1.5 ≈ +3.5 dB, 2.0 = +6 dB.`, {
220
+ volume: z
221
+ .number()
222
+ .min(0)
223
+ .max(2)
224
+ .describe("Monitor volume (0.0 - 2.0, 1.0 = 0 dB)"),
225
+ }, async ({ volume }) => {
226
+ const mixErr = await checkMixPrecondition(client, "set_monitor_volume");
227
+ if (mixErr)
228
+ return { content: [{ type: "text", text: mixErr }], isError: true };
229
+ return handleToolCall("set_monitor_volume", "write", () => client.setMasterVolume(volume), client);
230
+ });
231
+ }
232
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/tools/monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 录音控制 Tools — 分场景查询与录音停止
3
+ * Recording Control Tools — Scene-specific queries and recording stop
4
+ *
5
+ * 设计原则:
6
+ * - 会话初始化和开始录音必须在 GUI 手动完成(DADAO Engine 安全架构)
7
+ * - MCP 仅提供状态查询、停止录音等辅助操作
8
+ * - 查询按场景拆分,返回最小数据集,减少 token 消耗
9
+ */
10
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
+ export declare function registerRecordingTools(server: McpServer): void;
12
+ //# sourceMappingURL=recording.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording.d.ts","sourceRoot":"","sources":["../../src/tools/recording.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QAwHvD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * 录音控制 Tools — 分场景查询与录音停止
3
+ * Recording Control Tools — Scene-specific queries and recording stop
4
+ *
5
+ * 设计原则:
6
+ * - 会话初始化和开始录音必须在 GUI 手动完成(DADAO Engine 安全架构)
7
+ * - MCP 仅提供状态查询、停止录音等辅助操作
8
+ * - 查询按场景拆分,返回最小数据集,减少 token 消耗
9
+ */
10
+ import { z } from "zod";
11
+ import { RecordSaferClient } from "../api-client.js";
12
+ import { handleToolCall } from "../utils.js";
13
+ export function registerRecordingTools(server) {
14
+ const client = new RecordSaferClient();
15
+ // ===== 场景 1: 通道列表(改名场景) =====
16
+ server.tool("get_channels", `Get channel list for rename operations [read].
17
+
18
+ Use this for renaming and channel inspection. Returns a minimal payload:
19
+ {
20
+ ready: true, // session initialized and on recording console
21
+ recording: true, // recording active
22
+ deviceName: "Schoeps BLC",
23
+ channels: [
24
+ {id: 1, name: "Kick", deviceChannelLabel: "ADAT 1"},
25
+ {id: 2, name: "Snare", deviceChannelLabel: "ADAT 2"}
26
+ ]
27
+ }
28
+
29
+ If ready is false, instruct the user to complete setup and enter the recording console in Record Safer Pro.`, {}, async () => handleToolCall("get_channels", "read", () => client.getMcpChannels(), client));
30
+ // ===== 场景 2: 混音状态(调音量/pan 场景) =====
31
+ server.tool("get_mix", `Get mix state for volume/pan operations [read].
32
+
33
+ Call before volume/pan/mute/solo/phase-invert operations. Returns:
34
+ {
35
+ ready: true,
36
+ recording: false,
37
+ safeMode: true, // safe mode recording (monitoring/mixing/metering disabled)
38
+ channels: [
39
+ {id: 1, name: "Kick", volume: 1.0, pan: 0.0, mute: false, solo: false, phaseInvert: false}
40
+ ]
41
+ }
42
+
43
+ Safe-mode rule: monitoring, mixing, and level metering are disabled during recording.`, {}, async () => handleToolCall("get_mix", "read", () => client.getMcpMix(), client));
44
+ // ===== 场景 3: 系统健康(监控场景) =====
45
+ server.tool("get_health", `Get system health for monitoring [read].
46
+
47
+ Use this for monitoring and troubleshooting. Returns:
48
+ {
49
+ ready: true,
50
+ recording: true,
51
+ duration: 3600.5,
52
+ cpuLoad: 12.5,
53
+ diskFreeGB: 120.5,
54
+ bufferHealth: "excellent", // excellent/good/warning/critical
55
+ deviceAlive: true,
56
+ safeMode: false,
57
+ alerts: ["device_disconnected", "sample_rate_changed"]
58
+ }`, {}, async () => handleToolCall("get_health", "read", () => client.getMcpHealth(), client));
59
+ // ===== 场景 4: 最小状态(标记等轻量操作场景) =====
60
+ server.tool("get_status", `Get minimal recording status [read].
61
+
62
+ Use this for quick checks before actions like add_marker or stop_recording. Returns:
63
+ { ready: true, recording: true, duration: 3600.5 }
64
+
65
+ If ready is false, tell the user:
66
+ "Due to the DADAO Engine safety architecture, session initialization and recording start must be done manually in the Record Safer Pro GUI. Please complete setup and enter the recording console first."`, {}, async () => handleToolCall("get_status", "read", () => client.getMcpStatus(), client));
67
+ // ===== 完整录音状态(向后兼容) =====
68
+ server.tool("get_recording_status", `Get full recording status [read].
69
+ Returns the full backend payload (including sessionConfig, deviceHealth, powerStatus, and all other fields).
70
+ Prefer scene-specific tools (get_channels / get_mix / get_health / get_status) for routine queries.`, {}, async () => handleToolCall("get_recording_status", "read", () => client.getRecordingStatus(), client));
71
+ // ===== 会话重置 =====
72
+ server.tool("reset_session", "Reset current session [recording_control]. ⚠️ This clears current session configuration and requires explicit user confirmation.", {}, async () => handleToolCall("reset_session", "recording_control", () => client.resetSession(), client));
73
+ // ===== 停止录音 =====
74
+ server.tool("stop_recording", `Stop recording [recording_control].
75
+ ⚠️ This stops the current recording and closes output audio files. Explicit user confirmation is required.
76
+ Returns duration, file list, and total file size.
77
+
78
+ Safety rules:
79
+ - User intent to stop must be explicit in the current message.
80
+ - For ambiguous intent, ask for confirmation first.
81
+ - Never call this tool without a clear stop instruction.`, {
82
+ userConfirmed: z.boolean().describe("Must be true only after the user explicitly confirms stopping the active recording"),
83
+ }, async ({ userConfirmed }) => handleToolCall("stop_recording", "recording_control", () => client.stopRecording({ userConfirmed }), client));
84
+ }
85
+ //# sourceMappingURL=recording.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording.js","sourceRoot":"","sources":["../../src/tools/recording.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAEvC,+BAA+B;IAC/B,MAAM,CAAC,IAAI,CACT,cAAc,EACd;;;;;;;;;;;;;4GAawG,EACxG,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,CAAC,CAChF,CAAC;IAEF,qCAAqC;IACrC,MAAM,CAAC,IAAI,CACT,SAAS,EACT;;;;;;;;;;;;sFAYkF,EAClF,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CACtE,CAAC;IAEF,+BAA+B;IAC/B,MAAM,CAAC,IAAI,CACT,YAAY,EACZ;;;;;;;;;;;;;IAaA,EACA,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAC5E,CAAC;IAEF,oCAAoC;IACpC,MAAM,CAAC,IAAI,CACT,YAAY,EACZ;;;;;;0MAMsM,EACtM,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAC5E,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB;;oGAEgG,EAChG,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,sBAAsB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,MAAM,CAAC,CAC5F,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,kIAAkI,EAClI,EAAE,EACF,KAAK,IAAI,EAAE,CACT,cAAc,CAAC,eAAe,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAC5F,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB;;;;;;;yDAOqD,EACrD;QACE,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oFAAoF,CAAC;KAC1H,EACD,KAAK,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAC1B,cAAc,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,CAAC,CAC/G,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 配置管理 Tools — 输出路径、音频格式、系统设置
3
+ * Settings Management Tools — Output path, audio format, system settings
4
+ *
5
+ * 这些工具无前置依赖,随时可调用。
6
+ * 但注意:修改配置不会影响已初始化的会话,需要重新初始化才能生效。
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ export declare function registerSettingsTools(server: McpServer): void;
10
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/tools/settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAgFtD"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 配置管理 Tools — 输出路径、音频格式、系统设置
3
+ * Settings Management Tools — Output path, audio format, system settings
4
+ *
5
+ * 这些工具无前置依赖,随时可调用。
6
+ * 但注意:修改配置不会影响已初始化的会话,需要重新初始化才能生效。
7
+ */
8
+ import { z } from "zod";
9
+ import { RecordSaferClient } from "../api-client.js";
10
+ import { handleToolCall } from "../utils.js";
11
+ export function registerSettingsTools(server) {
12
+ const client = new RecordSaferClient();
13
+ const settingsUpdateSchema = z.object({
14
+ audioFormat: z.enum(["wav", "caf"]).optional(),
15
+ showLevelMeterDuringRecording: z.boolean().optional(),
16
+ levelMeterBufferSize: z.number().int().positive().optional(),
17
+ levelMeterBallistics: z.string().optional(),
18
+ monitoringEnabled: z.boolean().optional(),
19
+ telemetryConsent: z.boolean().optional(),
20
+ bitDepth: z.enum(["16-bit", "24-bit", "32-bit Float"]).optional(),
21
+ isConfigured: z.boolean().optional(),
22
+ monitorOutputDeviceId: z.string().optional(),
23
+ }).passthrough().refine((settings) => Object.keys(settings).length > 0, { message: "At least one setting update is required" });
24
+ server.tool("get_output_path", "Get current output directory [read]. Returns the persisted output path together with free-space and isSet status when available.", {}, async () => handleToolCall("get_output_path", "read", () => client.getOutputPath(), client));
25
+ server.tool("set_output_path", `Set output directory [write].
26
+ ⚠️ This changes the recording file destination and requires explicit user confirmation.
27
+ Note: takes effect for future recordings after session re-initialization.`, {
28
+ path: z.string().min(1).describe("Output path"),
29
+ }, async ({ path }) => handleToolCall("set_output_path", "write", () => client.setOutputPath(path), client));
30
+ server.tool("get_audio_format", "Get current audio file format [read]. Returns the persisted container format (wav/caf) and file extension; sample rate and bit depth are resolved elsewhere.", {}, async () => handleToolCall("get_audio_format", "read", () => client.getAudioFormat(), client));
31
+ server.tool("set_audio_format", `Set audio format [write].
32
+ ⚠️ This changes recording format parameters and requires explicit user confirmation.
33
+ Note: takes effect for future recordings after session re-initialization.`, {
34
+ format: z.enum(["wav", "caf"]).optional(),
35
+ sampleRate: z.number().optional(),
36
+ bitDepth: z.enum(["16-bit", "24-bit", "32-bit Float"]).optional(),
37
+ }, async ({ format, sampleRate, bitDepth }) => handleToolCall("set_audio_format", "write", () => client.setAudioFormat({ format, sampleRate, bitDepth }), client));
38
+ server.tool("get_settings", "Get persisted system settings [read]. Returns the application settings object stored by the desktop app.", {}, async () => handleToolCall("get_settings", "read", () => client.getSettings(), client));
39
+ server.tool("update_settings", "Update system settings [write]. ⚠️ This modifies persisted application settings and requires explicit user confirmation. MCP merges your partial update with the current settings before sending it to the backend because the backend expects a complete settings object.", {
40
+ settings: settingsUpdateSchema.describe("Partial settings update to merge with the current backend settings"),
41
+ }, async ({ settings }) => handleToolCall("update_settings", "write", () => client.updateSettings(settings), client));
42
+ }
43
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/tools/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 存储管理 Tools — 存储卷、外部驱动器、路径验证与锁定
3
+ * Storage Management Tools — Volumes, external drives, path validation and locking
4
+ *
5
+ * 查询类工具无前置依赖,随时可调用。
6
+ * 锁定/解锁需要在录音控制台中。
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ export declare function registerStorageTools(server: McpServer): void;
10
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/tools/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QA6CrD"}