srift-transfer 2.2.14 → 3.0.0

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,8 @@
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)
8
+ [![Glama](https://img.shields.io/badge/Glama-app.srift%2Fsrift-blueviolet.svg)](https://glama.ai/mcp/connectors/app.srift/srift)
7
9
  [![Encryption: AES-256-GCM](https://img.shields.io/badge/Encryption-AES--256--GCM-green.svg)](https://srift.app)
8
10
  [![Zero Telemetry](https://img.shields.io/badge/telemetry-zero-success.svg)](https://srift.app/privacy)
9
11
 
@@ -334,6 +336,19 @@ First-party, zero-dependency SDKs for accessing SRIFT from any programming langu
334
336
  - **LLM Context (`llms.txt`)**: [https://srift.app/llms.txt](https://srift.app/llms.txt)
335
337
  - **Bug Tracker & Issues**: [https://github.com/srivardhan113/SRIFT-Open_Source/issues](https://github.com/srivardhan113/SRIFT-Open_Source/issues)
336
338
 
339
+ ### Official Listings
340
+
341
+ | Surface | Link |
342
+ |---|---|
343
+ | npm | [`srift-transfer`](https://www.npmjs.com/package/srift-transfer) |
344
+ | MCP Registry | [`app.srift/srift`](https://registry.modelcontextprotocol.io/v0/servers?search=srift) |
345
+ | Smithery | [`srift/srift`](https://smithery.ai/servers/srift/srift) |
346
+ | Glama (connector) | [`app.srift/srift`](https://glama.ai/mcp/connectors/app.srift/srift) |
347
+ | Glama (server) | [`SRIFT-Open_Source`](https://glama.ai/mcp/servers/srivardhan113/SRIFT-Open_Source) |
348
+ | GitHub | [`SRIFT-Open_Source`](https://github.com/srivardhan113/SRIFT-Open_Source) |
349
+
350
+ All resolve to the same product. Install `srift-transfer`; the command is `srift`.
351
+
337
352
  ---
338
353
 
339
354
  ## 📄 License
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 = [
@@ -402,7 +650,7 @@ var DAEMON_URL = `http://127.0.0.1:${DAEMON_PORT}`;
402
650
  var SERVER_INFO = {
403
651
  name: "srift-mcp-server",
404
652
  title: "SRIFT Secure P2P File Transfer",
405
- version: "2.0.0"
653
+ version: "3.0.0"
406
654
  };
407
655
  function callDaemon(endpoint, method, body) {
408
656
  return new Promise((resolve, reject) => {
@@ -1292,7 +1540,7 @@ var app = express();
1292
1540
  app.use(cors());
1293
1541
  app.use(express.json());
1294
1542
  var DAEMON_START_TIME = Date.now();
1295
- var PACKAGE_VERSION = "2.1.8";
1543
+ var PACKAGE_VERSION = "3.0.0";
1296
1544
  app.get("/health", (req, res) => {
1297
1545
  res.json({
1298
1546
  ok: true,
@@ -2001,7 +2249,7 @@ app.get("/.well-known/mcp/server-card.json", (req, res) => {
2001
2249
  $schema: "https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",
2002
2250
  version: "1.0",
2003
2251
  protocolVersion: "2025-06-18",
2004
- serverInfo: { name: "SRIFT MCP Server (local daemon)", version: "2.0.0" },
2252
+ serverInfo: { name: "SRIFT MCP Server (local daemon)", version: PACKAGE_VERSION },
2005
2253
  capabilities: { tools: {}, resources: {}, prompts: {} },
2006
2254
  transport: [
2007
2255
  { type: "streamable-http", url: `http://127.0.0.1:${PORT}/mcp` },
@@ -2032,7 +2280,7 @@ app.get("/.well-known/agent.json", (req, res) => {
2032
2280
  name: "SRIFT",
2033
2281
  description: "Zero-config P2P E2EE file transfer + chat for any AI agent or automation.",
2034
2282
  url: `http://127.0.0.1:${PORT}`,
2035
- version: "2.0.0",
2283
+ version: PACKAGE_VERSION,
2036
2284
  capabilities: {
2037
2285
  streaming: true,
2038
2286
  pushNotifications: false,
@@ -2046,7 +2294,7 @@ app.get("/.well-known/agent.json", (req, res) => {
2046
2294
  app.get("/openapi.json", (req, res) => {
2047
2295
  res.json({
2048
2296
  openapi: "3.1.0",
2049
- info: { title: "SRIFT Local Daemon API", version: "2.1.8", description: "Zero-auth REST API for AI agents to drive SRIFT P2P transfer." },
2297
+ info: { title: "SRIFT Local Daemon API", version: PACKAGE_VERSION, description: "Zero-auth REST API for AI agents to drive SRIFT P2P transfer." },
2050
2298
  servers: [{ url: `http://127.0.0.1:${PORT}` }],
2051
2299
  paths: {
2052
2300
  "/health": { get: { summary: "Liveness probe", description: "Returns {ok,version,uptime_ms,mcp,webrtc,webtorrent}", responses: { "200": { description: "OK" } } } },
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 = [
@@ -566,7 +814,7 @@ var init_mcp = __esm({
566
814
  SERVER_INFO = {
567
815
  name: "srift-mcp-server",
568
816
  title: "SRIFT Secure P2P File Transfer",
569
- version: "2.0.0"
817
+ version: "3.0.0"
570
818
  };
571
819
  localDaemonBackend = { callTool, readResource };
572
820
  handleMcpMessage = createMcpHandler({
@@ -1482,7 +1730,7 @@ var init_daemon = __esm({
1482
1730
  app.use(cors());
1483
1731
  app.use(express.json());
1484
1732
  DAEMON_START_TIME = Date.now();
1485
- PACKAGE_VERSION = "2.1.8";
1733
+ PACKAGE_VERSION = "3.0.0";
1486
1734
  app.get("/health", (req, res) => {
1487
1735
  res.json({
1488
1736
  ok: true,
@@ -2048,7 +2296,7 @@ data: /mcp/messages
2048
2296
  $schema: "https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",
2049
2297
  version: "1.0",
2050
2298
  protocolVersion: "2025-06-18",
2051
- serverInfo: { name: "SRIFT MCP Server (local daemon)", version: "2.0.0" },
2299
+ serverInfo: { name: "SRIFT MCP Server (local daemon)", version: PACKAGE_VERSION },
2052
2300
  capabilities: { tools: {}, resources: {}, prompts: {} },
2053
2301
  transport: [
2054
2302
  { type: "streamable-http", url: `http://127.0.0.1:${PORT}/mcp` },
@@ -2079,7 +2327,7 @@ data: /mcp/messages
2079
2327
  name: "SRIFT",
2080
2328
  description: "Zero-config P2P E2EE file transfer + chat for any AI agent or automation.",
2081
2329
  url: `http://127.0.0.1:${PORT}`,
2082
- version: "2.0.0",
2330
+ version: PACKAGE_VERSION,
2083
2331
  capabilities: {
2084
2332
  streaming: true,
2085
2333
  pushNotifications: false,
@@ -2093,7 +2341,7 @@ data: /mcp/messages
2093
2341
  app.get("/openapi.json", (req, res) => {
2094
2342
  res.json({
2095
2343
  openapi: "3.1.0",
2096
- info: { title: "SRIFT Local Daemon API", version: "2.1.8", description: "Zero-auth REST API for AI agents to drive SRIFT P2P transfer." },
2344
+ info: { title: "SRIFT Local Daemon API", version: PACKAGE_VERSION, description: "Zero-auth REST API for AI agents to drive SRIFT P2P transfer." },
2097
2345
  servers: [{ url: `http://127.0.0.1:${PORT}` }],
2098
2346
  paths: {
2099
2347
  "/health": { get: { summary: "Liveness probe", description: "Returns {ok,version,uptime_ms,mcp,webrtc,webtorrent}", responses: { "200": { description: "OK" } } } },
@@ -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 = "3.0.0";
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": "3.0.0",
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": [