@avclabs.ai/media-mcp 0.2.1 → 0.3.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/dist/sam3.js CHANGED
@@ -2,12 +2,17 @@ import axios from 'axios';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { z } from 'zod';
5
- import FormData from 'form-data';
5
+ import { checkLocalFile, decodeBase64Image, downloadToBuffer, parseTosSignature, unwrapEnvelope, uploadToTos, } from './tos.js';
6
+ import { classifyStatus, POLL_REQUEST_TIMEOUT_MS, pollUntilTerminal, registerTool } from './tooling.js';
7
+ const SAM3_SUCCESS_CODES = new Set([0]);
6
8
  const Sam3PredictSchema = z.object({
7
9
  imagePath: z.string().optional().describe('Absolute path of a local image file (e.g. C:\\\\Users\\\\xxx\\\\photo.png)'),
8
10
  imageUrl: z.string().url().optional().describe('Publicly accessible URL of the image to process'),
9
- imageBase64: z.string().optional().describe('Base64-encoded image data. Use this when the image is provided as an attachment without a local path'),
10
- prompt: z.string().describe('Text prompt for mask generation. Must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool'),
11
+ imageBase64: z.string().optional().describe('Base64-encoded image data (a data: URL prefix is also accepted). Use this when the image is provided as an attachment without a local path'),
12
+ prompt: z.string().min(1).max(500).describe('Text prompt for mask generation. Must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool'),
13
+ });
14
+ const GetSam3TaskStatusSchema = z.object({
15
+ task_id: z.string().describe('SAM3 task ID returned by sam3_predict'),
11
16
  });
