mcp-file-uploader-cli 1.0.0 → 1.0.2
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.js +90 -83
- package/index.ts +107 -101
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -44879,97 +44880,103 @@ class StreamableHTTPServerTransport {
|
|
|
44879
44880
|
var import_express = __toESM(require_express2(), 1);
|
|
44880
44881
|
import fs from "fs";
|
|
44881
44882
|
import path from "path";
|
|
44882
|
-
|
|
44883
|
-
|
|
44884
|
-
|
|
44885
|
-
|
|
44886
|
-
|
|
44887
|
-
|
|
44888
|
-
|
|
44889
|
-
|
|
44890
|
-
|
|
44891
|
-
|
|
44892
|
-
|
|
44893
|
-
|
|
44894
|
-
|
|
44895
|
-
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
|
|
44899
|
-
|
|
44900
|
-
|
|
44901
|
-
|
|
44902
|
-
structuredContent: { success: false, message: "WEB_FILE_UPLOADER_URL environment variable not set" }
|
|
44903
|
-
};
|
|
44904
|
-
}
|
|
44905
|
-
const filePath = path.resolve(process.cwd(), filename);
|
|
44906
|
-
if (!fs.existsSync(filePath)) {
|
|
44907
|
-
return {
|
|
44908
|
-
content: [{ type: "text", text: JSON.stringify({ success: false, message: `File ${filename} not found in current directory` }) }],
|
|
44909
|
-
structuredContent: { success: false, message: `File ${filename} not found in current directory` }
|
|
44910
|
-
};
|
|
44911
|
-
}
|
|
44912
|
-
try {
|
|
44913
|
-
const fileBuffer = fs.readFileSync(filePath);
|
|
44914
|
-
const blob = new Blob([fileBuffer]);
|
|
44915
|
-
const formData = new FormData;
|
|
44916
|
-
formData.append("file", blob, path.basename(filename));
|
|
44917
|
-
const response = await fetch(`${uploaderUrl}/upload`, {
|
|
44918
|
-
method: "POST",
|
|
44919
|
-
body: formData
|
|
44920
|
-
});
|
|
44921
|
-
if (response.ok) {
|
|
44922
|
-
const result = await response.json();
|
|
44923
|
-
const fullDownloadUrl = `${uploaderUrl}${result.download_url}`;
|
|
44883
|
+
try {
|
|
44884
|
+
console.error("Initializing MCP server...");
|
|
44885
|
+
const server = new McpServer({
|
|
44886
|
+
name: "file-uploader-mcp",
|
|
44887
|
+
version: "1.0.0"
|
|
44888
|
+
});
|
|
44889
|
+
server.registerTool("upload_file", {
|
|
44890
|
+
title: "File Upload Tool",
|
|
44891
|
+
description: "Upload a file from the current working directory to the web file uploader service",
|
|
44892
|
+
inputSchema: exports_external2.object({
|
|
44893
|
+
filename: exports_external2.string()
|
|
44894
|
+
}),
|
|
44895
|
+
outputSchema: exports_external2.object({
|
|
44896
|
+
success: exports_external2.boolean(),
|
|
44897
|
+
message: exports_external2.string(),
|
|
44898
|
+
downloadUrl: exports_external2.string().optional()
|
|
44899
|
+
})
|
|
44900
|
+
}, async ({ filename }) => {
|
|
44901
|
+
const uploaderUrl = process.env.WEB_FILE_UPLOADER_URL;
|
|
44902
|
+
if (!uploaderUrl) {
|
|
44924
44903
|
return {
|
|
44925
|
-
content: [{ type: "text", text: JSON.stringify({ success:
|
|
44926
|
-
structuredContent: { success:
|
|
44904
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, message: "WEB_FILE_UPLOADER_URL environment variable not set" }) }],
|
|
44905
|
+
structuredContent: { success: false, message: "WEB_FILE_UPLOADER_URL environment variable not set" }
|
|
44927
44906
|
};
|
|
44928
|
-
}
|
|
44929
|
-
|
|
44907
|
+
}
|
|
44908
|
+
const filePath = path.resolve(process.cwd(), filename);
|
|
44909
|
+
if (!fs.existsSync(filePath)) {
|
|
44930
44910
|
return {
|
|
44931
|
-
content: [{ type: "text", text: JSON.stringify({ success: false, message: `
|
|
44932
|
-
structuredContent: { success: false, message: `
|
|
44911
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, message: `File ${filename} not found in current directory` }) }],
|
|
44912
|
+
structuredContent: { success: false, message: `File ${filename} not found in current directory` }
|
|
44933
44913
|
};
|
|
44934
44914
|
}
|
|
44935
|
-
} catch (error) {
|
|
44936
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
44937
|
-
return {
|
|
44938
|
-
content: [{ type: "text", text: JSON.stringify({ success: false, message: `Upload error: ${errorMessage}` }) }],
|
|
44939
|
-
structuredContent: { success: false, message: `Upload error: ${errorMessage}` }
|
|
44940
|
-
};
|
|
44941
|
-
}
|
|
44942
|
-
});
|
|
44943
|
-
var useHttp = process.argv.includes("--http");
|
|
44944
|
-
if (useHttp) {
|
|
44945
|
-
const app = import_express.default();
|
|
44946
|
-
app.use(import_express.default.json());
|
|
44947
|
-
app.post("/mcp", async (req, res) => {
|
|
44948
44915
|
try {
|
|
44949
|
-
const
|
|
44950
|
-
|
|
44951
|
-
|
|
44952
|
-
|
|
44953
|
-
|
|
44954
|
-
|
|
44916
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
44917
|
+
const blob = new Blob([fileBuffer]);
|
|
44918
|
+
const formData = new FormData;
|
|
44919
|
+
formData.append("file", blob, path.basename(filename));
|
|
44920
|
+
const response = await fetch(`${uploaderUrl}/upload`, {
|
|
44921
|
+
method: "POST",
|
|
44922
|
+
body: formData
|
|
44955
44923
|
});
|
|
44956
|
-
|
|
44957
|
-
|
|
44924
|
+
if (response.ok) {
|
|
44925
|
+
const result = await response.json();
|
|
44926
|
+
const fullDownloadUrl = `${uploaderUrl}${result.download_url}`;
|
|
44927
|
+
return {
|
|
44928
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, message: result.message, downloadUrl: fullDownloadUrl }) }],
|
|
44929
|
+
structuredContent: { success: true, message: result.message, downloadUrl: fullDownloadUrl }
|
|
44930
|
+
};
|
|
44931
|
+
} else {
|
|
44932
|
+
const errorText = await response.text();
|
|
44933
|
+
return {
|
|
44934
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, message: `Upload failed: ${errorText}` }) }],
|
|
44935
|
+
structuredContent: { success: false, message: `Upload failed: ${errorText}` }
|
|
44936
|
+
};
|
|
44937
|
+
}
|
|
44958
44938
|
} catch (error) {
|
|
44959
|
-
|
|
44960
|
-
|
|
44939
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
44940
|
+
return {
|
|
44941
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, message: `Upload error: ${errorMessage}` }) }],
|
|
44942
|
+
structuredContent: { success: false, message: `Upload error: ${errorMessage}` }
|
|
44943
|
+
};
|
|
44961
44944
|
}
|
|
44962
44945
|
});
|
|
44963
|
-
const
|
|
44964
|
-
|
|
44965
|
-
|
|
44966
|
-
|
|
44967
|
-
|
|
44968
|
-
|
|
44969
|
-
|
|
44970
|
-
|
|
44971
|
-
|
|
44972
|
-
|
|
44973
|
-
|
|
44974
|
-
|
|
44946
|
+
const useHttp = process.argv.includes("--http");
|
|
44947
|
+
if (useHttp) {
|
|
44948
|
+
const app = import_express.default();
|
|
44949
|
+
app.use(import_express.default.json());
|
|
44950
|
+
app.post("/mcp", async (req, res) => {
|
|
44951
|
+
try {
|
|
44952
|
+
const transport = new StreamableHTTPServerTransport({
|
|
44953
|
+
sessionIdGenerator: undefined,
|
|
44954
|
+
enableJsonResponse: true
|
|
44955
|
+
});
|
|
44956
|
+
res.on("close", () => {
|
|
44957
|
+
transport.close();
|
|
44958
|
+
});
|
|
44959
|
+
await server.connect(transport);
|
|
44960
|
+
await transport.handleRequest(req, res, req.body);
|
|
44961
|
+
} catch (error) {
|
|
44962
|
+
console.error("HTTP Transport error:", error);
|
|
44963
|
+
res.status(500).json({ error: "Internal server error" });
|
|
44964
|
+
}
|
|
44965
|
+
});
|
|
44966
|
+
const port = parseInt(process.env.PORT || "3000");
|
|
44967
|
+
app.listen(port, () => {
|
|
44968
|
+
console.log(`MCP HTTP Server running on http://localhost:${port}/mcp`);
|
|
44969
|
+
console.log(`Test with: npx @modelcontextprotocol/inspector http://localhost:${port}/mcp`);
|
|
44970
|
+
}).on("error", (error) => {
|
|
44971
|
+
console.error("Server error:", error);
|
|
44972
|
+
process.exit(1);
|
|
44973
|
+
});
|
|
44974
|
+
} else {
|
|
44975
|
+
const transport = new StdioServerTransport;
|
|
44976
|
+
await server.connect(transport);
|
|
44977
|
+
console.error("MCP Server started and listening on stdio");
|
|
44978
|
+
}
|
|
44979
|
+
} catch (error) {
|
|
44980
|
+
console.error("Application startup error:", error);
|
|
44981
|
+
process.exit(1);
|
|
44975
44982
|
}
|
package/index.ts
CHANGED
|
@@ -12,120 +12,126 @@ interface UploadResponse {
|
|
|
12
12
|
download_url: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// 註冊檔案上傳工具
|
|
22
|
-
server.registerTool(
|
|
23
|
-
'upload_file',
|
|
24
|
-
{
|
|
25
|
-
title: 'File Upload Tool',
|
|
26
|
-
description: 'Upload a file from the current working directory to the web file uploader service',
|
|
27
|
-
inputSchema: z.object({
|
|
28
|
-
filename: z.string(),
|
|
29
|
-
}),
|
|
30
|
-
outputSchema: z.object({
|
|
31
|
-
success: z.boolean(),
|
|
32
|
-
message: z.string(),
|
|
33
|
-
downloadUrl: z.string().optional(),
|
|
34
|
-
}),
|
|
35
|
-
},
|
|
36
|
-
async ({ filename }) => {
|
|
37
|
-
const uploaderUrl = process.env.WEB_FILE_UPLOADER_URL;
|
|
38
|
-
if (!uploaderUrl) {
|
|
39
|
-
return {
|
|
40
|
-
content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'WEB_FILE_UPLOADER_URL environment variable not set' }) }],
|
|
41
|
-
structuredContent: { success: false, message: 'WEB_FILE_UPLOADER_URL environment variable not set' }
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const filePath = path.resolve(process.cwd(), filename);
|
|
46
|
-
if (!fs.existsSync(filePath)) {
|
|
47
|
-
return {
|
|
48
|
-
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `File ${filename} not found in current directory` }) }],
|
|
49
|
-
structuredContent: { success: false, message: `File ${filename} not found in current directory` }
|
|
50
|
-
};
|
|
51
|
-
}
|
|
15
|
+
try {
|
|
16
|
+
console.error('Initializing MCP server...');
|
|
17
|
+
const server = new McpServer({
|
|
18
|
+
name: "file-uploader-mcp",
|
|
19
|
+
version: "1.0.0",
|
|
20
|
+
});
|
|
52
21
|
|
|
53
|
-
try {
|
|
54
|
-
const fileBuffer = fs.readFileSync(filePath);
|
|
55
|
-
const blob = new Blob([fileBuffer]);
|
|
56
|
-
const formData = new FormData();
|
|
57
|
-
formData.append('file', blob, path.basename(filename));
|
|
58
22
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
23
|
+
// 註冊檔案上傳工具
|
|
24
|
+
server.registerTool(
|
|
25
|
+
'upload_file',
|
|
26
|
+
{
|
|
27
|
+
title: 'File Upload Tool',
|
|
28
|
+
description: 'Upload a file from the current working directory to the web file uploader service',
|
|
29
|
+
inputSchema: z.object({
|
|
30
|
+
filename: z.string(),
|
|
31
|
+
}),
|
|
32
|
+
outputSchema: z.object({
|
|
33
|
+
success: z.boolean(),
|
|
34
|
+
message: z.string(),
|
|
35
|
+
downloadUrl: z.string().optional(),
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
async ({ filename }) => {
|
|
39
|
+
const uploaderUrl = process.env.WEB_FILE_UPLOADER_URL;
|
|
40
|
+
if (!uploaderUrl) {
|
|
41
|
+
return {
|
|
42
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'WEB_FILE_UPLOADER_URL environment variable not set' }) }],
|
|
43
|
+
structuredContent: { success: false, message: 'WEB_FILE_UPLOADER_URL environment variable not set' }
|
|
44
|
+
};
|
|
45
|
+
}
|
|
63
46
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const fullDownloadUrl = `${uploaderUrl}${result.download_url}`;
|
|
47
|
+
const filePath = path.resolve(process.cwd(), filename);
|
|
48
|
+
if (!fs.existsSync(filePath)) {
|
|
67
49
|
return {
|
|
68
|
-
content: [{ type: 'text', text: JSON.stringify({ success:
|
|
69
|
-
structuredContent: { success:
|
|
50
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `File ${filename} not found in current directory` }) }],
|
|
51
|
+
structuredContent: { success: false, message: `File ${filename} not found in current directory` }
|
|
70
52
|
};
|
|
71
|
-
}
|
|
72
|
-
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
57
|
+
const blob = new Blob([fileBuffer]);
|
|
58
|
+
const formData = new FormData();
|
|
59
|
+
formData.append('file', blob, path.basename(filename));
|
|
60
|
+
|
|
61
|
+
const response = await fetch(`${uploaderUrl}/upload`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
body: formData,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (response.ok) {
|
|
67
|
+
const result = await response.json() as UploadResponse;
|
|
68
|
+
const fullDownloadUrl = `${uploaderUrl}${result.download_url}`;
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: 'text', text: JSON.stringify({ success: true, message: result.message, downloadUrl: fullDownloadUrl }) }],
|
|
71
|
+
structuredContent: { success: true, message: result.message, downloadUrl: fullDownloadUrl }
|
|
72
|
+
};
|
|
73
|
+
} else {
|
|
74
|
+
const errorText = await response.text();
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `Upload failed: ${errorText}` }) }],
|
|
77
|
+
structuredContent: { success: false, message: `Upload failed: ${errorText}` }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
73
82
|
return {
|
|
74
|
-
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `Upload
|
|
75
|
-
structuredContent: { success: false, message: `Upload
|
|
83
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `Upload error: ${errorMessage}` }) }],
|
|
84
|
+
structuredContent: { success: false, message: `Upload error: ${errorMessage}` }
|
|
76
85
|
};
|
|
77
86
|
}
|
|
78
|
-
} catch (error) {
|
|
79
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
80
|
-
return {
|
|
81
|
-
content: [{ type: 'text', text: JSON.stringify({ success: false, message: `Upload error: ${errorMessage}` }) }],
|
|
82
|
-
structuredContent: { success: false, message: `Upload error: ${errorMessage}` }
|
|
83
|
-
};
|
|
84
87
|
}
|
|
85
|
-
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// 檢查是否通過命令行參數指定 HTTP 模式
|
|
89
|
-
const useHttp = process.argv.includes('--http');
|
|
90
|
-
|
|
91
|
-
// 如果是 HTTP 模式,啟動 HTTP Server
|
|
92
|
-
if (useHttp) {
|
|
93
|
-
const app = express();
|
|
94
|
-
app.use(express.json());
|
|
88
|
+
);
|
|
95
89
|
|
|
96
|
-
|
|
90
|
+
// 檢查是否通過命令行參數指定 HTTP 模式
|
|
91
|
+
const useHttp = process.argv.includes('--http');
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
});
|
|
93
|
+
// 如果是 HTTP 模式,啟動 HTTP Server
|
|
94
|
+
if (useHttp) {
|
|
95
|
+
const app = express();
|
|
96
|
+
app.use(express.json());
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
transport.close();
|
|
106
|
-
});
|
|
98
|
+
app.post('/mcp', async (req, res) => {
|
|
107
99
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
});
|
|
100
|
+
try {
|
|
101
|
+
const transport = new StreamableHTTPServerTransport({
|
|
102
|
+
sessionIdGenerator: undefined,
|
|
103
|
+
enableJsonResponse: true
|
|
104
|
+
});
|
|
115
105
|
|
|
106
|
+
res.on('close', () => {
|
|
107
|
+
transport.close();
|
|
108
|
+
});
|
|
116
109
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
110
|
+
await server.connect(transport);
|
|
111
|
+
await transport.handleRequest(req, res, req.body);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error('HTTP Transport error:', error);
|
|
114
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
const port = parseInt(process.env.PORT || '3000');
|
|
120
|
+
app.listen(port, () => {
|
|
121
|
+
console.log(`MCP HTTP Server running on http://localhost:${port}/mcp`);
|
|
122
|
+
|
|
123
|
+
console.log(`Test with: npx @modelcontextprotocol/inspector http://localhost:${port}/mcp`);
|
|
124
|
+
}).on('error', error => {
|
|
125
|
+
console.error('Server error:', error);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
129
|
+
// 否則使用 Stdio 模式
|
|
130
|
+
const transport = new StdioServerTransport();
|
|
131
|
+
await server.connect(transport);
|
|
132
|
+
console.error("MCP Server started and listening on stdio");
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error('Application startup error:', error);
|
|
136
|
+
process.exit(1);
|
|
131
137
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-file-uploader-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "MCP Server for file uploading functionality",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"module": "index.ts",
|
|
10
10
|
"type": "module",
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "bun build ./index.ts --outdir ./dist --target node",
|
|
12
|
+
"build": "bun build ./index.ts --outdir ./dist --target node --banner '#!/usr/bin/env bun'",
|
|
13
13
|
"start": "bun run dist/index.js",
|
|
14
14
|
"dev": "bun run index.ts"
|
|
15
15
|
},
|