@fileverse/api 0.0.20 → 0.0.21

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/public/llm.txt CHANGED
@@ -1,347 +1,621 @@
1
1
  # Fileverse API - AI Agent Guide
2
2
 
3
- > Fileverse API lets you create, manage, and publish documents to blockchain. This guide helps you (the AI agent) get connected and start working with documents.
3
+ > Fileverse API is a document management system by Fileverse that stores and syncs documents (ddocs) between a local database and blockchain.
4
4
 
5
- ## Step 1: Connect via MCP (Recommended)
5
+ **Skill Name**: fileverse-api
6
6
 
7
- The fastest way to start is by adding the Fileverse MCP server to your client. Ask the user to add the following configuration to their AI tool:
7
+ ## How to use this document
8
8
 
9
- ### Claude Code
9
+ Fetch this via GET {SERVER_URL}/llm.txt. Use it to discover the server URL, decide API vs CLI mode, then follow the relevant section below.
10
10
 
11
- Run this command, replacing the placeholder values:
11
+ ## Integration checklist
12
12
 
13
- ```bash
14
- claude mcp add fileverse-api -- npx -y @anthropic-ai/mcp-proxy@latest --endpoint "YOUR_SERVER_URL/mcp" --header "x-api-key: YOUR_API_KEY"
15
- ```
13
+ 1. Get server URL (from the URL you used to fetch this doc, minus /llm.txt) and apiKey (see API Key Configuration).
14
+ 2. Try GET {SERVER_URL}/ping. If you get 200 and {"reply":"pong"}, use API mode; otherwise use CLI mode.
15
+ 3. In API mode: every request must include apiKey as a query parameter; the path is complete before any query string.
16
+ 4. For create/update: extract ddocId from response.data.ddocId (not from the top level of the response).
17
+ 5. After create or update, poll GET /api/ddocs/{ddocId}?apiKey=... until syncStatus is "synced" or "failed", then show the link if synced.
18
+
19
+ ## Server URL
20
+
21
+ If you fetched this document from a URL (e.g., http://localhost:8001/llm.txt):
22
+ - Your server URL is that URL without the /llm.txt suffix
23
+ - Example: http://localhost:8001/llm.txt → Server URL is http://localhost:8001
24
+
25
+ If this document was provided another way, ask the user for their server URL.
26
+
27
+ ## API Key Configuration
28
+
29
+ Before starting, check for stored credentials:
30
+
31
+ 1. Look for config file at: ~/.fileverseapirc
32
+ 2. If found with valid apiKey, use it automatically
33
+ 3. If not found or missing apiKey:
34
+ - Ask user for their Fileverse API key
35
+ - Offer to save it: "Would you like me to save this API key for future sessions?"
36
+ - If yes, create/update ~/.fileverseapirc with JSON: {"apiKey": "...", "serverUrl": "..."}
37
+
38
+ ## Connection Strategy
39
+
40
+ After getting the server URL:
41
+
42
+ 1. **Try API first**: Attempt GET {SERVER_URL}/ping
43
+ 2. **If successful** (response: {"reply":"pong"}) → Use API Mode
44
+ 3. **If connection fails** (timeout, refused, unreachable) → Switch to CLI Mode
45
+
46
+ In API mode, every request must include apiKey as a query parameter; the path is complete before any query string.
47
+
48
+ When switching to CLI mode, inform the user:
49
+ "I can't reach your server directly (localhost isn't accessible from here). I'll help you using CLI commands instead - just run them and share the output with me."
50
+
51
+ ---
52
+
53
+ # Quick reference
54
+
55
+ ## All API endpoints
56
+
57
+ | Method | Path | Auth | Key params/body |
58
+ |--------|------|------|-----------------|
59
+ | GET | /ping | No | - |
60
+ | GET | /api/ddocs | apiKey | limit, skip |
61
+ | GET | /api/ddocs/{ddocId} | apiKey | - |
62
+ | POST | /api/ddocs | apiKey | JSON: {title, content} or form-data: file |
63
+ | PUT | /api/ddocs/{ddocId} | apiKey | JSON: {title?, content?} or form-data: file |
64
+ | DELETE | /api/ddocs/{ddocId} | apiKey | - |
65
+ | GET | /api/folders | apiKey | limit, skip |
66
+ | POST | /api/folders | apiKey | body: see Create Folder |
67
+ | GET | /api/folders/{folderRef}/{folderId} | apiKey | - |
68
+ | GET | /api/search | apiKey | q (required), limit, skip |
69
+ | GET | /api/events/failed | apiKey | - |
70
+ | POST | /api/events/retry-failed | apiKey | - |
71
+ | POST | /api/events/{id}/retry | apiKey | - |
72
+
73
+ ## All ddctl commands
74
+
75
+ | Command | Purpose | Key options |
76
+ |---------|---------|-------------|
77
+ | ddctl list | List ddocs | -l/--limit, -s/--skip |
78
+ | ddctl get <ddocId> | Get document metadata | - |
79
+ | ddctl view <ddocId> | View content preview | -n/--lines (default 10) |
80
+ | ddctl create <filepath> | Create from file | title = filename; file cannot be empty |
81
+ | ddctl update <ddocId> | Update ddoc | -f/--file <path> or opens editor |
82
+ | ddctl download <ddocId> | Download to file | -o/--output <filename> |
83
+ | ddctl delete <ddocIds...> | Delete one or more | space-separated ids |
84
+ | ddctl events list-failed | List failed worker events | - |
85
+ | ddctl events retry <eventId> | Retry one failed event | - |
86
+ | ddctl events retry-all | Retry all failed events | - |
87
+
88
+ ---
89
+
90
+ # MCP Integration (Recommended for AI Agents)
91
+
92
+ The Fileverse API MCP server is the easiest way for AI agents to interact with Fileverse API. It wraps all API calls into native MCP tools with built-in sync polling.
16
93
 
17
- Or add to `.claude/mcp.json`:
94
+ ## Setup
95
+
96
+ Install Fileverse API globally, then configure your MCP client:
97
+
98
+ ### Claude Code / Cursor
99
+
100
+ Add to your MCP config (e.g., `.claude/mcp.json` or Cursor MCP settings):
18
101
 
19
102
  ```json
20
103
  {
21
104
  "mcpServers": {
22
105
  "fileverse-api": {
23
- "command": "npx",
24
- "args": ["-y", "@anthropic-ai/mcp-proxy@latest", "--endpoint", "YOUR_SERVER_URL/mcp", "--header", "x-api-key: YOUR_API_KEY"]
106
+ "command": "fileverse-api-mcp",
107
+ "env": {
108
+ "FILEVERSE_API_KEY": "your-api-key",
109
+ "FILEVERSE_SERVER_URL": "http://localhost:8001"
110
+ }
25
111
  }
26
112
  }
27
113
  }
28
114
  ```
29
115
 
30
- ### Cursor
116
+ The MCP server can also read credentials from `~/.fileverseapirc` if env vars are not set.
31
117
 
32
- Add to Cursor MCP settings (`.cursor/mcp.json`):
118
+ ## Available MCP Tools
33
119
 
34
- ```json
120
+ | Tool | Description |
121
+ |------|-------------|
122
+ | fileverse_list_documents | List documents with pagination |
123
+ | fileverse_get_document | Get a single document by ddocId |
124
+ | fileverse_create_document | Create document and wait for sync (returns link) |
125
+ | fileverse_update_document | Update document and wait for sync (returns link) |
126
+ | fileverse_delete_document | Delete a document |
127
+ | fileverse_search_documents | Search documents by text query |
128
+ | fileverse_get_sync_status | Check sync status and link of a document |
129
+ | fileverse_retry_failed_events | Retry all failed blockchain sync events |
130
+
131
+ Create and update tools automatically poll until blockchain sync completes, so the agent does not need to implement polling logic.
132
+
133
+ ---
134
+
135
+ # Response Schemas
136
+
137
+ ## Document
138
+
139
+ Fields returned by GET /api/ddocs/{ddocId} and in list/search results:
140
+
141
+ ```
35
142
  {
36
- "mcpServers": {
37
- "fileverse-api": {
38
- "command": "npx",
39
- "args": ["-y", "@anthropic-ai/mcp-proxy@latest", "--endpoint", "YOUR_SERVER_URL/mcp", "--header", "x-api-key: YOUR_API_KEY"]
40
- }
41
- }
143
+ ddocId: string, // Unique document identifier
144
+ title: string, // Document title
145
+ content: string, // Document content (text/markdown)
146
+ syncStatus: "pending" | "synced" | "failed",
147
+ link: string | null, // Public URL (only when syncStatus is "synced")
148
+ localVersion: number, // Increments on each local edit
149
+ onchainVersion: number, // Version published to blockchain
150
+ isDeleted: number, // 0 = active, 1 = deleted
151
+ onChainFileId: number | null,
152
+ portalAddress: string,
153
+ createdAt: string, // ISO timestamp
154
+ updatedAt: string // ISO timestamp
42
155
  }
43
156
  ```
44
157
 
45
- ### Windsurf
158
+ ## Document List
46
159
 
47
- Add to `~/.codeium/windsurf/mcp_config.json`:
160
+ Returned by GET /api/ddocs:
48
161
 
49
- ```json
162
+ ```
50
163
  {
51
- "mcpServers": {
52
- "fileverse-api": {
53
- "command": "npx",
54
- "args": ["-y", "@anthropic-ai/mcp-proxy@latest", "--endpoint", "YOUR_SERVER_URL/mcp", "--header", "x-api-key: YOUR_API_KEY"]
55
- }
56
- }
164
+ ddocs: Document[],
165
+ total: number,
166
+ hasNext: boolean
57
167
  }
58
168
  ```
59
169
 
60
- ### ChatGPT (Desktop)
170
+ ## Search Result
61
171
 
62
- Go to Settings > MCP Servers > Add Server, then enter:
172
+ Returned by GET /api/search:
63
173
 
64
- - **Name**: fileverse-api
65
- - **Command**: `npx -y @anthropic-ai/mcp-proxy@latest --endpoint "YOUR_SERVER_URL/mcp" --header "x-api-key: YOUR_API_KEY"`
174
+ ```
175
+ {
176
+ nodes: Document[], // Note: "nodes" not "ddocs"
177
+ total: number,
178
+ hasNext: boolean
179
+ }
180
+ ```
66
181
 
67
- ### Any MCP-compatible client
182
+ ## Create/Update Response
68
183
 
69
- The Fileverse API exposes an MCP endpoint at `{SERVER_URL}/mcp`. Connect using any MCP client that supports the Streamable HTTP transport. Pass the API key via the `x-api-key` header.
184
+ Returned by POST /api/ddocs and PUT /api/ddocs/{ddocId}:
70
185
 
71
- ### Replacing placeholders
186
+ ```
187
+ {
188
+ message: string,
189
+ data: Document // Extract ddocId from data.ddocId
190
+ }
191
+ ```
72
192
 
73
- - **YOUR_SERVER_URL**: The base URL of the Fileverse API server (e.g., `http://localhost:8001`). If the user shared this document via a URL, strip `/llm.txt` to get the server URL.
74
- - **YOUR_API_KEY**: The user's Fileverse API key. Check `~/.fileverseapirc` for stored credentials, or ask the user to provide it.
193
+ ## Event
75
194
 
76
- ### After adding the MCP server
195
+ Returned by GET /api/events/failed:
77
196
 
78
- Restart or reload the AI tool. You will then have access to these tools:
197
+ ```
198
+ {
199
+ _id: string,
200
+ type: "create" | "update" | "delete",
201
+ timestamp: number,
202
+ fileId: string,
203
+ portalAddress: string,
204
+ status: "pending" | "processing" | "processed" | "failed",
205
+ retryCount: number,
206
+ lastError: string | null,
207
+ userOpHash: string | null
208
+ }
209
+ ```
79
210
 
80
- | Tool | Description |
81
- |------|-------------|
82
- | `fileverse_list_documents` | List documents with pagination |
83
- | `fileverse_get_document` | Get a single document by ddocId |
84
- | `fileverse_create_document` | Create document and wait for blockchain sync (returns link) |
85
- | `fileverse_update_document` | Update document and wait for blockchain sync (returns link) |
86
- | `fileverse_delete_document` | Delete a document |
87
- | `fileverse_search_documents` | Search documents by text query |
88
- | `fileverse_get_sync_status` | Check sync status and blockchain link of a document |
89
- | `fileverse_retry_failed_events` | Retry all failed blockchain sync events |
211
+ ---
90
212
 
91
- Create and update tools automatically poll until blockchain sync completes, so you do not need to implement polling logic. Once synced, the response includes a public `link` to the document.
213
+ # CLI MODE (Fallback when server unreachable)
92
214
 
93
- ---
215
+ Use this when you cannot reach the user's server (localhost, firewall, etc.).
216
+ You generate commands, user runs them and shares output with you.
94
217
 
95
- ## Step 2 (Alternative): Use the REST API directly
218
+ ## Installation and invocation
96
219
 
97
- If MCP is not available in your environment, you can call the REST API directly.
220
+ To set up Fileverse API and run the server:
221
+
222
+ ```bash
223
+ npm install -g @fileverse/api
224
+ npx @fileverse/api --apiKey <key> --rpcUrl <url>
225
+ ```
98
226
 
99
- ### Server URL
227
+ The package exposes the ddctl binary. After npm install -g @fileverse/api, run ddctl <command>. Without global install: npx -p @fileverse/api ddctl <command>.
100
228
 
101
- If this document was fetched from a URL (e.g., `http://localhost:8001/llm.txt`), the server URL is that URL without `/llm.txt`.
229
+ ## CLI Commands Reference
102
230
 
103
- ### Authentication
231
+ ### List Documents
232
+ ```bash
233
+ ddctl list
234
+ ddctl list -l 10 -s 20
235
+ ddctl list --limit 10 --skip 20
236
+ ```
104
237
 
105
- Every API request requires an `apiKey` query parameter appended to the URL:
238
+ ### Get Document Details
239
+ ```bash
240
+ ddctl get <ddocId>
241
+ ```
242
+ Shows metadata including the link (if synced to blockchain).
243
+
244
+ ### View Document Content
245
+ ```bash
246
+ ddctl view <ddocId>
247
+ ddctl view <ddocId> -n 20
248
+ ddctl view <ddocId> --lines 20
249
+ ```
250
+ Default preview is 10 lines.
251
+
252
+ ### Create Document
253
+ ```bash
254
+ ddctl create <filepath>
255
+ ```
256
+ Creates document from file. Title is derived from filename. File content cannot be empty.
257
+
258
+ ### Update Document
259
+ ```bash
260
+ ddctl update <ddocId> -f <filepath>
261
+ ddctl update <ddocId> --file <filepath>
262
+ ddctl update <ddocId>
263
+ ```
264
+ Without --file opens in editor (uses EDITOR env or vi).
106
265
 
266
+ ### Download Document
267
+ ```bash
268
+ ddctl download <ddocId>
269
+ ddctl download <ddocId> -o myfile.md
270
+ ddctl download <ddocId> --output myfile.md
107
271
  ```
108
- {SERVER_URL}{PATH}?apiKey={API_KEY}
272
+ Output supports markdown.
273
+
274
+ ### Delete Document
275
+ ```bash
276
+ ddctl delete <ddocId>
277
+ ddctl delete <id1> <id2> <id3>
109
278
  ```
279
+ One or more space-separated ddoc IDs.
110
280
 
111
- Check `~/.fileverseapirc` for stored credentials (JSON with `apiKey` and `serverUrl` fields). If not found, ask the user.
281
+ ### Worker events
282
+ ```bash
283
+ ddctl events list-failed
284
+ ddctl events retry <eventId>
285
+ ddctl events retry-all
286
+ ```
287
+ If sync is stuck, run ddctl events list-failed then ddctl events retry <id> or ddctl events retry-all.
112
288
 
113
- ### Verify connectivity
289
+ ## CLI Workflow Examples
114
290
 
291
+ ### Create and Check Sync Status
292
+ ```bash
293
+ ddctl create mydocument.md
294
+ ddctl get <ddocId>
115
295
  ```
116
- GET {SERVER_URL}/ping
296
+ Repeat get until syncStatus is "synced"; then the link field shows the public URL.
297
+
298
+ ### Search and Update
299
+ ```bash
300
+ ddctl list
301
+ ddctl view <ddocId>
302
+ ddctl update <ddocId> --file updated.md
303
+ ddctl get <ddocId>
117
304
  ```
118
305
 
119
- Expected response: `{"reply":"pong"}`
306
+ ---
120
307
 
121
- ### API Endpoints
308
+ # API MODE (Primary - when server is reachable)
122
309
 
123
- | Method | Path | Description |
124
- |--------|------|-------------|
125
- | GET | /ping | Health check (no auth) |
126
- | GET | /api/ddocs?apiKey=...&limit=10&skip=0 | List documents |
127
- | GET | /api/ddocs/{ddocId}?apiKey=... | Get one document |
128
- | POST | /api/ddocs?apiKey=... | Create document (JSON body: `{title, content}`) |
129
- | PUT | /api/ddocs/{ddocId}?apiKey=... | Update document (JSON body: `{title?, content?}`) |
130
- | DELETE | /api/ddocs/{ddocId}?apiKey=... | Delete document |
131
- | GET | /api/search?apiKey=...&q={query} | Search documents |
132
- | GET | /api/events/failed?apiKey=... | List failed sync events |
133
- | POST | /api/events/retry-failed?apiKey=... | Retry all failed events |
134
- | POST | /api/events/{id}/retry?apiKey=... | Retry one failed event |
310
+ Use this when GET /ping succeeds. You make HTTP requests directly to the server.
135
311
 
136
- ### Sync Status Polling (Required for REST API)
312
+ ## Authentication & URL Construction
137
313
 
138
- When using the REST API (not MCP), you must poll after create/update:
314
+ CRITICAL: The apiKey is a query parameter that goes at the END of the URL, after the complete path.
139
315
 
140
- 1. Send POST or PUT request
141
- 2. Extract `ddocId` from `response.data.ddocId` (not from the top level)
142
- 3. Poll `GET /api/ddocs/{ddocId}?apiKey=...` every 5 seconds
143
- 4. When `syncStatus` is `"synced"`: show the `link` field to the user
144
- 5. When `syncStatus` is `"failed"`: inform the user and suggest retrying
316
+ URL Structure: {SERVER_URL}{PATH}?apiKey={API_KEY}&{OTHER_PARAMS}
145
317
 
146
- ### URL Construction (Common Mistake)
318
+ Step-by-step URL construction:
319
+ 1. Start with the server URL: http://localhost:8001
320
+ 2. Add the complete path: /api/ddocs/abc123
321
+ 3. Add ? and the apiKey: ?apiKey=your-key
322
+ 4. Add any other params with &: &limit=10
147
323
 
148
- The `apiKey` query parameter must come AFTER the complete path:
324
+ CORRECT examples:
325
+ - GET http://localhost:8001/api/ddocs?apiKey=xxx
326
+ - GET http://localhost:8001/api/ddocs/abc123?apiKey=xxx
327
+ - PUT http://localhost:8001/api/ddocs/abc123?apiKey=xxx
328
+ - GET http://localhost:8001/api/ddocs?apiKey=xxx&limit=10&skip=0
149
329
 
150
- ```
151
- CORRECT: GET http://localhost:8001/api/ddocs/abc123?apiKey=xxx
152
- WRONG: GET http://localhost:8001/api/ddocs?apiKey=xxx/abc123
153
- ```
330
+ WRONG (do NOT do this):
331
+ - GET http://localhost:8001/api/ddocs?apiKey=xxx/abc123 ← WRONG: path after query param
332
+ - GET http://localhost:8001/api?apiKey=xxx/ddocs/abc123 ← WRONG: path after query param
154
333
 
155
- ---
334
+ The query string (?apiKey=...) must ALWAYS come after the full path is complete.
156
335
 
157
- ## Step 3 (Fallback): CLI Mode
336
+ ## Common mistakes
158
337
 
159
- If you cannot reach the server (e.g., localhost is not accessible), generate CLI commands for the user to run.
338
+ - Putting path segments after ?apiKey=... (wrong).
339
+ - Forgetting that create/update return data.ddocId, not top-level ddocId; always use response.data.ddocId.
340
+ - Not polling after create/update until syncStatus is "synced" or "failed".
160
341
 
161
- ### Installation
342
+ ## Important: Sync Status Polling
162
343
 
163
- ```bash
164
- npm install -g @fileverse/api
165
- ```
344
+ When you create or update a document, it syncs to blockchain asynchronously:
166
345
 
167
- ### Commands
168
-
169
- | Command | Purpose |
170
- |---------|---------|
171
- | `ddctl list` | List documents (`-l`/`--limit`, `-s`/`--skip`) |
172
- | `ddctl get <ddocId>` | Get document metadata |
173
- | `ddctl view <ddocId>` | Preview content (`-n`/`--lines`, default 10) |
174
- | `ddctl create <filepath>` | Create from file (title = filename) |
175
- | `ddctl update <ddocId> -f <filepath>` | Update from file |
176
- | `ddctl download <ddocId>` | Download document (`-o`/`--output`) |
177
- | `ddctl delete <ddocId> [...]` | Delete one or more documents |
178
- | `ddctl events list-failed` | List failed sync events |
179
- | `ddctl events retry <eventId>` | Retry one failed event |
180
- | `ddctl events retry-all` | Retry all failed events |
346
+ - **pending**: Saved locally, blockchain sync in progress
347
+ - **synced**: Published to blockchain (link field available)
348
+ - **failed**: Sync failed
181
349
 
182
- ---
350
+ After CREATE or UPDATE, poll until syncStatus is "synced" or "failed":
183
351
 
184
- # Response Schemas
352
+ 1. POST /api/ddocs or PUT /api/ddocs/{id}
353
+ 2. Extract ddocId from response.data.ddocId (not from the top level)
354
+ 3. Poll: GET /api/ddocs/{ddocId}?apiKey={API_KEY}
355
+ 4. If "pending", wait 5 seconds and poll again
356
+ 5. If "synced": extract the "link" field and show as clickable: [View Document](link)
357
+ 6. If "failed", inform user of sync failure
185
358
 
186
- ## Document
359
+ Typical sync time: 5-30 seconds.
187
360
 
188
- ```json
361
+ ## API Reference
362
+
363
+ Base: {SERVER_URL}
364
+
365
+ ### Health Check (No Auth)
366
+ GET /ping
367
+ Response: {"reply":"pong"}
368
+
369
+ ### List Documents
370
+ GET /api/ddocs?apiKey={API_KEY}&limit=10&skip=0
371
+
372
+ Response:
189
373
  {
190
- "ddocId": "string",
191
- "title": "string",
192
- "content": "string",
193
- "syncStatus": "pending | synced | failed",
194
- "link": "string | null",
195
- "localVersion": 0,
196
- "onchainVersion": 0,
197
- "isDeleted": 0,
198
- "onChainFileId": null,
199
- "portalAddress": "string",
200
- "createdAt": "ISO timestamp",
201
- "updatedAt": "ISO timestamp"
374
+ "ddocs": [...],
375
+ "total": 100,
376
+ "hasNext": true
202
377
  }
203
- ```
204
378
 
205
- ## List Response
379
+ ### Get Document
380
+ GET /api/ddocs/{ddocId}?apiKey={API_KEY}
206
381
 
207
- ```json
208
- { "ddocs": [...], "total": 100, "hasNext": true }
209
- ```
382
+ Response:
383
+ {
384
+ "ddocId": "...",
385
+ "title": "...",
386
+ "content": "...",
387
+ "syncStatus": "pending|synced|failed",
388
+ "link": "https://...",
389
+ ...
390
+ }
391
+ (link available when synced)
210
392
 
211
- ## Search Response
393
+ ### Create Document (JSON - recommended for AI agents)
394
+ POST /api/ddocs?apiKey={API_KEY}
395
+ Content-Type: application/json
212
396
 
213
- ```json
214
- { "nodes": [...], "total": 100, "hasNext": true }
215
- ```
397
+ { "title": "Document Title", "content": "Document content here..." }
216
398
 
217
- Note: search returns `nodes`, not `ddocs`.
399
+ Response: 201 with { "message": "...", "data": { "ddocId": "...", "title": "...", "syncStatus": "...", ... } }
400
+ Extract ddocId from response.data.ddocId. Then poll GET /api/ddocs/{ddocId} until syncStatus is "synced", then show the link.
218
401
 
219
- ## Create/Update Response
402
+ ### Create Document (Multipart - for file uploads)
403
+ POST /api/ddocs?apiKey={API_KEY}
404
+ Content-Type: multipart/form-data
220
405
 
221
- ```json
222
- { "message": "...", "data": { "ddocId": "...", ... } }
223
- ```
406
+ Send a single form field "file" with the document file. Title is derived from the filename. Max file size 10MB.
407
+
408
+ Response: same as JSON create above.
409
+
410
+ ### Update Document (JSON - recommended for AI agents)
411
+ PUT /api/ddocs/{ddocId}?apiKey={API_KEY}
412
+ Content-Type: application/json
413
+
414
+ { "title": "New Title", "content": "Updated content..." }
415
+
416
+ Both fields are optional; send only what you want to change.
417
+
418
+ Response: 200 with { "message": "...", "data": { ... } }
419
+ Poll until synced, then show the link.
420
+
421
+ ### Update Document (Multipart - for file uploads)
422
+ PUT /api/ddocs/{ddocId}?apiKey={API_KEY}
423
+ Content-Type: multipart/form-data
224
424
 
225
- Extract ddocId from `data.ddocId`.
425
+ Send a single form field "file" with the updated document file. Title is derived from the filename. Max file size 10MB.
426
+
427
+ Response: same as JSON update above.
428
+
429
+ ### Delete Document
430
+ DELETE /api/ddocs/{ddocId}?apiKey={API_KEY}
431
+
432
+ ### List Folders
433
+ GET /api/folders?apiKey={API_KEY}&limit=10&skip=0
434
+
435
+ Response:
436
+ {
437
+ "folders": [...],
438
+ "total": 100,
439
+ "hasNext": true
440
+ }
441
+
442
+ ### Create Folder
443
+ POST /api/folders?apiKey={API_KEY}
444
+ Content-Type: application/json
445
+
446
+ Required body fields: onchainFileId, folderId, folderRef, folderName, portalAddress, metadataIPFSHash, lastTransactionBlockNumber, lastTransactionBlockTimestamp.
447
+ Typically used for sync/on-chain integration, not ad-hoc folder creation by agents.
448
+
449
+ ### Get Folder
450
+ GET /api/folders/{folderRef}/{folderId}?apiKey={API_KEY}
451
+ Both folderRef and folderId are required.
452
+
453
+ ### Search Documents
454
+ GET /api/search?apiKey={API_KEY}&q={query}&limit=10&skip=0
455
+ Query parameter "q" is required.
456
+
457
+ Response:
458
+ {
459
+ "nodes": [...],
460
+ "total": 100,
461
+ "hasNext": true
462
+ }
463
+ (Search returns "nodes", not "ddocs".)
464
+
465
+ ### List Failed Events
466
+ GET /api/events/failed?apiKey={API_KEY}
467
+
468
+ Response: array of events (e.g. _id, fileId, portalAddress, type, timestamp, lastError).
469
+
470
+ ### Retry All Failed Events
471
+ POST /api/events/retry-failed?apiKey={API_KEY}
472
+
473
+ Response: { "retried": number }
474
+
475
+ ### Retry One Failed Event
476
+ POST /api/events/{id}/retry?apiKey={API_KEY}
477
+
478
+ Response: { "ok": true } or 404 if event not found or not in failed state.
479
+
480
+ ## OpenAPI Specification
481
+
482
+ A machine-readable OpenAPI 3.1 spec is available at GET {SERVER_URL}/openapi.json. Use it for auto-generating tool definitions or importing into Swagger UI / Postman.
226
483
 
227
484
  ---
228
485
 
229
- # Key Concepts
486
+ # Agent Workflow Recipes
230
487
 
231
- - **DDoc**: A document with a unique `ddocId`
232
- - **syncStatus**: `pending` (saving to blockchain) -> `synced` (published, `link` available) or `failed`
233
- - **link**: Public URL to view the document on-chain (only present when synced)
234
- - **localVersion**: Increments on each local edit
235
- - **onchainVersion**: Version published to blockchain
488
+ ## Recipe 1: Publish a local file to blockchain
236
489
 
237
- # Error Handling
490
+ 1. Read the file content from the local filesystem
491
+ 2. POST /api/ddocs?apiKey={API_KEY} with JSON body: {"title": "<filename>", "content": "<file content>"}
492
+ 3. Extract ddocId from response.data.ddocId
493
+ 4. Poll GET /api/ddocs/{ddocId}?apiKey={API_KEY} every 5 seconds
494
+ 5. When syncStatus is "synced", show: "Published! [View Document](link)"
495
+ 6. If syncStatus is "failed", show: "Saved locally but blockchain sync failed. Run retry."
238
496
 
239
- | Status | Meaning |
240
- |--------|---------|
241
- | 400 | Validation error (missing/invalid params) |
242
- | 401 | Invalid or missing API key |
243
- | 404 | Resource not found |
244
- | 429 | Rate limited (respect Retry-After header) |
245
- | 500 | Server error (retry or inform user) |
497
+ ## Recipe 2: Find and update a document by title
246
498
 
247
- # OpenAPI Specification
499
+ 1. GET /api/search?apiKey={API_KEY}&q={title} to search for the document
500
+ 2. From the results (response.nodes), find the matching document and extract its ddocId
501
+ 3. PUT /api/ddocs/{ddocId}?apiKey={API_KEY} with JSON body: {"content": "<new content>"}
502
+ 4. Poll GET /api/ddocs/{ddocId}?apiKey={API_KEY} until synced
503
+ 5. Show the updated link
248
504
 
249
- A machine-readable OpenAPI 3.1 spec is available at `GET {SERVER_URL}/openapi.json`.
505
+ ## Recipe 3: Check health and diagnose sync issues
506
+
507
+ 1. GET /ping - verify server is running (expect {"reply":"pong"})
508
+ 2. GET /api/ddocs?apiKey={API_KEY}&limit=5 - verify API key works and list recent docs
509
+ 3. GET /api/events/failed?apiKey={API_KEY} - check for failed sync events
510
+ 4. If failed events exist, POST /api/events/retry-failed?apiKey={API_KEY} to retry them
511
+ 5. Report: server status, number of documents, number of failed events (and if retried)
250
512
 
251
513
  ---
252
514
 
253
- # Custom Slash Commands (Skills)
515
+ # Claude Code Integration
516
+
517
+ ## Custom Slash Commands
254
518
 
255
- If the user asks you to set up Fileverse slash commands, create the following files. These work in Claude Code and other tools that support markdown-based command prompts.
519
+ You can create custom slash commands for Claude Code that integrate with Fileverse API. Create a `.claude/commands/` directory in your project and add markdown prompt files.
256
520
 
257
- Create a `.claude/commands/` directory in the project, then add these files:
521
+ ### fileverse-publish.md
258
522
 
259
- ## `.claude/commands/fileverse-publish.md`
523
+ Create `.claude/commands/fileverse-publish.md`:
260
524
 
261
525
  ```markdown
262
- Publish a file to Fileverse blockchain storage.
526
+ Publish a file to Fileverse API blockchain storage.
263
527
 
264
528
  Steps:
265
- 1. Read the file at: $ARGUMENTS
266
- 2. Use the fileverse_create_document MCP tool with the filename (without extension) as the title and the file contents as content.
267
- 3. If MCP tools are not available, fall back to the REST API:
268
- - Read credentials from ~/.fileverseapirc (JSON with apiKey and serverUrl fields)
269
- - POST to {serverUrl}/api/ddocs?apiKey={apiKey} with JSON body: {"title": "<filename>", "content": "<file contents>"}
270
- - Extract ddocId from response.data.ddocId
271
- - Poll GET {serverUrl}/api/ddocs/{ddocId}?apiKey={apiKey} every 5s until syncStatus is "synced" or "failed"
272
- 4. If synced: show "Published! Link: {link}"
273
- 5. If failed: show "Saved locally but blockchain sync failed"
529
+ 1. Read credentials from ~/.fileverseapirc (JSON with apiKey and serverUrl fields)
530
+ 2. Read the file at: $ARGUMENTS
531
+ 3. POST to {serverUrl}/api/ddocs?apiKey={apiKey} with JSON body:
532
+ Content-Type: application/json
533
+ {"title": "<filename without extension>", "content": "<file contents>"}
534
+ 4. Extract ddocId from response.data.ddocId
535
+ 5. Poll GET {serverUrl}/api/ddocs/{ddocId}?apiKey={apiKey} every 5 seconds until syncStatus is "synced" or "failed"
536
+ 6. If synced: show "Published! Link: {link}"
537
+ 7. If failed: show "Saved locally but blockchain sync failed"
274
538
  ```
275
539
 
276
540
  Usage: `/fileverse-publish path/to/document.md`
277
541
 
278
- ## `.claude/commands/fileverse-list.md`
542
+ ### fileverse-list.md
543
+
544
+ Create `.claude/commands/fileverse-list.md`:
279
545
 
280
546
  ```markdown
281
- List all documents stored in Fileverse.
547
+ List all documents in Fileverse API.
282
548
 
283
549
  Steps:
284
- 1. Use the fileverse_list_documents MCP tool with limit 50.
285
- 2. If MCP tools are not available, fall back to the REST API:
286
- - Read credentials from ~/.fileverseapirc
287
- - GET {serverUrl}/api/ddocs?apiKey={apiKey}&limit=50
550
+ 1. Read credentials from ~/.fileverseapirc (JSON with apiKey and serverUrl fields)
551
+ 2. GET {serverUrl}/api/ddocs?apiKey={apiKey}&limit=50
288
552
  3. Display results as a table with columns: ddocId, title, syncStatus, link, updatedAt
289
553
  4. Show total count and whether more documents exist (hasNext)
290
554
  ```
291
555
 
292
556
  Usage: `/fileverse-list`
293
557
 
294
- ## `.claude/commands/fileverse-search.md`
558
+ ### fileverse-search.md
559
+
560
+ Create `.claude/commands/fileverse-search.md`:
295
561
 
296
562
  ```markdown
297
- Search for documents in Fileverse.
563
+ Search for documents in Fileverse API.
298
564
 
299
565
  Steps:
300
- 1. Use the fileverse_search_documents MCP tool with query: $ARGUMENTS
301
- 2. If MCP tools are not available, fall back to the REST API:
302
- - Read credentials from ~/.fileverseapirc
303
- - GET {serverUrl}/api/search?apiKey={apiKey}&q=$ARGUMENTS
566
+ 1. Read credentials from ~/.fileverseapirc (JSON with apiKey and serverUrl fields)
567
+ 2. GET {serverUrl}/api/search?apiKey={apiKey}&q=$ARGUMENTS
304
568
  3. Display matching documents with: ddocId, title, syncStatus, link
305
569
  4. Show total matches found
306
570
  ```
307
571
 
308
572
  Usage: `/fileverse-search meeting notes`
309
573
 
310
- ## `.claude/commands/fileverse-status.md`
574
+ ### fileverse-status.md
575
+
576
+ Create `.claude/commands/fileverse-status.md`:
311
577
 
312
578
  ```markdown
313
- Check the sync status of a Fileverse document.
579
+ Check the sync status of a Fileverse API document.
314
580
 
315
581
  Steps:
316
- 1. Use the fileverse_get_sync_status MCP tool with ddocId: $ARGUMENTS
317
- 2. If MCP tools are not available, fall back to the REST API:
318
- - Read credentials from ~/.fileverseapirc
319
- - GET {serverUrl}/api/ddocs/$ARGUMENTS?apiKey={apiKey}
582
+ 1. Read credentials from ~/.fileverseapirc (JSON with apiKey and serverUrl fields)
583
+ 2. GET {serverUrl}/api/ddocs/$ARGUMENTS?apiKey={apiKey}
320
584
  3. Display:
321
585
  - Title
322
586
  - Sync Status (pending/synced/failed)
323
587
  - Link (if synced)
324
588
  - Local Version vs On-chain Version
325
589
  - Last Updated
326
- 4. If status is "failed", offer to retry using fileverse_retry_failed_events or POST {serverUrl}/api/events/retry-failed?apiKey={apiKey}
590
+ 4. If status is "failed", suggest running: POST {serverUrl}/api/events/retry-failed?apiKey={apiKey}
327
591
  ```
328
592
 
329
593
  Usage: `/fileverse-status <ddocId>`
330
594
 
331
- ## `.claude/commands/fileverse-delete.md`
595
+ ---
332
596
 
333
- ```markdown
334
- Delete a document from Fileverse.
597
+ # Key Concepts
335
598
 
336
- Steps:
337
- 1. If $ARGUMENTS looks like a ddocId, use it directly. Otherwise, search for it:
338
- - Use fileverse_search_documents MCP tool (or GET /api/search) with $ARGUMENTS as the query
339
- - Show matching documents and ask the user to confirm which one to delete
340
- 2. Use the fileverse_delete_document MCP tool with the ddocId.
341
- 3. If MCP tools are not available:
342
- - Read credentials from ~/.fileverseapirc
343
- - DELETE {serverUrl}/api/ddocs/{ddocId}?apiKey={apiKey}
344
- 4. Confirm deletion to the user.
345
- ```
599
+ - **DDoc**: A document with unique ddocId
600
+ - **syncStatus**: pending synced (success) or failed
601
+ - **link**: Public URL to view document (only available when synced)
602
+ - **localVersion**: Increments on each edit
603
+ - **onchainVersion**: Version on blockchain
604
+
605
+ # Error Handling
606
+
607
+ **400 Bad Request**: Validation errors (missing/invalid body or params). Response body: { "error": "..." } or { "message": "..." }.
608
+ **401 Unauthorized**: Invalid or missing API key
609
+ **404 Not Found**: Resource doesn't exist
610
+ **429 Too Many Requests**: If returned (e.g. from upstream), respect Retry-After header if present.
611
+ **500 Server Error**: Internal error, retry or inform user
612
+
613
+ ---
614
+
615
+ # Future Improvements (Planned)
346
616
 
347
- Usage: `/fileverse-delete <ddocId or search term>`
617
+ - **SSE for Sync Status**: Real-time sync status push via GET /api/ddocs/:ddocId/stream to eliminate polling
618
+ - **Batch Operations**: POST /api/ddocs/bulk for creating/updating/deleting multiple documents at once
619
+ - **Partial Responses**: ?fields=ddocId,syncStatus,link for requesting only specific fields
620
+ - **TypeScript SDK**: Typed client library with built-in sync polling at @fileverse/api/client
621
+ - **Webhook Callbacks**: Register a URL to be notified when sync completes instead of polling