12
17
  export function setupSam3Tools(server, baseUrl, apiKey, pollInterval, pollMaxAttempts) {
13
18
  const client = axios.create({
@@ -18,150 +23,189 @@ export function setupSam3Tools(server, baseUrl, apiKey, pollInterval, pollMaxAtt
18
23
  },
19
24
  timeout: 60000,
20
25
  });
21
- server.tool('sam3_predict', `Analyze an image using the SAM3 segmentation API to generate inference results (masks, boxes, scores).
26
+ registerTool(server, 'sam3_predict', `Analyze an image using the SAM3 segmentation API to generate inference results (masks, boxes, scores).
22
27
  The image can be provided in one of three ways:
23
28
  1. imagePath: Absolute path of a local image file (e.g. C:\\Users\\xxx\\photo.png). Use this when the user provides a local file path.
24
29
  2. imageUrl: Publicly accessible URL of the image (e.g. https://example.com/photo.jpg). Use this when the user provides a web link.
25
30
  3. imageBase64: Base64-encoded image data. Use this when the user uploads or drags-and-drops an image as an attachment and no local path is available.
26
31
  In this case, encode the image content as base64 and pass it via this parameter.
27
32
  If the user mentions an uploaded image but does not provide a path, URL, or base64 data, ask the user for the local absolute path.
28
- Prompt must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool.`, Sam3PredictSchema.shape, async (args) => {
33
+ Prompt must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool.`, Sam3PredictSchema.shape, async (args) => sam3PredictTool(client, pollInterval, pollMaxAttempts, args));
34
+ registerTool(server, 'get_sam3_task_status', 'Query SAM3 image segmentation task status by task_id. Status can be: processing, completed, or failed. If completed, the result URL is returned.', GetSam3TaskStatusSchema.shape, async (args) => {
29
35
  try {
30
- if (!apiKey) {
31
- throw new Error('SAM3 API Key not configured. Please set API_KEY environment variable or --api-key argument.');
32
- }
33
- const result = await sam3PredictTool(client, pollInterval, pollMaxAttempts, args);
34
- return {
35
- content: [{ type: 'text', text: result }],
36
- };
36
+ const data = await getSam3Result(client, args.task_id);
37
+ return normalizeSam3Status(args.task_id, data);
37
38
  }
38
39
  catch (error) {
39
- const errorMessage = error instanceof Error ? error.message : String(error);
40
+ // Keep task_id in every failure exit of the status tool, consistent
41
+ // with the polling failure shape.
40
42
  return {
41
- content: [{ type: 'text', text: JSON.stringify({ success: false, error: errorMessage }, null, 2) }],
43
+ success: false,
44
+ task_id: args.task_id,
45
+ status: 'unknown',
46
+ error: error instanceof Error ? error.message : String(error),
42
47
  };
43
48
  }
44
49
  });
45
50
  }
51
+ function normalizeSam3Status(taskId, data) {
52
+ const kind = classifyStatus(data?.status);
53
+ if (kind === 'ok') {
54
+ return {
55
+ success: true,
56
+ task_id: taskId,
57
+ status: data.status,
58
+ result_url: data.result,
59
+ };
60
+ }
61
+ if (kind === 'failed') {
62
+ return {
63
+ success: false,
64
+ task_id: taskId,
65
+ status: data.status,
66
+ error: data.error_message || 'Task failed',
67
+ };
68
+ }
69
+ if (kind === 'unknown') {
70
+ return {
71
+ success: false,
72
+ task_id: taskId,
73
+ status: data?.status ?? 'unknown',
74
+ error: `Unrecognized task status: ${JSON.stringify(data?.status ?? null)}`,
75
+ };
76
+ }
77
+ return {
78
+ success: true,
79
+ task_id: taskId,
80
+ status: data.status,
81
+ message: 'Task is still processing, please check again later.',
82
+ };
83
+ }
46
84
  async function getSam3PostSignature(client, fileName) {
47
85
  const response = await client.post('/get_postsignature_url', {
48
86
  file_type: 'image',
49
87
  file_name: fileName,
50
88
  });
51
- const data = response.data;
52
- if (data.code !== 0) {
53
- throw new Error(`get_postsignature_url error: ${data.message || 'unknown error'}`);
54
- }
55
- return data.data;
56
- }
57
- async function uploadImageToTos(url, sigData, tosKey, buffer, fileName) {
58
- const formData = new FormData();
59
- formData.append('key', tosKey);
60
- formData.append('policy', sigData.policy);
61
- formData.append('x-tos-algorithm', sigData.algorithm);
62
- formData.append('x-tos-credential', sigData.credential);
63
- formData.append('x-tos-date', sigData.date);
64
- formData.append('x-tos-signature', sigData.signature);
65
- formData.append('file', buffer, fileName);
66
- const response = await axios.post(url, formData, {
67
- headers: formData.getHeaders(),
68
- maxBodyLength: Infinity,
69
- maxContentLength: Infinity,
70
- });
71
- if (response.status >= 400) {
72
- throw new Error(`TOS upload failed: ${response.status} ${response.statusText}`);
89
+ const unwrapped = unwrapEnvelope(response, SAM3_SUCCESS_CODES);
90
+ if (!unwrapped.ok) {
91
+ throw new Error(`get_postsignature_url error: ${unwrapped.error}`);
73
92
  }
93
+ return unwrapped.data;
74
94
  }
75
95
  async function sam3Predict(client, fileId, prompt) {
76
96
  const response = await client.post('/predict', { file_id: fileId, prompt });
77
- return response.data.task_id;
97
+ const body = response.data;
98
+ if (!body || typeof body !== 'object' || typeof body.task_id !== 'string' || !body.task_id) {
99
+ const preview = typeof body === 'string' ? body.slice(0, 200) : JSON.stringify(body)?.slice(0, 200);
100
+ throw new Error(`Unexpected /predict response: ${preview}`);
101
+ }
102
+ return body.task_id;
78
103
  }
79
104
  async function downloadSam3Result(url) {
80
- const response = await axios.get(url);
105
+ const response = await axios.get(url, { timeout: 30000 });
81
106
  return response.data;
82
107
  }
108
+ const SAM3_RESULT_DOWNLOAD_NOTE = 'The task has completed; only the result download failed. Do not resubmit. Use get_sam3_task_status with this task_id to recover the result.';
109
+ /**
110
+ * Last-hop fetch for a completed SAM3 task. Never throws: a download failure
111
+ * becomes a structured object that keeps task_id and the terminal status, so
112
+ * the caller can resume via get_sam3_task_status. A download failure is not
113
+ * a truncated wait and never rewrites the remote status to failed/processing.
114
+ */
115
+ export async function fetchSam3ResultPayload(taskId, resultUrl) {
116
+ if (typeof resultUrl !== 'string' || resultUrl.trim() === '') {
117
+ return {
118
+ success: false,
119
+ task_id: taskId,
120
+ status: 'completed',
121
+ error: `Task ${taskId} completed but has no usable result_url; use get_sam3_task_status with this task_id to recover.`,
122
+ note: SAM3_RESULT_DOWNLOAD_NOTE,
123
+ };
124
+ }
125
+ try {
126
+ const data = await downloadSam3Result(resultUrl);
127
+ return { success: true, task_id: taskId, status: 'completed', result_url: resultUrl, result: data };
128
+ }
129
+ catch (error) {
130
+ const message = error instanceof Error ? error.message : String(error);
131
+ return {
132
+ success: false,
133
+ task_id: taskId,
134
+ status: 'completed',
135
+ result_url: resultUrl,
136
+ error: `Failed to download the completed result for task ${taskId}: ${message}`,
137
+ note: SAM3_RESULT_DOWNLOAD_NOTE,
138
+ };
139
+ }
140
+ }
83
141
  async function prepareImageBuffer(args) {
84
142
  const { imagePath, imageUrl, imageBase64 } = args;
85
- if (!imagePath && !imageUrl && !imageBase64) {
86
- throw new Error('Missing image input: must provide one of imagePath, imageUrl, or imageBase64');
87
- }
88
- let buffer;
89
- let fileName;
90
143
  if (imagePath) {
91
- if (!fs.existsSync(imagePath)) {
92
- throw new Error(`Local file does not exist: ${imagePath}`);
93
- }
94
- fileName = path.basename(imagePath);
95
- buffer = fs.readFileSync(imagePath);
96
- }
97
- else if (imageUrl) {
98
- const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
99
- buffer = Buffer.from(response.data);
100
- fileName = path.basename(new URL(imageUrl).pathname) || 'image.png';
144
+ checkLocalFile(imagePath, 'image');
145
+ return { buffer: fs.readFileSync(imagePath), fileName: path.basename(imagePath) };
101
146
  }
102
- else if (imageBase64) {
103
- buffer = Buffer.from(imageBase64, 'base64');
104
- fileName = 'image.png';
147
+ if (imageUrl) {
148
+ const buffer = await downloadToBuffer(imageUrl);
149
+ const fileName = path.basename(new URL(imageUrl).pathname) || 'image.png';
150
+ return { buffer, fileName };
105
151
  }
106
- else {
107
- throw new Error('Missing image input: must provide one of imagePath, imageUrl, or imageBase64');
152
+ if (imageBase64) {
153
+ return decodeBase64Image(imageBase64);
108
154
  }
109
- return { buffer, fileName };
155
+ throw new Error('Missing image input: must provide one of imagePath, imageUrl, or imageBase64');
110
156
  }
111
157
  async function sam3CreateTask(client, buffer, fileName, prompt) {
112
158
  const signatureData = await getSam3PostSignature(client, fileName);
113
- const { url, origin_policy } = signatureData;
114
- if (!url) {
115
- throw new Error('Missing upload URL in post signature response');
116
- }
117
- const keyObj = JSON.parse(origin_policy).conditions.find((c) => 'key' in c);
118
- const tosKey = keyObj ? keyObj.key : new URL(url).pathname.slice(1);
119
- const fileId = new URL(url).pathname.split('/').pop();
120
- if (!fileId) {
121
- throw new Error('Could not extract file_id from upload URL');
122
- }
123
- await uploadImageToTos(url, signatureData, tosKey, buffer, fileName);
124
- const taskId = await sam3Predict(client, fileId, prompt);
125
- return taskId;
126
- }
127
- async function getSam3Result(client, taskId) {
128
- const response = await client.get(`/predict/result/${encodeURIComponent(taskId)}`);
129
- return response.data;
159
+ const target = parseTosSignature(signatureData);
160
+ await uploadToTos(target, buffer, fileName);
161
+ return sam3Predict(client, target.fileId, prompt);
130
162
  }
131
- async function getSam3PredictResult(client, taskId, pollInterval, pollMaxAttempts) {
132
- for (let attempt = 0; attempt < pollMaxAttempts; attempt++) {
133
- const data = await getSam3Result(client, taskId);
134
- if (data.status === 'completed') {
135
- return data;
136
- }
137
- if (data.status === 'failed') {
138
- throw new Error(`Task failed: ${data.error_message || 'unknown error'}`);
163
+ async function getSam3Result(client, taskId, signal) {
164
+ const response = await client.get(`/predict/result/${encodeURIComponent(taskId)}`, {
165
+ timeout: POLL_REQUEST_TIMEOUT_MS,
166
+ signal,
167
+ });
168
+ const data = response.data;
169
+ if (!data || typeof data !== 'object' || Array.isArray(data)) {
170
+ throw new Error(`Unexpected task status response (HTTP ${response.status})`);
171
+ }
172
+ // The endpoint's success body shape is not confirmed against a live backend
173
+ // (envelope {code:0,data:{...}} or bare {status,...}); unwrap only when the
174
+ // body is shaped like an envelope, so auth/business errors surface with
175
+ // their real message instead of degrading to "Unrecognized task status".
176
+ if ('code' in data) {
177
+ const unwrapped = unwrapEnvelope(response, SAM3_SUCCESS_CODES);
178
+ if (!unwrapped.ok) {
179
+ throw new Error(`Task status request failed: ${unwrapped.error}`);
139
180
  }
140
- await sleep(pollInterval);
181
+ return unwrapped.data;
141
182
  }
142
- return {
143
- success: true,
144
- status: 'processing',
145
- task_id: taskId,
146
- message: `Task is still processing (waited about ${Math.round(pollMaxAttempts * pollInterval / 1000)} seconds). Please retry later or record this task_id for manual follow-up.`,
147
- note: 'The synchronous wait for this long-running task has been truncated.',
148
- };
183
+ return data;
149
184
  }
150
185
  async function sam3PredictTool(client, pollInterval, pollMaxAttempts, args) {
151
- if (!args.prompt) {
152
- throw new Error('Missing argument: prompt');
153
- }
154
186
  const { buffer, fileName } = await prepareImageBuffer(args);
155
187
  const taskId = await sam3CreateTask(client, buffer, fileName, args.prompt);
156
- const taskResult = await getSam3PredictResult(client, taskId, pollInterval, pollMaxAttempts);
157
- if (taskResult.success === true && taskResult.status === 'processing') {
158
- return JSON.stringify(taskResult, null, 2);
188
+ const taskResult = await pollUntilTerminal({
189
+ taskId,
190
+ timeoutSeconds: (pollInterval * pollMaxAttempts) / 1000,
191
+ pollIntervalSeconds: pollInterval / 1000,
192
+ maxAttempts: pollMaxAttempts,
193
+ continueHint: 'get_sam3_task_status',
194
+ fetchStatus: async (signal) => {
195
+ const data = await getSam3Result(client, taskId, signal);
196
+ return {
197
+ status: data.status,
198
+ payload: { result_url: data.result, error_message: data.error_message },
199
+ };
200
+ },
201
+ });
202
+ if (!taskResult.success || taskResult.status === 'processing') {
203
+ return taskResult;
159
204
  }
160
- const resultUrl = taskResult.result;
161
- const resultJson = await downloadSam3Result(resultUrl);
162
- return JSON.stringify(resultJson, null, 2);
163
- }
164
- function sleep(ms) {
165
- return new Promise((resolve) => setTimeout(resolve, ms));
205
+ const outcome = await fetchSam3ResultPayload(taskResult.task_id, taskResult.result_url);
206
+ if (!outcome.success) {
207
+ return outcome;
208
+ }
209
+ return JSON.stringify(outcome.result, null, 2);
166
210
  }
167
211
  //# sourceMappingURL=sam3.js.map
package/dist/sam3.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sam3.js","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sam3.js","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * MCP Server - Video enhancement and SAM3 image segmentation
3
+ * MCP Server - Video enhancement, image enhancement/colorization/denoising, and SAM3 image segmentation
4
4
  */
5
5
  export {};
6
6
  //# sourceMappingURL=server.d.ts.map
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * MCP Server - Video enhancement and SAM3 image segmentation
3
+ * MCP Server - Video enhancement, image enhancement/colorization/denoising, and SAM3 image segmentation
4
4
  */
5
5
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
6
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -8,67 +8,89 @@ import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
  import { fileURLToPath } from 'url';
10
10
  import { setupVideoEnhancementTools } from './video-enhancement.js';
11
+ import { setupImageEnhancementTools } from './image-enhancement.js';
11
12
  import { setupSam3Tools } from './sam3.js';
13
+ import { resolveMediaHostConfig } from './service-config.js';
12
14
  const __filename = fileURLToPath(import.meta.url);
13
15
  const __dirname = path.dirname(__filename);
14
- function loadConfig() {
15
- const configPaths = [
16
- path.resolve(process.cwd(), 'config.json'),
17
- path.resolve(__dirname, '..', 'config.json'),
18
- ];
19
- for (const configPath of configPaths) {
20
- if (fs.existsSync(configPath)) {
21
- try {
22
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
23
- return {
24
- baseUrl: config.baseUrl || 'https://mcp.avc.ai/enhance',
25
- sam3BaseUrl: config.sam3BaseUrl || 'https://mcp.avc.ai/sam',
26
- };
27
- }
28
- catch {
29
- continue;
30
- }
31
- }
16
+ function parseConfigFile(configPath) {
17
+ let raw;
18
+ try {
19
+ raw = fs.readFileSync(configPath, 'utf-8');
20
+ }
21
+ catch (error) {
22
+ console.error(`Error: cannot read config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
23
+ process.exit(1);
24
+ }
25
+ let config;
26
+ try {
27
+ config = JSON.parse(raw);
28
+ }
29
+ catch (error) {
30
+ console.error(`Error: config file ${configPath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
31
+ process.exit(1);
32
+ }
33
+ // Absent keys stay undefined; defaults are applied by resolveMediaHostConfig.
34
+ return {
35
+ baseUrl: typeof config.baseUrl === 'string' ? config.baseUrl : undefined,
36
+ imageBaseUrl: typeof config.imageBaseUrl === 'string' ? config.imageBaseUrl : undefined,
37
+ sam3BaseUrl: typeof config.sam3BaseUrl === 'string' ? config.sam3BaseUrl : undefined,
38
+ };
39
+ }
40
+ function loadConfig(explicitConfigPath) {
41
+ if (explicitConfigPath) {
42
+ const resolved = path.resolve(explicitConfigPath);
43
+ console.error(`Using config file: ${resolved}`);
44
+ return parseConfigFile(resolved);
45
+ }
46
+ // Only the config bundled with the package is considered; a config.json in
47
+ // the caller's working directory must never silently redirect API traffic.
48
+ const bundledPath = path.resolve(__dirname, '..', 'config.json');
49
+ if (fs.existsSync(bundledPath)) {
50
+ return parseConfigFile(bundledPath);
51
+ }
52
+ return {};
53
+ }
54
+ // Collect CLI values without consulting the environment; precedence between
55
+ // layers is resolved by resolveMediaHostConfig.
56
+ function parseCliOverrides(args) {
57
+ const overrides = {};
58
+ for (let i = 0; i < args.length; i++) {
59
+ const takeValue = (key) => {
60
+ overrides[key] = args[i + 1];
61
+ i++;
62
+ };
63
+ if (args[i] === '--base-url' && i + 1 < args.length)
64
+ takeValue('baseUrl');
65
+ else if (args[i] === '--image-base-url' && i + 1 < args.length)
66
+ takeValue('imageBaseUrl');
67
+ else if (args[i] === '--api-key' && i + 1 < args.length)
68
+ takeValue('apiKey');
69
+ else if (args[i] === '--sam3-base-url' && i + 1 < args.length)
70
+ takeValue('sam3BaseUrl');
71
+ else if (args[i] === '--sam3-poll-interval' && i + 1 < args.length)
72
+ takeValue('sam3PollIntervalMs');
73
+ else if (args[i] === '--sam3-poll-max-attempts' && i + 1 < args.length)
74
+ takeValue('sam3PollMaxAttempts');
32
75
  }
33
- return { baseUrl: 'https://mcp.avc.ai/enhance', sam3BaseUrl: 'https://mcp.avc.ai/sam' };
76
+ return overrides;
34
77
  }
35
78
  // Main entry
36
79
  async function main() {
37
80
  const args = process.argv.slice(2);
38
- const config = loadConfig();
39
- let baseUrl = process.env.HTTP_API_BASE_URL || config.baseUrl;
40
- let apiKey = process.env.API_KEY || '';
41
- let sam3BaseUrl = process.env.SAM3_API_BASE_URL || config.sam3BaseUrl;
42
- let sam3ApiKey = apiKey;
43
- let sam3PollInterval = parseInt(process.env.SAM3_POLL_INTERVAL || '2000', 10);
44
- let sam3PollMaxAttempts = parseInt(process.env.SAM3_POLL_MAX_ATTEMPTS || '25', 10);
45
- // Parse command line arguments
81
+ let explicitConfigPath;
46
82
  for (let i = 0; i < args.length; i++) {
47
- if (args[i] === '--base-url' && i + 1 < args.length) {
48
- baseUrl = args[i + 1];
49
- i++;
50
- }
51
- else if (args[i] === '--api-key' && i + 1 < args.length) {
52
- apiKey = args[i + 1];
53
- i++;
54
- }
55
- else if (args[i] === '--sam3-base-url' && i + 1 < args.length) {
56
- sam3BaseUrl = args[i + 1];
57
- i++;
83
+ if (args[i] === '--config' && i + 1 < args.length) {
84
+ explicitConfigPath = args[i + 1];
85
+ break;
58
86
  }
59
- else if (args[i] === '--sam3-poll-interval' && i + 1 < args.length) {
60
- sam3PollInterval = parseInt(args[i + 1], 10);
61
- i++;
62
- }
63
- else if (args[i] === '--sam3-poll-max-attempts' && i + 1 < args.length) {
64
- sam3PollMaxAttempts = parseInt(args[i + 1], 10);
65
- i++;
66
- }
67
- }
68
- if (!apiKey) {
69
- console.error('Error: --api-key argument or API_KEY environment variable is required');
70
- process.exit(1);
71
87
  }
88
+ const fileConfig = loadConfig(explicitConfigPath);
89
+ // SAM3's sync wait is bounded by two independent limits derived from its
90
+ // config: at most SAM3_POLL_MAX_ATTEMPTS status queries and a time budget of
91
+ // interval x attempts (default 25 x 2000 ms = 50 s). Whichever runs out
92
+ // first truncates the wait; the task keeps running remotely either way.
93
+ const hostConfig = resolveMediaHostConfig({ cli: parseCliOverrides(args), env: process.env, file: fileConfig });
72
94
  const server = new McpServer({
73
95
  name: 'media-mcp',
74
96
  version: '0.3.0',
@@ -78,9 +100,11 @@ async function main() {
78
100
  },
79
101
  });
80
102
  // Register video enhancement tools
81
- setupVideoEnhancementTools(server, baseUrl, apiKey);
103
+ setupVideoEnhancementTools(server, hostConfig.enhancementApiBaseUrl, hostConfig.apiKey);
104
+ // Register image enhancement tools
105
+ setupImageEnhancementTools(server, hostConfig.imageApiBaseUrl, hostConfig.apiKey);
82
106
  // Register SAM3 tools
83
- setupSam3Tools(server, sam3BaseUrl, sam3ApiKey, sam3PollInterval, sam3PollMaxAttempts);
107
+ setupSam3Tools(server, hostConfig.sam3ApiBaseUrl, hostConfig.apiKey, hostConfig.sam3PollIntervalMs, hostConfig.sam3PollMaxAttempts);
84
108
  const transport = new StdioServerTransport();
85
109
  await server.connect(transport);
86
110
  console.error('MCP Server running on stdio');
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ export declare const SAM3_POLL_INTERVAL_MS_BOUNDS: {
2
+ readonly min: 500;
3
+ readonly max: 60000;
4
+ };
5
+ export declare const SAM3_POLL_MAX_ATTEMPTS_BOUNDS: {
6
+ readonly min: 1;
7
+ readonly max: 1000;
8
+ };
9
+ export declare class ConfigError extends Error {
10
+ }
11
+ export interface MediaHostFileConfig {
12
+ baseUrl?: string;
13
+ imageBaseUrl?: string;
14
+ sam3BaseUrl?: string;
15
+ }
16
+ export interface MediaHostCliOverrides {
17
+ baseUrl?: string;
18
+ imageBaseUrl?: string;
19
+ sam3BaseUrl?: string;
20
+ apiKey?: string;
21
+ /** Raw argument text; parsed and bounds-checked here. */
22
+ sam3PollIntervalMs?: string;
23
+ sam3PollMaxAttempts?: string;
24
+ }
25
+ export interface MediaHostEnv {
26
+ API_KEY?: string;
27
+ HTTP_API_BASE_URL?: string;
28
+ IMAGE_API_BASE_URL?: string;
29
+ SAM3_API_BASE_URL?: string;
30
+ /** Canonical name. */
31
+ SAM3_POLL_INTERVAL_MS?: string;
32
+ /** Deprecated alias of SAM3_POLL_INTERVAL_MS. */
33
+ SAM3_POLL_INTERVAL?: string;
34
+ SAM3_POLL_MAX_ATTEMPTS?: string;
35
+ }
36
+ export interface MediaHostConfig {
37
+ enhancementApiBaseUrl: string;
38
+ imageApiBaseUrl: string;
39
+ sam3ApiBaseUrl: string;
40
+ apiKey: string;
41
+ sam3PollIntervalMs: number;
42
+ sam3PollMaxAttempts: number;
43
+ }
44
+ export declare function parseSam3WaitInt(raw: string | undefined, name: string, bounds: {
45
+ min: number;
46
+ max: number;
47
+ }, fallback: number): number;
48
+ /**
49
+ * Resolves the final Media host configuration.
50
+ *
51
+ * Precedence per key: CLI override > environment > file config > built-in
52
+ * default. The image API base URL is derived only after the merge: an unset
53
+ * image base falls back to the resolved enhancement base, no matter which
54
+ * layer provided it. All validation happens here, before any tool is created
55
+ * or request is made; error messages never echo secret values.
56
+ */
57
+ export declare function resolveMediaHostConfig(options: {
58
+ cli?: MediaHostCliOverrides;
59
+ env?: MediaHostEnv;
60
+ file?: MediaHostFileConfig;
61
+ }): MediaHostConfig;
62
+ //# sourceMappingURL=service-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-config.d.ts","sourceRoot":"","sources":["../src/service-config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,4BAA4B;;;CAAoC,CAAC;AAC9E,eAAO,MAAM,6BAA6B;;;CAAiC,CAAC;AAO5E,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAWD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,QAAQ,EAAE,MAAM,GACf,MAAM,CAOR;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC9C,GAAG,CAAC,EAAE,qBAAqB,CAAC;IAC5B,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B,GAAG,eAAe,CAkClB"}