yungle-mcp 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -6,8 +6,9 @@ any MCP client with one sign-in: ask what arrived, share files, and approve ever
6
6
 
7
7
  ## Connect in one click (recommended)
8
8
 
9
- Yungle runs this server for you. Add it as a remote MCP server (in Claude: *Settings →
10
- Connectors → Add custom connector*; in Cursor: *MCP → Add server*) and sign in when asked:
9
+ Yungle runs this server for you. **In Claude**, add it from the connector directory:
10
+ [claude.ai/directory/yungle](https://claude.ai/directory/yungle). **Elsewhere** (Cursor: *MCP → Add
11
+ server*, and any other MCP client), add it as a remote server and sign in when asked:
11
12
 
12
13
  ```
13
14
  https://yungle.co/mcp
package/dist/index.mjs CHANGED
@@ -74,7 +74,7 @@ async function uploadPath(endpoint, target, path, size, doFetch = fetch) {
74
74
  }
75
75
 
76
76
  // src/server.ts
77
- var MCP_VERSION = true ? "0.2.2" : "dev";
77
+ var MCP_VERSION = true ? "0.2.4" : "dev";
78
78
  function createServer(client, opts = { canWrite: false, canEmail: false, local: false }) {
79
79
  const server = new McpServer(
80
80
  { name: "yungle", version: MCP_VERSION },
@@ -103,7 +103,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
103
103
  "list_transfers",
104
104
  {
105
105
  title: "List transfers",
106
- description: "Answers: what have I sent recently? what is expiring soon? which deliveries has nobody picked up? who did I send that to? Returns recent transfers with size, recipients, download count, expiry date and share link. Start here for any question about sent files.",
106
+ description: "Answers: what have I sent recently? what is expiring soon? which deliveries has nobody picked up? who did I send that to? Returns recent transfers with size, recipients, download count, expiry date and share link.",
107
107
  inputSchema: {},
108
108
  annotations: { title: "List transfers", readOnlyHint: true }
109
109
  },
@@ -116,8 +116,8 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
116
116
  "get_transfer",
117
117
  {
118
118
  title: "Transfer detail",
119
- description: "Answers: what is in this transfer? was it delivered? has a specific recipient opened it? is it safe to share? Returns the files with their malware-scan verdicts, plus per-recipient delivery and download status. Needs an id from list_transfers.",
120
- inputSchema: { id: z.string().describe("Transfer id from list_transfers.") },
119
+ description: "Answers: what is in this transfer? was it delivered? has a specific recipient downloaded it? is it safe to share? Returns the files with their malware-scan verdicts, plus per-recipient delivery and download status for one transfer id.",
120
+ inputSchema: { id: z.string().describe("Transfer id.") },
121
121
  annotations: { title: "Transfer detail", readOnlyHint: true }
122
122
  },
123
123
  async ({ id }) => ok(wrapUntrusted(await client.getTransfer(id)))
@@ -126,7 +126,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
126
126
  "get_transfer_downloads",
127
127
  {
128
128
  title: "Download receipts",
129
- description: "Answers: did the client download it? when? how many times? Returns download events with timestamps and per-recipient status. IMPORTANT when counting: one page visit is one download, not one per file \u2014 events sharing a sessionId are a single visit, so count distinct sessions or a single visitor looks like eight.",
129
+ description: "Answers: did the client download it? when? how many times? Returns download events with timestamps and per-recipient status. One visit can fetch several files: events that share a sessionId belong to the same visit.",
130
130
  inputSchema: { id: z.string() },
131
131
  annotations: { title: "Download receipts", readOnlyHint: true }
132
132
  },
@@ -146,7 +146,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
146
146
  "get_collection",
147
147
  {
148
148
  title: "Collection detail",
149
- description: "Answers: what is the link for this collection? how much is in it? when does it expire? Returns one collection with its secret share link, file count, total size and expiry. Needs an id from list_collections.",
149
+ description: "Answers: what is the link for this collection? how much is in it? when does it expire? Returns one collection with its secret share link, file count, total size and expiry.",
150
150
  inputSchema: { id: z.string() },
151
151
  annotations: { title: "Collection detail", readOnlyHint: true }
152
152
  },
@@ -156,7 +156,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
156
156
  "list_collection_files",
157
157
  {
158
158
  title: "Files in a collection",
159
- description: 'Answers: what files are in this collection? what is in this folder? are the raws uploaded yet? Returns filenames, sizes and types. Omit folderId for every file; pass "root" for the top level only, or a folder id from list_folders. Filenames only \u2014 never file contents.',
159
+ description: 'Answers: what files are in this collection? what is in this folder? are the raws uploaded yet? Returns filenames, sizes and types. Omit folderId for every file; pass "root" for the top level only, or a folder id. Filenames only \u2014 never file contents.',
160
160
  inputSchema: { id: z.string(), folderId: z.string().optional() },
161
161
  annotations: { title: "Files in a collection", readOnlyHint: true }
162
162
  },
@@ -166,7 +166,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
166
166
  "list_folders",
167
167
  {
168
168
  title: "Folders in a collection",
169
- description: "Answers: how is this collection organised? what folders exist? Returns the folder tree. Ordered by depth then path, which is NOT a pre-order traversal \u2014 build the tree from parentId rather than trusting the order. Each folder also carries its full materialised path.",
169
+ description: "Answers: how is this collection organised? what folders exist? Returns the folder tree. Ordered by depth, then path (not a pre-order traversal). Each folder carries its parentId and its full path.",
170
170
  inputSchema: { id: z.string() },
171
171
  annotations: { title: "Folders in a collection", readOnlyHint: true }
172
172
  },
@@ -199,9 +199,8 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
199
199
  description: [
200
200
  "Prepare a draft transfer for files the user will upload themselves, and return its id.",
201
201
  "",
202
- "This does NOT upload any files and does NOT email anybody. Use it when the user wants",
203
- "to start a send and finish it in the browser or with `yungle send`. To share content",
204
- "you have in hand, use create_share_link instead."
202
+ "It uploads no files and emails nobody: the user uploads the files and sends the transfer",
203
+ "themselves, in the browser or with the Yungle CLI."
205
204
  ].join("\n"),
206
205
  inputSchema: {
207
206
  files: z.array(
@@ -323,7 +322,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
323
322
  {
324
323
  title: "Email a transfer to recipients",
325
324
  description: [
326
- "Email an existing transfer (from create_share_link or share_local_files) to up to 10",
325
+ "Email an existing transfer, one already shared as a link, to up to 10",
327
326
  "recipients. The user is asked to confirm every send, with the addresses and message",
328
327
  "shown to them; if this client cannot ask, nothing is sent and you get the link to pass on."
329
328
  ].join("\n"),
package/dist/server.mjs CHANGED
@@ -34,7 +34,7 @@ function pageQuery(page, extra = {}) {
34
34
  const q = params.toString();
35
35
  return q ? `?${q}` : "";
36
36
  }
37
- var CLIENT_VERSION = true ? "0.2.0" : "dev";
37
+ var CLIENT_VERSION = true ? "0.2.1" : "dev";
38
38
  var YungleClient = class {
39
39
  baseUrl;
40
40
  apiKey;
@@ -345,7 +345,7 @@ async function uploadPath(endpoint, target, path, size, doFetch = fetch) {
345
345
  }
346
346
 
347
347
  // src/server.ts
348
- var MCP_VERSION = true ? "0.2.2" : "dev";
348
+ var MCP_VERSION = true ? "0.2.4" : "dev";
349
349
  function createServer(client, opts = { canWrite: false, canEmail: false, local: false }) {
350
350
  const server = new McpServer(
351
351
  { name: "yungle", version: MCP_VERSION },
@@ -374,7 +374,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
374
374
  "list_transfers",
375
375
  {
376
376
  title: "List transfers",
377
- description: "Answers: what have I sent recently? what is expiring soon? which deliveries has nobody picked up? who did I send that to? Returns recent transfers with size, recipients, download count, expiry date and share link. Start here for any question about sent files.",
377
+ description: "Answers: what have I sent recently? what is expiring soon? which deliveries has nobody picked up? who did I send that to? Returns recent transfers with size, recipients, download count, expiry date and share link.",
378
378
  inputSchema: {},
379
379
  annotations: { title: "List transfers", readOnlyHint: true }
380
380
  },
@@ -387,8 +387,8 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
387
387
  "get_transfer",
388
388
  {
389
389
  title: "Transfer detail",
390
- description: "Answers: what is in this transfer? was it delivered? has a specific recipient opened it? is it safe to share? Returns the files with their malware-scan verdicts, plus per-recipient delivery and download status. Needs an id from list_transfers.",
391
- inputSchema: { id: z.string().describe("Transfer id from list_transfers.") },
390
+ description: "Answers: what is in this transfer? was it delivered? has a specific recipient downloaded it? is it safe to share? Returns the files with their malware-scan verdicts, plus per-recipient delivery and download status for one transfer id.",
391
+ inputSchema: { id: z.string().describe("Transfer id.") },
392
392
  annotations: { title: "Transfer detail", readOnlyHint: true }
393
393
  },
394
394
  async ({ id }) => ok(wrapUntrusted(await client.getTransfer(id)))
@@ -397,7 +397,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
397
397
  "get_transfer_downloads",
398
398
  {
399
399
  title: "Download receipts",
400
- description: "Answers: did the client download it? when? how many times? Returns download events with timestamps and per-recipient status. IMPORTANT when counting: one page visit is one download, not one per file \u2014 events sharing a sessionId are a single visit, so count distinct sessions or a single visitor looks like eight.",
400
+ description: "Answers: did the client download it? when? how many times? Returns download events with timestamps and per-recipient status. One visit can fetch several files: events that share a sessionId belong to the same visit.",
401
401
  inputSchema: { id: z.string() },
402
402
  annotations: { title: "Download receipts", readOnlyHint: true }
403
403
  },
@@ -417,7 +417,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
417
417
  "get_collection",
418
418
  {
419
419
  title: "Collection detail",
420
- description: "Answers: what is the link for this collection? how much is in it? when does it expire? Returns one collection with its secret share link, file count, total size and expiry. Needs an id from list_collections.",
420
+ description: "Answers: what is the link for this collection? how much is in it? when does it expire? Returns one collection with its secret share link, file count, total size and expiry.",
421
421
  inputSchema: { id: z.string() },
422
422
  annotations: { title: "Collection detail", readOnlyHint: true }
423
423
  },
@@ -427,7 +427,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
427
427
  "list_collection_files",
428
428
  {
429
429
  title: "Files in a collection",
430
- description: 'Answers: what files are in this collection? what is in this folder? are the raws uploaded yet? Returns filenames, sizes and types. Omit folderId for every file; pass "root" for the top level only, or a folder id from list_folders. Filenames only \u2014 never file contents.',
430
+ description: 'Answers: what files are in this collection? what is in this folder? are the raws uploaded yet? Returns filenames, sizes and types. Omit folderId for every file; pass "root" for the top level only, or a folder id. Filenames only \u2014 never file contents.',
431
431
  inputSchema: { id: z.string(), folderId: z.string().optional() },
432
432
  annotations: { title: "Files in a collection", readOnlyHint: true }
433
433
  },
@@ -437,7 +437,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
437
437
  "list_folders",
438
438
  {
439
439
  title: "Folders in a collection",
440
- description: "Answers: how is this collection organised? what folders exist? Returns the folder tree. Ordered by depth then path, which is NOT a pre-order traversal \u2014 build the tree from parentId rather than trusting the order. Each folder also carries its full materialised path.",
440
+ description: "Answers: how is this collection organised? what folders exist? Returns the folder tree. Ordered by depth, then path (not a pre-order traversal). Each folder carries its parentId and its full path.",
441
441
  inputSchema: { id: z.string() },
442
442
  annotations: { title: "Folders in a collection", readOnlyHint: true }
443
443
  },
@@ -470,9 +470,8 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
470
470
  description: [
471
471
  "Prepare a draft transfer for files the user will upload themselves, and return its id.",
472
472
  "",
473
- "This does NOT upload any files and does NOT email anybody. Use it when the user wants",
474
- "to start a send and finish it in the browser or with `yungle send`. To share content",
475
- "you have in hand, use create_share_link instead."
473
+ "It uploads no files and emails nobody: the user uploads the files and sends the transfer",
474
+ "themselves, in the browser or with the Yungle CLI."
476
475
  ].join("\n"),
477
476
  inputSchema: {
478
477
  files: z.array(
@@ -594,7 +593,7 @@ function createServer(client, opts = { canWrite: false, canEmail: false, local:
594
593
  {
595
594
  title: "Email a transfer to recipients",
596
595
  description: [
597
- "Email an existing transfer (from create_share_link or share_local_files) to up to 10",
596
+ "Email an existing transfer, one already shared as a link, to up to 10",
598
597
  "recipients. The user is asked to confirm every send, with the addresses and message",
599
598
  "shown to them; if this client cannot ask, nothing is sent and you get the link to pass on."
600
599
  ].join("\n"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yungle-mcp",
3
3
  "mcpName": "co.yungle/yungle",
4
- "version": "0.2.2",
4
+ "version": "0.2.4",
5
5
  "type": "module",
6
6
  "description": "MCP server for Yungle: let Claude, Cursor or any MCP client read your file transfers, share files and send them, with your approval.",
7
7
  "bin": {
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "@modelcontextprotocol/sdk": "^1.0.0",
17
17
  "zod": "^3.24.1",
18
- "yungle-client": "^0.2.0"
18
+ "yungle-client": "^0.2.1"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/node": "^22.10.5",