nworks 0.3.1 → 0.3.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 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
- "\uB85C\uCEEC \uD30C\uC77C\uC744 \uB4DC\uB77C\uC774\uBE0C\uC5D0 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file scope \uD544\uC694)",
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
- filePath: external_exports.string().describe("\uC5C5\uB85C\uB4DC\uD560 \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C"),
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
- const result = await uploadFile(
14992
- filePath,
14993
- userId ?? "me",
14994
- folderId,
14995
- overwrite ?? false
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
  }