feat(files): enhance file handling with support for HTTP uploads and direct binary access

This commit is contained in:
2026-03-31 00:04:36 +02:00
parent 3c1ca83dc9
commit 8f734c0556
6 changed files with 164 additions and 21 deletions

View File

@@ -41,8 +41,8 @@ A Go MCP server for capturing and retrieving thoughts, memory, and project conte
| `recall_context` | Semantic + recency context block for injection |
| `link_thoughts` | Create a typed relationship between thoughts |
| `related_thoughts` | Explicit links + semantic neighbours |
| `save_file` | Store a base64-encoded image, document, audio file, or other binary and optionally link it to a thought |
| `load_file` | Retrieve a stored file by ID as base64 plus metadata |
| `save_file` | Store a file (base64 or by resource URI) and optionally link it to a thought |
| `load_file` | Retrieve a stored file by ID; returns metadata, base64 content, and an embedded MCP binary resource |
| `list_files` | Browse stored files by thought, project, or kind |
| `backfill_embeddings` | Generate missing embeddings for stored thoughts |
| `reparse_thought_metadata` | Re-extract and normalize metadata for stored thoughts |
@@ -181,7 +181,11 @@ Run `reparse_thought_metadata` to fix stale or inconsistent metadata by re-extra
## File Storage
Use `save_file` to persist binary files as base64. Files can optionally be linked to a memory by passing `thought_id`, which also adds an attachment reference to that thought's metadata. AI clients should prefer `save_file` when the goal is to retain the artifact itself, rather than reading or summarizing the file first. Stored files and attachment metadata are not forwarded to the metadata extraction client.
Files can optionally be linked to a thought by passing `thought_id`, which also adds an attachment reference to that thought's metadata. AI clients should prefer `save_file` when the goal is to retain the artifact itself, rather than reading or summarizing the file first. Stored files and attachment metadata are not forwarded to the metadata extraction client.
### MCP tools
**Save via base64** (small files or when HTTP is not available):
```json
{
@@ -193,15 +197,27 @@ Use `save_file` to persist binary files as base64. Files can optionally be linke
}
```
Load a stored file again with:
**Save via resource URI** (preferred for binary; avoids base64 overhead):
Upload the file binary via HTTP first (see below), then pass the returned URI to `save_file`:
```json
{
"id": "stored-file-uuid"
"name": "meeting-notes.pdf",
"thought_id": "optional-thought-uuid",
"content_uri": "amcs://files/<id-from-upload>"
}
```
List files for a thought or project with:
`content_base64` and `content_uri` are mutually exclusive.
**Load a file** — returns metadata, base64 content, and an embedded MCP binary resource (`amcs://files/{id}`):
```json
{ "id": "stored-file-uuid" }
```
**List files** for a thought or project:
```json
{
@@ -212,9 +228,13 @@ List files for a thought or project with:
}
```
AMCS also supports direct authenticated HTTP uploads to `/files` for clients that want to stream file bodies instead of base64-encoding them into an MCP tool call.
### MCP resources
The Go server caps `/files` uploads at 100 MB per request. Large uploads are still also subject to available memory, Postgres limits, and any reverse proxy or load balancer limits in front of AMCS.
Stored files are also exposed as MCP resources at `amcs://files/{id}`. MCP clients can read raw binary content directly via `resources/read` without going through `load_file`.
### HTTP upload and download
Direct HTTP access avoids base64 encoding entirely. The Go server caps `/files` uploads at 100 MB per request. Large uploads are also subject to available memory, Postgres limits, and any reverse proxy or load balancer in front of AMCS.
Multipart upload:
@@ -235,6 +255,14 @@ curl -X POST "http://localhost:8080/files?project=amcs&name=meeting-notes.pdf" \
--data-binary @./meeting-notes.pdf
```
Binary download:
```bash
curl http://localhost:8080/files/<id> \
-H "x-brain-key: <key>" \
-o meeting-notes.pdf
```
**Automatic backfill** (optional, config-gated):
```yaml