srift-transfer 2.2.14 → 2.2.15

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
@@ -4,6 +4,7 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen.svg)](https://nodejs.org/)
6
6
  [![MCP Protocol](https://img.shields.io/badge/MCP-2025--06--18-purple.svg)](https://modelcontextprotocol.io)
7
+ [![Smithery](https://img.shields.io/badge/Smithery-srift%2Fsrift-7c3aed)](https://smithery.ai/servers/srift/srift)
7
8
  [![Encryption: AES-256-GCM](https://img.shields.io/badge/Encryption-AES--256--GCM-green.svg)](https://srift.app)
8
9
  [![Zero Telemetry](https://img.shields.io/badge/telemetry-zero-success.svg)](https://srift.app/privacy)
9
10
 
package/dist/daemon.js CHANGED
@@ -17,17 +17,34 @@ var PROTOCOL_VERSION = "2025-06-18";
17
17
  var MCP_TOOLS = [
18
18
  {
19
19
  name: "srift_start_session",
20
+ title: "Start SRIFT Session",
20
21
  description: "Create a new SRIFT secure session. Returns the 7-character session ID and a shareable URL. The host approves all future joins. E2EE keys derive locally from the session ID + optional roomSecret.",
21
22
  inputSchema: {
22
23
  type: "object",
23
24
  properties: {
24
- sessionName: { type: "string", description: "Human-readable session name (optional)" },
25
+ sessionName: { type: "string", description: 'Human-readable session name (optional, e.g. "Project Collab")' },
25
26
  roomSecret: { type: "string", description: "Optional shared secret for extra-strong E2EE key derivation. Never sent to server." }
26
27
  }
28
+ },
29
+ outputSchema: {
30
+ type: "object",
31
+ properties: {
32
+ sessionId: { type: "string", description: "7-character unique session room code" },
33
+ url: { type: "string", description: "Direct browser join URL to share with peers" },
34
+ role: { type: "string", description: "User role in session (host)" }
35
+ },
36
+ required: ["sessionId"]
37
+ },
38
+ annotations: {
39
+ readOnlyHint: false,
40
+ destructiveHint: false,
41
+ audience: ["agent", "user"],
42
+ priority: 0.9
27
43
  }
28
44
  },
29
45
  {
30
46
  name: "srift_join_session",
47
+ title: "Join SRIFT Session",
31
48
  description: "Request to join an existing SRIFT session by its 7-character session ID. The host must approve before transfers/chat work.",
32
49
  inputSchema: {
33
50
  type: "object",
@@ -37,20 +54,77 @@ var MCP_TOOLS = [
37
54
  roomSecret: { type: "string", description: "Optional shared secret matching the host's" }
38
55
  },
39
56
  required: ["sessionId"]
57
+ },
58
+ outputSchema: {
59
+ type: "object",
60
+ properties: {
61
+ sessionId: { type: "string", description: "Session room code" },
62
+ status: { type: "string", description: "Join request status (approved, pending, or joined)" },
63
+ message: { type: "string", description: "Status message or instructions" }
64
+ },
65
+ required: ["sessionId"]
66
+ },
67
+ annotations: {
68
+ readOnlyHint: false,
69
+ destructiveHint: false,
70
+ audience: ["agent", "user"],
71
+ priority: 0.9
40
72
  }
41
73
  },
42
74
  {
43
75
  name: "srift_session_status",
76
+ title: "Get Session Status",
44
77
  description: "Get current session details: id, role (host/guest), connection state, pending join requests, peer count.",
45
- inputSchema: { type: "object", properties: {} }
78
+ inputSchema: { type: "object", properties: {} },
79
+ outputSchema: {
80
+ type: "object",
81
+ properties: {
82
+ sessionId: { type: "string", description: "Active session ID, if any" },
83
+ role: { type: "string", description: 'Active role: "host", "guest", or null' },
84
+ isConnected: { type: "boolean", description: "True if connected to signaling server" },
85
+ peerCount: { type: "number", description: "Number of connected peers in the room" },
86
+ pendingJoins: {
87
+ type: "array",
88
+ description: "List of pending guest join requests waiting for host approval",
89
+ items: {
90
+ type: "object",
91
+ properties: {
92
+ tempUserId: { type: "string", description: "Temporary ID of requesting user" },
93
+ username: { type: "string", description: "Username of requesting user" }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ },
99
+ annotations: {
100
+ readOnlyHint: true,
101
+ destructiveHint: false,
102
+ audience: ["agent", "user"],
103
+ priority: 0.8
104
+ }
46
105
  },
47
106
  {
48
107
  name: "srift_close_session",
108
+ title: "Close Session",
49
109
  description: "Close the active session. Flushes E2EE keys, disconnects signaling, clears chat history.",
50
- inputSchema: { type: "object", properties: {} }
110
+ inputSchema: { type: "object", properties: {} },
111
+ outputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ success: { type: "boolean", description: "True if session was closed cleanly" },
115
+ message: { type: "string", description: "Confirmation message" }
116
+ }
117
+ },
118
+ annotations: {
119
+ readOnlyHint: false,
120
+ destructiveHint: true,
121
+ audience: ["agent", "user"],
122
+ priority: 0.7
123
+ }
51
124
  },
52
125
  {
53
126
  name: "srift_approve_join",
127
+ title: "Approve Join Request",
54
128
  description: "Host-only. Approve a pending guest join request by their temp user ID.",
55
129
  inputSchema: {
56
130
  type: "object",
@@ -58,87 +132,261 @@ var MCP_TOOLS = [
58
132
  tempUserId: { type: "string", description: "Temp user ID from session_status pendingJoins" }
59
133
  },
60
134
  required: ["tempUserId"]
135
+ },
136
+ outputSchema: {
137
+ type: "object",
138
+ properties: {
139
+ success: { type: "boolean", description: "True if guest was approved" },
140
+ tempUserId: { type: "string", description: "Approved user temporary ID" }
141
+ }
142
+ },
143
+ annotations: {
144
+ readOnlyHint: false,
145
+ destructiveHint: false,
146
+ audience: ["agent", "user"],
147
+ priority: 0.8
61
148
  }
62
149
  },
63
150
  {
64
151
  name: "srift_reject_join",
152
+ title: "Reject Join Request",
65
153
  description: "Host-only. Reject a pending guest join request.",
66
154
  inputSchema: {
67
155
  type: "object",
68
156
  properties: {
69
- tempUserId: { type: "string" },
70
- reason: { type: "string", description: "Optional rejection reason" }
157
+ tempUserId: { type: "string", description: "Temp user ID from session_status pendingJoins" },
158
+ reason: { type: "string", description: "Optional rejection reason message sent to guest" }
71
159
  },
72
160
  required: ["tempUserId"]
161
+ },
162
+ outputSchema: {
163
+ type: "object",
164
+ properties: {
165
+ success: { type: "boolean", description: "True if guest join request was rejected" },
166
+ tempUserId: { type: "string", description: "Rejected user temporary ID" }
167
+ }
168
+ },
169
+ annotations: {
170
+ readOnlyHint: false,
171
+ destructiveHint: true,
172
+ audience: ["agent", "user"],
173
+ priority: 0.7
73
174
  }
74
175
  },
75
176
  {
76
177
  name: "srift_kick_user",
178
+ title: "Kick Peer",
77
179
  description: "Host-only. Disconnect and ban a peer from the active room.",
78
180
  inputSchema: {
79
181
  type: "object",
80
- properties: { userId: { type: "string" } },
182
+ properties: {
183
+ userId: { type: "string", description: "User ID of the participant to disconnect and remove" }
184
+ },
81
185
  required: ["userId"]
186
+ },
187
+ outputSchema: {
188
+ type: "object",
189
+ properties: {
190
+ success: { type: "boolean", description: "True if peer was successfully kicked" },
191
+ userId: { type: "string", description: "ID of kicked peer" }
192
+ }
193
+ },
194
+ annotations: {
195
+ readOnlyHint: false,
196
+ destructiveHint: true,
197
+ audience: ["agent", "user"],
198
+ priority: 0.6
82
199
  }
83
200
  },
84
201
  {
85
202
  name: "srift_send_file",
203
+ title: "Send File in Session",
86
204
  description: "Offer a file to the connected peer in an existing session. The peer must accept with srift_accept_transfer. Returns a fileId for monitoring. Transport is auto-selected internally.",
87
205
  inputSchema: {
88
206
  type: "object",
89
207
  properties: {
90
- filePath: { type: "string", description: "Absolute path to the file on disk" }
208
+ filePath: { type: "string", description: "Absolute path to the file on local disk" }
91
209
  },
92
210
  required: ["filePath"]
211
+ },
212
+ outputSchema: {
213
+ type: "object",
214
+ properties: {
215
+ fileId: { type: "string", description: "Unique identifier for the offered file transfer" },
216
+ fileName: { type: "string", description: "Base filename of the offered file" },
217
+ fileSize: { type: "number", description: "Size of file in bytes" }
218
+ }
219
+ },
220
+ annotations: {
221
+ readOnlyHint: false,
222
+ destructiveHint: false,
223
+ audience: ["agent", "user"],
224
+ priority: 0.9
93
225
  }
94
226
  },
95
227
  {
96
228
  name: "srift_accept_transfer",
229
+ title: "Accept File Transfer",
97
230
  description: "Accept a pending file offer from the peer and start downloading.",
98
231
  inputSchema: {
99
232
  type: "object",
100
233
  properties: {
101
- fileId: { type: "string", description: "fileId from the inbound file_offer event" },
234
+ fileId: { type: "string", description: "fileId from the inbound file_offer event or transfer list" },
102
235
  saveDir: { type: "string", description: "Absolute path to destination directory (defaults to CWD)" }
103
236
  },
104
237
  required: ["fileId"]
238
+ },
239
+ outputSchema: {
240
+ type: "object",
241
+ properties: {
242
+ success: { type: "boolean", description: "True if transfer acceptance started successfully" },
243
+ fileId: { type: "string", description: "Accepted transfer ID" },
244
+ saveDir: { type: "string", description: "Destination directory path" }
245
+ }
246
+ },
247
+ annotations: {
248
+ readOnlyHint: false,
249
+ destructiveHint: false,
250
+ audience: ["agent", "user"],
251
+ priority: 0.9
105
252
  }
106
253
  },
107
254
  {
108
255
  name: "srift_list_transfers",
256
+ title: "List Active Transfers",
109
257
  description: "List all active and recent transfers with progress, speed, ETA, and status.",
110
- inputSchema: { type: "object", properties: {} }
258
+ inputSchema: { type: "object", properties: {} },
259
+ outputSchema: {
260
+ type: "object",
261
+ properties: {
262
+ transfers: {
263
+ type: "array",
264
+ description: "List of live or recent file transfers",
265
+ items: {
266
+ type: "object",
267
+ properties: {
268
+ fileId: { type: "string", description: "Transfer unique file ID" },
269
+ name: { type: "string", description: "Filename" },
270
+ size: { type: "number", description: "Size in bytes" },
271
+ progress: { type: "number", description: "Transfer percentage 0-100" },
272
+ status: { type: "string", description: "Transfer status (uploading, downloading, completed, failed)" },
273
+ speedKBps: { type: "number", description: "Current transfer speed in KB/s" },
274
+ etaSeconds: { type: "number", description: "Estimated remaining seconds" }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ },
280
+ annotations: {
281
+ readOnlyHint: true,
282
+ destructiveHint: false,
283
+ audience: ["agent", "user"],
284
+ priority: 0.8
285
+ }
111
286
  },
112
287
  {
113
288
  name: "srift_quick_share",
289
+ title: "Quick Share File",
114
290
  description: 'One-shot helper: if no session is active, creates one; then seeds the file and returns a public DOWNLOAD URL (https://srift.app/d/<token>) the recipient can open in any browser or curl. No install needed on their side. Best for "AI wants to deliver a file to the user with zero ceremony".',
115
291
  inputSchema: {
116
292
  type: "object",
117
293
  properties: {
118
- filePath: { type: "string" },
119
- sessionName: { type: "string" }
294
+ filePath: { type: "string", description: "Absolute path to the file to deliver to the recipient" },
295
+ sessionName: { type: "string", description: "Optional session label for the transfer" }
120
296
  },
121
297
  required: ["filePath"]
298
+ },
299
+ outputSchema: {
300
+ type: "object",
301
+ properties: {
302
+ sessionId: { type: "string", description: "Associated session ID" },
303
+ fileId: { type: "string", description: "Transfer file ID" },
304
+ downloadUrl: { type: "string", description: "Public HTTP download URL for recipient" },
305
+ fileName: { type: "string", description: "Base filename" },
306
+ fileSize: { type: "number", description: "File size in bytes" }
307
+ },
308
+ required: ["downloadUrl"]
309
+ },
310
+ annotations: {
311
+ readOnlyHint: false,
312
+ destructiveHint: false,
313
+ audience: ["agent", "user"],
314
+ priority: 1
122
315
  }
123
316
  },
124
317
  {
125
318
  name: "srift_send_chat",
319
+ title: "Send Encrypted Chat",
126
320
  description: "Send an end-to-end encrypted (AES-256-GCM) chat message to the connected peer.",
127
321
  inputSchema: {
128
322
  type: "object",
129
- properties: { message: { type: "string" } },
323
+ properties: {
324
+ message: { type: "string", description: "Plaintext message string to encrypt and transmit" }
325
+ },
130
326
  required: ["message"]
327
+ },
328
+ outputSchema: {
329
+ type: "object",
330
+ properties: {
331
+ success: { type: "boolean", description: "True if message was sent" },
332
+ timestamp: { type: "string", description: "ISO 8601 transmission timestamp" }
333
+ }
334
+ },
335
+ annotations: {
336
+ readOnlyHint: false,
337
+ destructiveHint: false,
338
+ audience: ["agent", "user"],
339
+ priority: 0.8
131
340
  }
132
341
  },
133
342
  {
134
343
  name: "srift_chat_history",
344
+ title: "Read Chat History",
135
345
  description: "Read the locally-decrypted chat log for the current session.",
136
- inputSchema: { type: "object", properties: {} }
346
+ inputSchema: { type: "object", properties: {} },
347
+ outputSchema: {
348
+ type: "object",
349
+ properties: {
350
+ messages: {
351
+ type: "array",
352
+ description: "Decrypted message log for current session",
353
+ items: {
354
+ type: "object",
355
+ properties: {
356
+ sender: { type: "string", description: "Sender display name" },
357
+ message: { type: "string", description: "Decrypted plaintext content" },
358
+ timestamp: { type: "string", description: "ISO timestamp" }
359
+ }
360
+ }
361
+ }
362
+ }
363
+ },
364
+ annotations: {
365
+ readOnlyHint: true,
366
+ destructiveHint: false,
367
+ audience: ["agent", "user"],
368
+ priority: 0.7
369
+ }
137
370
  },
138
371
  {
139
372
  name: "srift_read_state",
373
+ title: "Read Local State",
140
374
  description: "Return the raw .srift-state.json contents (session + active transfers snapshot). Useful for one-shot polling without subscribing to SSE.",
141
- inputSchema: { type: "object", properties: {} }
375
+ inputSchema: { type: "object", properties: {} },
376
+ outputSchema: {
377
+ type: "object",
378
+ properties: {
379
+ session: { type: "object", description: "Current session state snapshot" },
380
+ activeTransfers: { type: "array", description: "Live transfers array" },
381
+ lastUpdated: { type: "string", description: "Last state write timestamp" }
382
+ }
383
+ },
384
+ annotations: {
385
+ readOnlyHint: true,
386
+ destructiveHint: false,
387
+ audience: ["agent", "user"],
388
+ priority: 0.6
389
+ }
142
390
  }
143
391
  ];
144
392
  var MCP_RESOURCES = [
package/dist/index.js CHANGED
@@ -159,17 +159,34 @@ var init_core = __esm({
159
159
  MCP_TOOLS = [
160
160
  {
161
161
  name: "srift_start_session",
162
+ title: "Start SRIFT Session",
162
163
  description: "Create a new SRIFT secure session. Returns the 7-character session ID and a shareable URL. The host approves all future joins. E2EE keys derive locally from the session ID + optional roomSecret.",
163
164
  inputSchema: {
164
165
  type: "object",
165
166
  properties: {
166
- sessionName: { type: "string", description: "Human-readable session name (optional)" },
167
+ sessionName: { type: "string", description: 'Human-readable session name (optional, e.g. "Project Collab")' },
167
168
  roomSecret: { type: "string", description: "Optional shared secret for extra-strong E2EE key derivation. Never sent to server." }
168
169
  }
170
+ },
171
+ outputSchema: {
172
+ type: "object",
173
+ properties: {
174
+ sessionId: { type: "string", description: "7-character unique session room code" },
175
+ url: { type: "string", description: "Direct browser join URL to share with peers" },
176
+ role: { type: "string", description: "User role in session (host)" }
177
+ },
178
+ required: ["sessionId"]
179
+ },
180
+ annotations: {
181
+ readOnlyHint: false,
182
+ destructiveHint: false,
183
+ audience: ["agent", "user"],
184
+ priority: 0.9
169
185
  }
170
186
  },
171
187
  {
172
188
  name: "srift_join_session",
189
+ title: "Join SRIFT Session",
173
190
  description: "Request to join an existing SRIFT session by its 7-character session ID. The host must approve before transfers/chat work.",
174
191
  inputSchema: {
175
192
  type: "object",
@@ -179,20 +196,77 @@ var init_core = __esm({
179
196
  roomSecret: { type: "string", description: "Optional shared secret matching the host's" }
180
197
  },
181
198
  required: ["sessionId"]
199
+ },
200
+ outputSchema: {
201
+ type: "object",
202
+ properties: {
203
+ sessionId: { type: "string", description: "Session room code" },
204
+ status: { type: "string", description: "Join request status (approved, pending, or joined)" },
205
+ message: { type: "string", description: "Status message or instructions" }
206
+ },
207
+ required: ["sessionId"]
208
+ },
209
+ annotations: {
210
+ readOnlyHint: false,
211
+ destructiveHint: false,
212
+ audience: ["agent", "user"],
213
+ priority: 0.9
182
214
  }
183
215
  },
184
216
  {
185
217
  name: "srift_session_status",
218
+ title: "Get Session Status",
186
219
  description: "Get current session details: id, role (host/guest), connection state, pending join requests, peer count.",
187
- inputSchema: { type: "object", properties: {} }
220
+ inputSchema: { type: "object", properties: {} },
221
+ outputSchema: {
222
+ type: "object",
223
+ properties: {
224
+ sessionId: { type: "string", description: "Active session ID, if any" },
225
+ role: { type: "string", description: 'Active role: "host", "guest", or null' },
226
+ isConnected: { type: "boolean", description: "True if connected to signaling server" },
227
+ peerCount: { type: "number", description: "Number of connected peers in the room" },
228
+ pendingJoins: {
229
+ type: "array",
230
+ description: "List of pending guest join requests waiting for host approval",
231
+ items: {
232
+ type: "object",
233
+ properties: {
234
+ tempUserId: { type: "string", description: "Temporary ID of requesting user" },
235
+ username: { type: "string", description: "Username of requesting user" }
236
+ }
237
+ }
238
+ }
239
+ }
240
+ },
241
+ annotations: {
242
+ readOnlyHint: true,
243
+ destructiveHint: false,
244
+ audience: ["agent", "user"],
245
+ priority: 0.8
246
+ }
188
247
  },
189
248
  {
190
249
  name: "srift_close_session",
250
+ title: "Close Session",
191
251
  description: "Close the active session. Flushes E2EE keys, disconnects signaling, clears chat history.",
192
- inputSchema: { type: "object", properties: {} }
252
+ inputSchema: { type: "object", properties: {} },
253
+ outputSchema: {
254
+ type: "object",
255
+ properties: {
256
+ success: { type: "boolean", description: "True if session was closed cleanly" },
257
+ message: { type: "string", description: "Confirmation message" }
258
+ }
259
+ },
260
+ annotations: {
261
+ readOnlyHint: false,
262
+ destructiveHint: true,
263
+ audience: ["agent", "user"],
264
+ priority: 0.7
265
+ }
193
266
  },
194
267
  {
195
268
  name: "srift_approve_join",
269
+ title: "Approve Join Request",
196
270
  description: "Host-only. Approve a pending guest join request by their temp user ID.",
197
271
  inputSchema: {
198
272
  type: "object",
@@ -200,87 +274,261 @@ var init_core = __esm({
200
274
  tempUserId: { type: "string", description: "Temp user ID from session_status pendingJoins" }
201
275
  },
202
276
  required: ["tempUserId"]
277
+ },
278
+ outputSchema: {
279
+ type: "object",
280
+ properties: {
281
+ success: { type: "boolean", description: "True if guest was approved" },
282
+ tempUserId: { type: "string", description: "Approved user temporary ID" }
283
+ }
284
+ },
285
+ annotations: {
286
+ readOnlyHint: false,
287
+ destructiveHint: false,
288
+ audience: ["agent", "user"],
289
+ priority: 0.8
203
290
  }
204
291
  },
205
292
  {
206
293
  name: "srift_reject_join",
294
+ title: "Reject Join Request",
207
295
  description: "Host-only. Reject a pending guest join request.",
208
296
  inputSchema: {
209
297
  type: "object",
210
298
  properties: {
211
- tempUserId: { type: "string" },
212
- reason: { type: "string", description: "Optional rejection reason" }
299
+ tempUserId: { type: "string", description: "Temp user ID from session_status pendingJoins" },
300
+ reason: { type: "string", description: "Optional rejection reason message sent to guest" }
213
301
  },
214
302
  required: ["tempUserId"]
303
+ },
304
+ outputSchema: {
305
+ type: "object",
306
+ properties: {
307
+ success: { type: "boolean", description: "True if guest join request was rejected" },
308
+ tempUserId: { type: "string", description: "Rejected user temporary ID" }
309
+ }
310
+ },
311
+ annotations: {
312
+ readOnlyHint: false,
313
+ destructiveHint: true,
314
+ audience: ["agent", "user"],
315
+ priority: 0.7
215
316
  }
216
317
  },
217
318
  {
218
319
  name: "srift_kick_user",
320
+ title: "Kick Peer",
219
321
  description: "Host-only. Disconnect and ban a peer from the active room.",
220
322
  inputSchema: {
221
323
  type: "object",
222
- properties: { userId: { type: "string" } },
324
+ properties: {
325
+ userId: { type: "string", description: "User ID of the participant to disconnect and remove" }
326
+ },
223
327
  required: ["userId"]
328
+ },
329
+ outputSchema: {
330
+ type: "object",
331
+ properties: {
332
+ success: { type: "boolean", description: "True if peer was successfully kicked" },
333
+ userId: { type: "string", description: "ID of kicked peer" }
334
+ }
335
+ },
336
+ annotations: {
337
+ readOnlyHint: false,
338
+ destructiveHint: true,
339
+ audience: ["agent", "user"],
340
+ priority: 0.6
224
341
  }
225
342
  },
226
343
  {
227
344
  name: "srift_send_file",
345
+ title: "Send File in Session",
228
346
  description: "Offer a file to the connected peer in an existing session. The peer must accept with srift_accept_transfer. Returns a fileId for monitoring. Transport is auto-selected internally.",
229
347
  inputSchema: {
230
348
  type: "object",
231
349
  properties: {
232
- filePath: { type: "string", description: "Absolute path to the file on disk" }
350
+ filePath: { type: "string", description: "Absolute path to the file on local disk" }
233
351
  },
234
352
  required: ["filePath"]
353
+ },
354
+ outputSchema: {
355
+ type: "object",
356
+ properties: {
357
+ fileId: { type: "string", description: "Unique identifier for the offered file transfer" },
358
+ fileName: { type: "string", description: "Base filename of the offered file" },
359
+ fileSize: { type: "number", description: "Size of file in bytes" }
360
+ }
361
+ },
362
+ annotations: {
363
+ readOnlyHint: false,
364
+ destructiveHint: false,
365
+ audience: ["agent", "user"],
366
+ priority: 0.9
235
367
  }
236
368
  },
237
369
  {
238
370
  name: "srift_accept_transfer",
371
+ title: "Accept File Transfer",
239
372
  description: "Accept a pending file offer from the peer and start downloading.",
240
373
  inputSchema: {
241
374
  type: "object",
242
375
  properties: {
243
- fileId: { type: "string", description: "fileId from the inbound file_offer event" },
376
+ fileId: { type: "string", description: "fileId from the inbound file_offer event or transfer list" },
244
377
  saveDir: { type: "string", description: "Absolute path to destination directory (defaults to CWD)" }
245
378
  },
246
379
  required: ["fileId"]
380
+ },
381
+ outputSchema: {
382
+ type: "object",
383
+ properties: {
384
+ success: { type: "boolean", description: "True if transfer acceptance started successfully" },
385
+ fileId: { type: "string", description: "Accepted transfer ID" },
386
+ saveDir: { type: "string", description: "Destination directory path" }
387
+ }
388
+ },
389
+ annotations: {
390
+ readOnlyHint: false,
391
+ destructiveHint: false,
392
+ audience: ["agent", "user"],
393
+ priority: 0.9
247
394
  }
248
395
  },
249
396
  {
250
397
  name: "srift_list_transfers",
398
+ title: "List Active Transfers",
251
399
  description: "List all active and recent transfers with progress, speed, ETA, and status.",
252
- inputSchema: { type: "object", properties: {} }
400
+ inputSchema: { type: "object", properties: {} },
401
+ outputSchema: {
402
+ type: "object",
403
+ properties: {
404
+ transfers: {
405
+ type: "array",
406
+ description: "List of live or recent file transfers",
407
+ items: {
408
+ type: "object",
409
+ properties: {
410
+ fileId: { type: "string", description: "Transfer unique file ID" },
411
+ name: { type: "string", description: "Filename" },
412
+ size: { type: "number", description: "Size in bytes" },
413
+ progress: { type: "number", description: "Transfer percentage 0-100" },
414
+ status: { type: "string", description: "Transfer status (uploading, downloading, completed, failed)" },
415
+ speedKBps: { type: "number", description: "Current transfer speed in KB/s" },
416
+ etaSeconds: { type: "number", description: "Estimated remaining seconds" }
417
+ }
418
+ }
419
+ }
420
+ }
421
+ },
422
+ annotations: {
423
+ readOnlyHint: true,
424
+ destructiveHint: false,
425
+ audience: ["agent", "user"],
426
+ priority: 0.8
427
+ }
253
428
  },
254
429
  {
255
430
  name: "srift_quick_share",
431
+ title: "Quick Share File",
256
432
  description: 'One-shot helper: if no session is active, creates one; then seeds the file and returns a public DOWNLOAD URL (https://srift.app/d/<token>) the recipient can open in any browser or curl. No install needed on their side. Best for "AI wants to deliver a file to the user with zero ceremony".',
257
433
  inputSchema: {
258
434
  type: "object",
259
435
  properties: {
260
- filePath: { type: "string" },
261
- sessionName: { type: "string" }
436
+ filePath: { type: "string", description: "Absolute path to the file to deliver to the recipient" },
437
+ sessionName: { type: "string", description: "Optional session label for the transfer" }
262
438
  },
263
439
  required: ["filePath"]
440
+ },
441
+ outputSchema: {
442
+ type: "object",
443
+ properties: {
444
+ sessionId: { type: "string", description: "Associated session ID" },
445
+ fileId: { type: "string", description: "Transfer file ID" },
446
+ downloadUrl: { type: "string", description: "Public HTTP download URL for recipient" },
447
+ fileName: { type: "string", description: "Base filename" },
448
+ fileSize: { type: "number", description: "File size in bytes" }
449
+ },
450
+ required: ["downloadUrl"]
451
+ },
452
+ annotations: {
453
+ readOnlyHint: false,
454
+ destructiveHint: false,
455
+ audience: ["agent", "user"],
456
+ priority: 1
264
457
  }
265
458
  },
266
459
  {
267
460
  name: "srift_send_chat",
461
+ title: "Send Encrypted Chat",
268
462
  description: "Send an end-to-end encrypted (AES-256-GCM) chat message to the connected peer.",
269
463
  inputSchema: {
270
464
  type: "object",
271
- properties: { message: { type: "string" } },
465
+ properties: {
466
+ message: { type: "string", description: "Plaintext message string to encrypt and transmit" }
467
+ },
272
468
  required: ["message"]
469
+ },
470
+ outputSchema: {
471
+ type: "object",
472
+ properties: {
473
+ success: { type: "boolean", description: "True if message was sent" },
474
+ timestamp: { type: "string", description: "ISO 8601 transmission timestamp" }
475
+ }
476
+ },
477
+ annotations: {
478
+ readOnlyHint: false,
479
+ destructiveHint: false,
480
+ audience: ["agent", "user"],
481
+ priority: 0.8
273
482
  }
274
483
  },
275
484
  {
276
485
  name: "srift_chat_history",
486
+ title: "Read Chat History",
277
487
  description: "Read the locally-decrypted chat log for the current session.",
278
- inputSchema: { type: "object", properties: {} }
488
+ inputSchema: { type: "object", properties: {} },
489
+ outputSchema: {
490
+ type: "object",
491
+ properties: {
492
+ messages: {
493
+ type: "array",
494
+ description: "Decrypted message log for current session",
495
+ items: {
496
+ type: "object",
497
+ properties: {
498
+ sender: { type: "string", description: "Sender display name" },
499
+ message: { type: "string", description: "Decrypted plaintext content" },
500
+ timestamp: { type: "string", description: "ISO timestamp" }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ },
506
+ annotations: {
507
+ readOnlyHint: true,
508
+ destructiveHint: false,
509
+ audience: ["agent", "user"],
510
+ priority: 0.7
511
+ }
279
512
  },
280
513
  {
281
514
  name: "srift_read_state",
515
+ title: "Read Local State",
282
516
  description: "Return the raw .srift-state.json contents (session + active transfers snapshot). Useful for one-shot polling without subscribing to SSE.",
283
- inputSchema: { type: "object", properties: {} }
517
+ inputSchema: { type: "object", properties: {} },
518
+ outputSchema: {
519
+ type: "object",
520
+ properties: {
521
+ session: { type: "object", description: "Current session state snapshot" },
522
+ activeTransfers: { type: "array", description: "Live transfers array" },
523
+ lastUpdated: { type: "string", description: "Last state write timestamp" }
524
+ }
525
+ },
526
+ annotations: {
527
+ readOnlyHint: true,
528
+ destructiveHint: false,
529
+ audience: ["agent", "user"],
530
+ priority: 0.6
531
+ }
284
532
  }
285
533
  ];
286
534
  MCP_RESOURCES = [
@@ -2923,7 +3171,7 @@ var __filename = fileURLToPath2(import.meta.url);
2923
3171
  var __dirname = path3.dirname(__filename);
2924
3172
  var DAEMON_PORT3 = parseInt(process.env.SRIFT_DAEMON_PORT || "3822", 10);
2925
3173
  var DAEMON_URL3 = `http://127.0.0.1:${DAEMON_PORT3}`;
2926
- var CLI_VERSION = "2.2.14";
3174
+ var CLI_VERSION = "2.2.15";
2927
3175
  function parseDuration(s) {
2928
3176
  if (!s) return 0;
2929
3177
  const m = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)?$/i.exec(s.trim());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "srift-transfer",
3
- "version": "2.2.14",
3
+ "version": "2.2.15",
4
4
  "mcpName": "app.srift/srift",
5
5
  "description": "Zero-config, zero-token peer-to-peer secure file transfer, encrypted chat, and Model Context Protocol (MCP) server for AI coding agents (Claude, Cursor, Windsurf, Continue, Zed) and developers. End-to-end AES-256-GCM encrypted.",
6
6
  "keywords": [