nworks 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +102 -18
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +102 -18
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -919,6 +919,51 @@ Content-Type: application/octet-stream\r
|
|
|
919
919
|
if (!uploadRes.ok) return handleError(uploadRes);
|
|
920
920
|
return await uploadRes.json();
|
|
921
921
|
}
|
|
922
|
+
async function uploadBuffer(fileBuffer, fileName, userId = "me", folderId, overwrite = false, profile = "default") {
|
|
923
|
+
const fileSize = fileBuffer.length;
|
|
924
|
+
const base = `${BASE_URL3}/users/${userId}/drive/files`;
|
|
925
|
+
const createUrl = folderId ? `${base}/${folderId}` : base;
|
|
926
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
927
|
+
console.error(`[nworks] POST ${createUrl} (create upload URL for buffer)`);
|
|
928
|
+
}
|
|
929
|
+
const createRes = await authedFetch(
|
|
930
|
+
createUrl,
|
|
931
|
+
{
|
|
932
|
+
method: "POST",
|
|
933
|
+
headers: { "Content-Type": "application/json" },
|
|
934
|
+
body: JSON.stringify({ fileName, fileSize, overwrite })
|
|
935
|
+
},
|
|
936
|
+
profile
|
|
937
|
+
);
|
|
938
|
+
if (!createRes.ok) return handleError(createRes);
|
|
939
|
+
const { uploadUrl } = await createRes.json();
|
|
940
|
+
const boundary = `----nworks${Date.now()}`;
|
|
941
|
+
const header = Buffer.from(
|
|
942
|
+
`--${boundary}\r
|
|
943
|
+
Content-Disposition: form-data; name="Filedata"; filename="${fileName}"\r
|
|
944
|
+
Content-Type: application/octet-stream\r
|
|
945
|
+
\r
|
|
946
|
+
`
|
|
947
|
+
);
|
|
948
|
+
const footer = Buffer.from(`\r
|
|
949
|
+
--${boundary}--\r
|
|
950
|
+
`);
|
|
951
|
+
const body = Buffer.concat([header, fileBuffer, footer]);
|
|
952
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
953
|
+
console.error(`[nworks] POST ${uploadUrl} (upload buffer, ${fileSize} bytes)`);
|
|
954
|
+
}
|
|
955
|
+
const uploadRes = await authedFetch(
|
|
956
|
+
uploadUrl,
|
|
957
|
+
{
|
|
958
|
+
method: "POST",
|
|
959
|
+
headers: { "Content-Type": `multipart/form-data; boundary=${boundary}` },
|
|
960
|
+
body
|
|
961
|
+
},
|
|
962
|
+
profile
|
|
963
|
+
);
|
|
964
|
+
if (!uploadRes.ok) return handleError(uploadRes);
|
|
965
|
+
return await uploadRes.json();
|
|
966
|
+
}
|
|
922
967
|
async function downloadFile(fileId, userId = "me", profile = "default") {
|
|
923
968
|
const url2 = `${BASE_URL3}/users/${userId}/drive/files/${fileId}/download`;
|
|
924
969
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
@@ -14979,28 +15024,54 @@ function registerTools(server) {
|
|
|
14979
15024
|
);
|
|
14980
15025
|
server.tool(
|
|
14981
15026
|
"nworks_drive_upload",
|
|
14982
|
-
"\
|
|
15027
|
+
"\uD30C\uC77C\uC744 \uB4DC\uB77C\uC774\uBE0C\uC5D0 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file scope \uD544\uC694). content(base64)\uC640 fileName\uC73C\uB85C \uC804\uB2EC\uD558\uAC70\uB098, filePath\uB85C \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4. MCP \uD074\uB77C\uC774\uC5B8\uD2B8\uC5D0\uC11C\uB294 content+fileName \uBC29\uC2DD\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
14983
15028
|
{
|
|
14984
|
-
|
|
15029
|
+
content: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uB0B4\uC6A9 (base64 \uC778\uCF54\uB529). filePath \uB300\uC2E0 \uC0AC\uC6A9"),
|
|
15030
|
+
fileName: external_exports.string().optional().describe("\uD30C\uC77C\uBA85 (content \uC0AC\uC6A9 \uC2DC \uD544\uC218)"),
|
|
15031
|
+
filePath: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C (content \uB300\uC2E0 \uC0AC\uC6A9, \uB85C\uCEEC \uD658\uACBD\uC5D0\uC11C\uB9CC \uB3D9\uC791)"),
|
|
14985
15032
|
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)"),
|
|
14986
15033
|
folderId: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uD3F4\uB354 ID (\uBBF8\uC9C0\uC815 \uC2DC \uB8E8\uD2B8)"),
|
|
14987
15034
|
overwrite: external_exports.boolean().optional().describe("\uB3D9\uC77C \uD30C\uC77C\uBA85 \uB36E\uC5B4\uC4F0\uAE30 (\uAE30\uBCF8: false)")
|
|
14988
15035
|
},
|
|
14989
|
-
async ({ filePath, userId, folderId, overwrite }) => {
|
|
15036
|
+
async ({ content, fileName, filePath, userId, folderId, overwrite }) => {
|
|
14990
15037
|
try {
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
15038
|
+
let result;
|
|
15039
|
+
if (content && fileName) {
|
|
15040
|
+
const buffer = Buffer.from(content, "base64");
|
|
15041
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
15042
|
+
console.error(`[nworks] MCP upload: fileName=${fileName}, bufferSize=${buffer.length}`);
|
|
15043
|
+
}
|
|
15044
|
+
result = await uploadBuffer(
|
|
15045
|
+
buffer,
|
|
15046
|
+
fileName,
|
|
15047
|
+
userId ?? "me",
|
|
15048
|
+
folderId,
|
|
15049
|
+
overwrite ?? false
|
|
15050
|
+
);
|
|
15051
|
+
} else if (filePath) {
|
|
15052
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
15053
|
+
console.error(`[nworks] MCP upload: filePath=${filePath}`);
|
|
15054
|
+
}
|
|
15055
|
+
result = await uploadFile(
|
|
15056
|
+
filePath,
|
|
15057
|
+
userId ?? "me",
|
|
15058
|
+
folderId,
|
|
15059
|
+
overwrite ?? false
|
|
15060
|
+
);
|
|
15061
|
+
} else {
|
|
15062
|
+
return {
|
|
15063
|
+
content: [{ type: "text", text: "Error: content+fileName \uB610\uB294 filePath \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4. MCP \uD074\uB77C\uC774\uC5B8\uD2B8\uC5D0\uC11C\uB294 \uD30C\uC77C \uB0B4\uC6A9\uC744 base64\uB85C \uC778\uCF54\uB529\uD558\uC5EC content \uD30C\uB77C\uBBF8\uD130\uC5D0 \uC804\uB2EC\uD558\uACE0, fileName\uC5D0 \uD30C\uC77C\uBA85\uC744 \uC9C0\uC815\uD558\uC138\uC694." }],
|
|
15064
|
+
isError: true
|
|
15065
|
+
};
|
|
15066
|
+
}
|
|
14997
15067
|
return {
|
|
14998
15068
|
content: [{ type: "text", text: JSON.stringify({ success: true, ...result }) }]
|
|
14999
15069
|
};
|
|
15000
15070
|
} catch (err) {
|
|
15001
15071
|
const error48 = err;
|
|
15072
|
+
const detail = process.env["NWORKS_VERBOSE"] === "1" ? ` | stack: ${error48.stack}` : "";
|
|
15002
15073
|
return {
|
|
15003
|
-
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15074
|
+
content: [{ type: "text", text: `Error: ${error48.message}${detail}` }],
|
|
15004
15075
|
isError: true
|
|
15005
15076
|
};
|
|
15006
15077
|
}
|
|
@@ -15008,27 +15079,40 @@ function registerTools(server) {
|
|
|
15008
15079
|
);
|
|
15009
15080
|
server.tool(
|
|
15010
15081
|
"nworks_drive_download",
|
|
15011
|
-
"\uB4DC\uB77C\uC774\uBE0C \uD30C\uC77C\uC744 \uB2E4\uC6B4\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file \uB610\uB294 file.read scope \uD544\uC694)",
|
|
15082
|
+
"\uB4DC\uB77C\uC774\uBE0C \uD30C\uC77C\uC744 \uB2E4\uC6B4\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file \uB610\uB294 file.read scope \uD544\uC694). outputDir\uC744 \uC9C0\uC815\uD558\uBA74 \uB85C\uCEEC\uC5D0 \uD30C\uC77C\uB85C \uC800\uC7A5\uD558\uACE0, \uBBF8\uC9C0\uC815 \uC2DC \uD30C\uC77C \uB0B4\uC6A9\uC744 \uC9C1\uC811 \uBC18\uD658\uD569\uB2C8\uB2E4 (\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC740 text, \uBC14\uC774\uB108\uB9AC\uB294 base64).",
|
|
15012
15083
|
{
|
|
15013
15084
|
fileId: external_exports.string().describe("\uB2E4\uC6B4\uB85C\uB4DC\uD560 \uD30C\uC77C ID"),
|
|
15014
|
-
outputDir: external_exports.string().optional().describe("\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC (\uBBF8\uC9C0\uC815 \uC2DC \
|
|
15085
|
+
outputDir: external_exports.string().optional().describe("\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC (\uC9C0\uC815 \uC2DC \uD30C\uC77C\uB85C \uC800\uC7A5, \uBBF8\uC9C0\uC815 \uC2DC \uB0B4\uC6A9\uC744 \uC9C1\uC811 \uBC18\uD658)"),
|
|
15015
15086
|
outputName: external_exports.string().optional().describe("\uC800\uC7A5 \uD30C\uC77C\uBA85 (\uBBF8\uC9C0\uC815 \uC2DC \uC6D0\uBCF8 \uD30C\uC77C\uBA85)"),
|
|
15016
15087
|
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
15017
15088
|
},
|
|
15018
15089
|
async ({ fileId, outputDir, outputName, userId }) => {
|
|
15019
15090
|
try {
|
|
15020
|
-
const { writeFile: writeFile3 } = await import("fs/promises");
|
|
15021
|
-
const { join: join3 } = await import("path");
|
|
15022
15091
|
const result = await downloadFile(
|
|
15023
15092
|
fileId,
|
|
15024
15093
|
userId ?? "me"
|
|
15025
15094
|
);
|
|
15026
15095
|
const fileName = outputName ?? result.fileName ?? fileId;
|
|
15027
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15096
|
+
if (outputDir) {
|
|
15097
|
+
const { writeFile: writeFile3 } = await import("fs/promises");
|
|
15098
|
+
const { join: join3 } = await import("path");
|
|
15099
|
+
const outPath = join3(outputDir, fileName);
|
|
15100
|
+
await writeFile3(outPath, result.buffer);
|
|
15101
|
+
return {
|
|
15102
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, fileName, path: outPath, size: result.buffer.length }) }]
|
|
15103
|
+
};
|
|
15104
|
+
}
|
|
15105
|
+
const textExtensions = /\.(txt|md|csv|json|xml|html|htm|css|js|ts|jsx|tsx|yaml|yml|toml|ini|cfg|conf|log|sh|bash|zsh|py|rb|java|go|rs|c|cpp|h|hpp|sql|graphql|env|gitignore|dockerignore|editorconfig)$/i;
|
|
15106
|
+
const isText = textExtensions.test(fileName);
|
|
15107
|
+
if (isText) {
|
|
15108
|
+
const text = result.buffer.toString("utf-8");
|
|
15109
|
+
return {
|
|
15110
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, fileName, size: result.buffer.length, encoding: "text", content: text }) }]
|
|
15111
|
+
};
|
|
15112
|
+
}
|
|
15113
|
+
const base643 = result.buffer.toString("base64");
|
|
15030
15114
|
return {
|
|
15031
|
-
content: [{ type: "text", text: JSON.stringify({ success: true, fileName,
|
|
15115
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, fileName, size: result.buffer.length, encoding: "base64", content: base643 }) }]
|
|
15032
15116
|
};
|
|
15033
15117
|
} catch (err) {
|
|
15034
15118
|
const error48 = err;
|