@telepath-computer/autofile 0.4.0 → 0.5.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
@@ -1,83 +1,98 @@
1
- # Autofile
1
+ <p align="center">
2
+ <img src="assets/icon.svg" width="72" height="72" alt="Autofile icon">
3
+ </p>
2
4
 
3
- Autofile makes it easy for agents to store information in a structured, unambiguous way, and makes that information available to the services and interfaces that want to use it and show it.
5
+ <h1 align="center">Autofile</h1>
4
6
 
5
- Autofile is designed for:
7
+ <p align="center">
8
+ <strong>A portable, open filesystem for agents.</strong>
9
+ </p>
6
10
 
7
- - **No ambiguity on input.** Every kind of information has one defined place and type, with clear instructions for how it is filed.
8
- - **Efficient retrieval.** Agents find what they need by keyword search, by matching on typed properties, and by following links between records.
9
- - **Shared access.** Agents and programs use the same records, types and attachments through MCP or the library.
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@telepath-computer/autofile"><img src="https://img.shields.io/npm/v/@telepath-computer/autofile" alt="npm version"></a>
13
+ <a href="LICENSE"><img src="https://img.shields.io/github/license/telepath-computer/autofile" alt="MIT licence"></a>
14
+ <img src="https://img.shields.io/badge/node-%E2%89%A524-339933" alt="Node 24 or later">
15
+ </p>
10
16
 
11
- Autofile is an [MCP](https://modelcontextprotocol.io) server and a library. Agents use its tools and resources; programs can embed the same store through the `Autofile` class.
17
+ <p align="center">
18
+ <img src="assets/autofile-view.png" width="760" alt="A grid of records in Autofile: journal entries, contacts, events, topics and saved references">
19
+ <br>
20
+ <em>GUI coming soon</em>
21
+ </p>
12
22
 
13
- ## Install
23
+ **Agents file everything, and it never turns into a mess.** Every kind of information has one place and one shape, and anything that doesn't fit is turned away. A year of filing by any number of agents stays as coherent as the first day, and anything in it can still be found straight away.
14
24
 
15
- Autofile needs Node.js 24 or later.
25
+ **The live data layer for the apps you vibe-code.** Point an app at Autofile and it has storage, search, links, file attachments and live updates, with nothing else to build. The screens agents put up on [Television](https://github.com/telepath-computer/television) work this way: they change the moment an agent files something.
16
26
 
17
- ```sh
18
- npm install -g @telepath-computer/autofile
19
- ```
27
+ **Yours, wherever you take it.** Your records are plain files on your own machine, readable without Autofile and easy to move, back up or sync. Autofile is open source, and any agent that speaks [MCP](https://modelcontextprotocol.io) can use it.
20
28
 
21
- This installs the `autofile` command.
29
+ ## Get started
22
30
 
23
- ## Connect an agent
31
+ You need Node.js 24 or later.
24
32
 
25
- An MCP client starts Autofile itself by running `autofile`, and talks to it over stdio. For Claude Code:
33
+ 1. Install Autofile:
26
34
 
27
- ```sh
28
- claude mcp add autofile --scope user -- autofile
29
- ```
35
+ ```sh
36
+ npm install -g @telepath-computer/autofile
37
+ ```
38
+
39
+ 2. Add it to your agent. For Claude Code:
30
40
 
31
- For another client, add an MCP server whose command is `autofile`, with no arguments.
41
+ ```sh
42
+ claude mcp add autofile --scope user -- autofile
43
+ ```
32
44
 
33
- Autofile starts with no types. Ask your agent to file something: it proposes a type, such as `contact` with the fields a contact needs, and creates it once you agree. It then files records of that type, and finds them again by search, by field value, or by following links between records.
45
+ For another MCP client, add a server whose command is `autofile`, with no arguments.
34
46
 
35
- ## Choose a store
47
+ 3. Ask your agent to remember something.
36
48
 
37
- Autofile uses a default store until the `storage` setting selects another. Changing that setting moves no records and takes effect when clients restart Autofile. See [storage configuration](spec/storage.md#folders) for the current implementation and [Commands](spec/index.md#commands) for other settings.
49
+ Autofile starts empty. Your agent proposes types as it needs them, and creates each one once you agree.
50
+
51
+ ## File over app
52
+
53
+ Autofile follows [File over app](https://stephango.com/file-over-app), the philosophy of Steph Ango (kepano), CEO of Obsidian: "Apps are ephemeral, but your files have a chance to last."
54
+
55
+ Your records are plain JSON files in one Autofile folder, with attachments kept as the original files. Put the folder anywhere, such as Dropbox to sync it between machines, with `autofile set storage ~/Dropbox/Autofile`. Any program can read it, with or without Autofile, and the files are yours forever.
38
56
 
39
57
  ## Serve over HTTP
40
58
 
41
- For clients that connect over HTTP, such as a web page, run:
59
+ For apps and agents that connect over HTTP, run:
42
60
 
43
61
  ```sh
44
62
  autofile serve
45
63
  ```
46
64
 
47
- This serves the same tools and resources at `http://127.0.0.1:7319/mcp` until stopped. Autofile does not authenticate HTTP clients: anything that can reach the address can read and change every record. It therefore listens only on this machine by default, and accepts requests from web pages only when they are served from this machine. [Serving over HTTP](spec/index.md#serving-over-http) explains how to change the address, the port, and the web pages it accepts.
65
+ This serves the same tools and resources at `http://127.0.0.1:7319/mcp`, and attachments next to it. Autofile does not authenticate HTTP clients, so anything that can reach the address can read and change every record. It listens only on this machine by default. [Serving over HTTP](spec/index.md#serving-over-http) explains how to change the address and which web pages it accepts.
48
66
 
49
- ## Use as a library
67
+ ## Use it as a library
50
68
 
51
- Install the package in your project with `npm install @telepath-computer/autofile`, then import the ES module:
69
+ Programs can use the same store directly:
70
+
71
+ ```sh
72
+ npm install @telepath-computer/autofile
73
+ ```
52
74
 
53
75
  ```js
54
76
  import { Autofile } from "@telepath-computer/autofile";
55
77
 
56
78
  const store = new Autofile({ folder: "./records" });
57
79
  try {
58
- const { records } = await store.records.find({ q: "dentist" });
80
+ const { records } = await store.records.find({ q: "Ada Park" });
59
81
  for (const record of records) console.log(record.title ?? record.uri);
60
82
  } finally {
61
83
  await store.close();
62
84
  }
63
85
  ```
64
86
 
65
- The `folder` option is the path of a store in the current implementation; [Storage](spec/storage.md) describes its format. Importing starts no server or watcher, and construction does no I/O. The first operation initializes the store if needed. [Library API](spec/index.md#library-api) covers writing records, declaring types, blobs, change subscriptions and errors.
66
-
67
- Record addresses use `autofile:///<type>/<key>`, type declarations use `autofile:///_types/<name>`, and attachments use `autofile:///_blobs/<hash>.<ext>`. Keep and reuse these addresses as opaque identifiers; they do not tell a client how data is stored.
68
-
69
- Upload an attachment before writing the record that holds it. `blobs.put(bytes, mediaType)` takes a `Uint8Array` and returns an address; put that address in a field marked `"format": "blob"` in the type schema. For an open store with a `document` type that declares `title` and `attachment` fields:
87
+ The [Library API](spec/index.md#library-api) covers writing records, declaring types, attachments and watching for changes.
70
88
 
71
- ```js
72
- const uri = await store.blobs.put(new TextEncoder().encode("Meeting notes"), "text/plain");
73
- await store.records.create("document", { title: "Meeting notes", attachment: uri });
74
- ```
89
+ ## Status
75
90
 
76
- Records may share an attachment address. MCP clients use `upload_blob` with base64 bytes and a media type, or an absolute local file path over stdio, then put the returned address in the record. Record writes accept neither data URIs nor local paths in blob fields.
91
+ Autofile is new and changing quickly. Until version 1.0, addresses, tools and the library API may change between minor versions.
77
92
 
78
93
  ## Specification
79
94
 
80
- [spec/index.md](spec/index.md) describes records, types, links, attachments, the MCP tools and resources, and the commands. [Storage](spec/storage.md) specifies the on-disk format, and [Implementation](spec/implementation.md) describes the code.
95
+ [spec/index.md](spec/index.md) describes records, types, links, attachments, the MCP tools and resources, and the commands. [Storage](spec/storage.md) specifies the folder format, and [Implementation](spec/implementation.md) describes the code.
81
96
 
82
97
  ## Development
83
98
 
@@ -87,3 +102,7 @@ npm test
87
102
  ```
88
103
 
89
104
  `npm test` builds Autofile and runs the tests.
105
+
106
+ ## Licence
107
+
108
+ [MIT](LICENSE)
package/dist/blobs.d.ts CHANGED
@@ -1,18 +1,16 @@
1
1
  /** Stores explicitly uploaded attachments and checks their canonical addresses. */
2
- /** Largest blob that fits in one MCP message after base64 encoding. */
3
- export declare const MAX_BLOB_BYTES = 7340032;
4
2
  /** Canonical names Autofile recognizes in its blob folder. */
5
3
  export declare const BLOB_NAME_PATTERN: RegExp;
6
4
  /** Canonical URIs Autofile recognizes for stored blobs. */
7
5
  export declare const BLOB_URI_PATTERN: RegExp;
8
- /** Stores one attachment atomically, reusing an existing regular file. */
6
+ /** Stores uploaded bytes through the same incremental writer as streamed sources. */
9
7
  export declare function writeBlob(blobFolder: string, bytes: Buffer, mediaType: string): Promise<string>;
10
- /** Reports unavailable or oversized bytes for a canonical attachment address. */
8
+ /** Hashes and stores chunks in order, publishing only a complete attachment. */
9
+ export declare function writeBlobStream(blobFolder: string, chunks: AsyncIterable<Uint8Array>, mediaType: string): Promise<string>;
10
+ /** Checks attachment existence without opening or reading its bytes. */
11
11
  export declare function blobReferenceProblem(blobFolder: string, uri: string): Promise<string | undefined>;
12
12
  /** Checks the bare media type accepted by explicit uploads. */
13
13
  export declare function isMediaType(value: unknown): value is string;
14
- /** Gives the upload size and the accepted limit in the existing refusal form. */
15
- export declare function blobSizeProblem(size: number): string;
16
14
  /** Deletes the named canonical blob resources when they still exist. */
17
15
  export declare function deleteBlobUris(blobFolder: string, uris: Iterable<string>): Promise<void>;
18
16
  /** Returns the canonical blob name from a URI. */
package/dist/blobs.js CHANGED
@@ -1,39 +1,68 @@
1
1
  /** Stores explicitly uploaded attachments and checks their canonical addresses. */
2
2
  import { createHash, randomUUID } from "node:crypto";
3
- import { constants } from "node:fs";
4
- import { lstat, mkdir, open, rename, unlink, writeFile } from "node:fs/promises";
5
- import { basename, dirname, join } from "node:path";
3
+ import { chmod, lstat, mkdir, rename, unlink, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
6
5
  import { extension as extensionForMimeType } from "mime-types";
7
6
  const BLOB_EXTENSION_PATTERN_SOURCE = "[a-z0-9_-]+";
8
- /** Largest blob that fits in one MCP message after base64 encoding. */
9
- export const MAX_BLOB_BYTES = 7_340_032;
10
7
  /** Canonical names Autofile recognizes in its blob folder. */
11
8
  export const BLOB_NAME_PATTERN = new RegExp(`^[a-f0-9]{64}(?:\\.${BLOB_EXTENSION_PATTERN_SOURCE})?$`, "u");
12
9
  /** Canonical URIs Autofile recognizes for stored blobs. */
13
- export const BLOB_URI_PATTERN = new RegExp(`^autofile:///_blobs/([a-f0-9]{64}(?:\\.${BLOB_EXTENSION_PATTERN_SOURCE})?)$`, "u");
10
+ export const BLOB_URI_PATTERN = new RegExp(`^autofile:///blobs/([a-f0-9]{64}(?:\\.${BLOB_EXTENSION_PATTERN_SOURCE})?)$`, "u");
14
11
  const blobExtensionPattern = new RegExp(`^${BLOB_EXTENSION_PATTERN_SOURCE}$`, "u");
15
- /** Stores one attachment atomically, reusing an existing regular file. */
12
+ /** Stores uploaded bytes through the same incremental writer as streamed sources. */
16
13
  export async function writeBlob(blobFolder, bytes, mediaType) {
14
+ async function* chunks() { yield bytes; }
15
+ return writeBlobStream(blobFolder, chunks(), mediaType);
16
+ }
17
+ /** Hashes and stores chunks in order, publishing only a complete attachment. */
18
+ export async function writeBlobStream(blobFolder, chunks, mediaType) {
17
19
  const extension = extensionForMimeType(mediaType.toLowerCase());
18
20
  const suffix = extension === false ? undefined : normalizeExtension(extension);
19
- const digest = createHash("sha256").update(bytes).digest("hex");
20
- const name = `${digest}${suffix === undefined ? "" : `.${suffix}`}`;
21
+ const digest = createHash("sha256");
21
22
  await mkdir(blobFolder, { recursive: true });
22
23
  if (!await isDirectory(blobFolder)) {
23
24
  throw Object.assign(new Error("blob folder is not a directory"), { code: "ENOTDIR" });
24
25
  }
25
- const path = join(blobFolder, name);
26
- if (!await isRegularFile(path))
27
- await writeBlobAtomically(path, bytes);
28
- return blobUri(name);
26
+ const temporaryPath = join(blobFolder, `.upload.${String(process.pid)}.${randomUUID()}`);
27
+ async function* hashedChunks() {
28
+ for await (const chunk of chunks) {
29
+ digest.update(chunk);
30
+ yield chunk;
31
+ }
32
+ }
33
+ try {
34
+ // writeFile awaits each chunk write before advancing the iterable, so the
35
+ // source is backpressured and attachments never accumulate in memory.
36
+ await writeFile(temporaryPath, hashedChunks(), { flag: "wx" });
37
+ const name = `${digest.digest("hex")}${suffix === undefined ? "" : `.${suffix}`}`;
38
+ const path = join(blobFolder, name);
39
+ if (await isRegularFile(path)) {
40
+ await unlink(temporaryPath);
41
+ }
42
+ else {
43
+ // Set the exact read-only mode before publishing the immutable attachment.
44
+ await chmod(temporaryPath, 0o444);
45
+ await rename(temporaryPath, path);
46
+ }
47
+ return blobUri(name);
48
+ }
49
+ catch (error) {
50
+ try {
51
+ await unlink(temporaryPath);
52
+ }
53
+ catch (cleanupError) {
54
+ if (!hasCode(cleanupError, "ENOENT"))
55
+ throw cleanupError;
56
+ }
57
+ throw error;
58
+ }
29
59
  }
30
- /** Reports unavailable or oversized bytes for a canonical attachment address. */
60
+ /** Checks attachment existence without opening or reading its bytes. */
31
61
  export async function blobReferenceProblem(blobFolder, uri) {
32
62
  const name = blobNameFromUri(uri);
33
- const details = name === undefined ? undefined : await storedBlobDetails(blobFolder, name);
34
- if (details === undefined)
35
- return `references a blob that does not exist: ${uri}`;
36
- return details.size > MAX_BLOB_BYTES ? blobSizeProblem(details.size) : undefined;
63
+ return name !== undefined && await isDirectory(blobFolder) && await isRegularFile(join(blobFolder, name))
64
+ ? undefined
65
+ : `references a blob that does not exist: ${uri}`;
37
66
  }
38
67
  /** Checks the bare media type accepted by explicit uploads. */
39
68
  export function isMediaType(value) {
@@ -42,10 +71,6 @@ export function isMediaType(value) {
42
71
  const token = "[!#$%&'*+.^_`|~0-9A-Za-z-]+";
43
72
  return new RegExp(`^${token}/${token}$`, "u").test(value);
44
73
  }
45
- /** Gives the upload size and the accepted limit in the existing refusal form. */
46
- export function blobSizeProblem(size) {
47
- return `blob is ${String(size)} bytes; limit is ${String(MAX_BLOB_BYTES)} bytes`;
48
- }
49
74
  /** Deletes the named canonical blob resources when they still exist. */
50
75
  export async function deleteBlobUris(blobFolder, uris) {
51
76
  if (!await isDirectory(blobFolder))
@@ -69,70 +94,12 @@ export function blobNameFromUri(uri) {
69
94
  }
70
95
  /** Builds the canonical URI for a recognized blob name. */
71
96
  export function blobUri(name) {
72
- return `autofile:///_blobs/${name}`;
97
+ return `autofile:///blobs/${name}`;
73
98
  }
74
99
  function normalizeExtension(extension) {
75
100
  const normalized = extension.toLowerCase();
76
101
  return blobExtensionPattern.test(normalized) ? normalized : undefined;
77
102
  }
78
- async function storedBlobDetails(blobFolder, name) {
79
- if (!await isDirectory(blobFolder))
80
- return undefined;
81
- const file = await openRegularFile(join(blobFolder, name));
82
- if (file === undefined)
83
- return undefined;
84
- try {
85
- return { size: file.size };
86
- }
87
- finally {
88
- await file.handle.close();
89
- }
90
- }
91
- async function openRegularFile(path) {
92
- let handle;
93
- try {
94
- handle = await open(path, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOFOLLOW);
95
- }
96
- catch (error) {
97
- if (hasCode(error, "ENOENT")
98
- || hasCode(error, "ENOTDIR")
99
- || hasCode(error, "ELOOP")
100
- || hasCode(error, "ENXIO")
101
- || hasCode(error, "ENODEV")) {
102
- return undefined;
103
- }
104
- throw error;
105
- }
106
- try {
107
- const details = await handle.stat();
108
- if (!details.isFile()) {
109
- await handle.close();
110
- return undefined;
111
- }
112
- return { handle, size: details.size };
113
- }
114
- catch (error) {
115
- await handle.close();
116
- throw error;
117
- }
118
- }
119
- async function writeBlobAtomically(path, bytes) {
120
- const temporaryPath = join(dirname(path), `.${basename(path)}.${String(process.pid)}.${randomUUID()}`);
121
- try {
122
- await writeFile(temporaryPath, bytes, { flag: "wx" });
123
- await rename(temporaryPath, path);
124
- }
125
- catch (error) {
126
- try {
127
- await unlink(temporaryPath);
128
- }
129
- catch (cleanupError) {
130
- if (!hasCode(cleanupError, "ENOENT"))
131
- throw cleanupError;
132
- }
133
- throw error;
134
- }
135
- }
136
103
  async function isDirectory(path) {
137
104
  try {
138
105
  return (await lstat(path)).isDirectory();
package/dist/blobs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -101,7 +101,7 @@ async function runStdio() {
101
101
  throw error;
102
102
  });
103
103
  handle = serveStdio(async () => {
104
- const server = await buildServer(store);
104
+ const server = await buildServer(store, { blobLocation: "stdio" });
105
105
  connectedServer = server;
106
106
  return server;
107
107
  }, {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Mounts Autofile's transport-independent MCP server on Node's HTTP server. */
1
+ /** Serves MCP requests and streamed blob downloads through the same HTTP checks. */
2
2
  import { type HttpSettings } from "./config.js";
3
3
  import type { Autofile } from "./index.js";
4
4
  export interface RunningHttpServer {
package/dist/http.js CHANGED
@@ -1,5 +1,7 @@
1
- /** Mounts Autofile's transport-independent MCP server on Node's HTTP server. */
1
+ /** Serves MCP requests and streamed blob downloads through the same HTTP checks. */
2
2
  import { createServer } from "node:http";
3
+ import { Readable } from "node:stream";
4
+ import { pipeline } from "node:stream/promises";
3
5
  import { toNodeHandler } from "@modelcontextprotocol/node";
4
6
  import { createMcpHandler } from "@modelcontextprotocol/server";
5
7
  import { normalizeHttpOrigin } from "./config.js";
@@ -7,9 +9,12 @@ import { buildServer } from "./server.js";
7
9
  import { watchResources } from "./mcp-watch.js";
8
10
  const MAX_REQUEST_BODY_BYTES = 64 * 1024 * 1024;
9
11
  const CORS_ALLOW_HEADERS = "Content-Type, MCP-Protocol-Version, Mcp-Method, Mcp-Name";
12
+ const BLOB_METHODS = "GET, HEAD, OPTIONS";
13
+ const BLOB_EXPOSE_HEADERS = "Content-Length, Content-Range, Accept-Ranges, ETag";
14
+ const blobPathPattern = /^\/blobs\/([a-f0-9]{64})(?:\.[a-z0-9_-]+)?$/u;
10
15
  /** Starts one modern-only Streamable HTTP endpoint around a process-shared store. */
11
16
  export async function startHttpServer(store, settings, onError) {
12
- const handler = createMcpHandler(() => buildServer(store), {
17
+ const handler = createMcpHandler(() => buildServer(store, { blobLocation: "http" }), {
13
18
  legacy: "reject",
14
19
  maxRequestBodySize: MAX_REQUEST_BODY_BYTES,
15
20
  onerror: onError,
@@ -34,7 +39,23 @@ export async function startHttpServer(store, settings, onError) {
34
39
  ...settings.origins.map((origin) => new URL(origin).hostname.toLowerCase()),
35
40
  ]);
36
41
  const httpServer = createServer((request, response) => {
37
- void routeRequest(request, response, allowedOrigins, allowedHosts, serveMcp);
42
+ void routeRequest(request, response, allowedOrigins, allowedHosts, serveMcp, store).catch((error) => {
43
+ // Cancelling a download closes its pipeline. This is a normal client action,
44
+ // whereas storage and handler failures are reported without physical paths.
45
+ if (error instanceof Error && "code" in error
46
+ && (error.code === "ERR_STREAM_PREMATURE_CLOSE" || error.code === "ECONNRESET"))
47
+ return;
48
+ onError(new Error("Could not serve HTTP request"));
49
+ if (response.headersSent || response.destroyed)
50
+ response.destroy();
51
+ else {
52
+ response.removeHeader("Content-Length");
53
+ response.removeHeader("Content-Range");
54
+ response.removeHeader("ETag");
55
+ response.removeHeader("Cache-Control");
56
+ refuse(response, 500, "Internal Server Error\n");
57
+ }
58
+ });
38
59
  });
39
60
  const closed = new Promise((resolveClosed) => httpServer.once("close", resolveClosed));
40
61
  try {
@@ -69,7 +90,14 @@ export async function startHttpServer(store, settings, onError) {
69
90
  await store.close();
70
91
  }
71
92
  }
72
- async function routeRequest(request, response, allowedOrigins, allowedHosts, serveMcp) {
93
+ async function routeRequest(request, response, allowedOrigins, allowedHosts, serveMcp, store) {
94
+ const path = requestPath(request);
95
+ const isBlob = path?.startsWith("/blobs/") === true;
96
+ if (isBlob) {
97
+ response.setHeader("Vary", "Origin");
98
+ response.setHeader("X-Content-Type-Options", "nosniff");
99
+ response.setHeader("Content-Security-Policy", "sandbox");
100
+ }
73
101
  if (!isAllowedHost(request.headers.host, allowedHosts)) {
74
102
  refuse(response, 403, "Forbidden\n");
75
103
  return;
@@ -79,12 +107,18 @@ async function routeRequest(request, response, allowedOrigins, allowedHosts, ser
79
107
  refuse(response, 403, "Forbidden\n");
80
108
  return;
81
109
  }
82
- if (requestPath(request) !== "/mcp") {
110
+ if (path !== "/mcp" && !isBlob) {
83
111
  refuse(response, 404, "Not Found\n");
84
112
  return;
85
113
  }
86
114
  if (origin !== undefined)
87
115
  setCorsHeaders(response, origin);
116
+ if (isBlob && path !== undefined) {
117
+ if (origin !== undefined)
118
+ response.setHeader("Access-Control-Expose-Headers", BLOB_EXPOSE_HEADERS);
119
+ await serveBlob(request, response, path, store);
120
+ return;
121
+ }
88
122
  if (request.method === "OPTIONS") {
89
123
  response.setHeader("Connection", "close");
90
124
  response.writeHead(204, {
@@ -95,6 +129,97 @@ async function routeRequest(request, response, allowedOrigins, allowedHosts, ser
95
129
  }
96
130
  await serveMcp(request, response);
97
131
  }
132
+ async function serveBlob(request, response, path, store) {
133
+ if (request.method === "OPTIONS") {
134
+ response.writeHead(204, {
135
+ "Connection": "close",
136
+ "Access-Control-Allow-Methods": BLOB_METHODS,
137
+ "Access-Control-Allow-Headers": "Range, If-None-Match",
138
+ }).end();
139
+ return;
140
+ }
141
+ if (request.method !== "GET" && request.method !== "HEAD") {
142
+ response.setHeader("Allow", BLOB_METHODS);
143
+ refuse(response, 405, "Method Not Allowed\n");
144
+ return;
145
+ }
146
+ const hash = blobPathPattern.exec(path)?.[1];
147
+ const uri = `autofile://${path}`;
148
+ const details = hash === undefined ? undefined : await store.blobs.stat(uri);
149
+ if (details === undefined) {
150
+ refuse(response, 404, "Not Found\n");
151
+ return;
152
+ }
153
+ const etag = `"${hash}"`;
154
+ response.setHeader("Content-Type", details.mimeType);
155
+ response.setHeader("Accept-Ranges", "bytes");
156
+ response.setHeader("ETag", etag);
157
+ response.setHeader("Cache-Control", "private, max-age=31536000, immutable");
158
+ if (matchesEtag(request.headers["if-none-match"], etag)) {
159
+ response.writeHead(304).end();
160
+ return;
161
+ }
162
+ if (request.method === "HEAD") {
163
+ response.setHeader("Content-Length", details.size);
164
+ response.writeHead(200).end();
165
+ return;
166
+ }
167
+ const ifRange = request.headers["if-range"];
168
+ const range = ifRange === undefined || ifRange === etag
169
+ ? parseByteRange(request.headers.range, details.size)
170
+ : undefined;
171
+ if (range === "unsatisfiable") {
172
+ response.setHeader("Content-Range", `bytes */${details.size}`);
173
+ refuse(response, 416, "Range Not Satisfiable\n");
174
+ return;
175
+ }
176
+ const body = await store.blobs.stream(uri, range);
177
+ if (body === undefined) {
178
+ response.removeHeader("ETag");
179
+ response.removeHeader("Cache-Control");
180
+ refuse(response, 404, "Not Found\n");
181
+ return;
182
+ }
183
+ response.setHeader("Content-Length", range === undefined ? details.size : range.end - range.start);
184
+ if (range !== undefined) {
185
+ response.setHeader("Content-Range", `bytes ${range.start}-${range.end - 1}/${details.size}`);
186
+ }
187
+ response.writeHead(range === undefined ? 200 : 206);
188
+ // The pipeline propagates backpressure and cancels the store stream when the
189
+ // connection closes, keeping memory and file descriptors bounded.
190
+ // Node and DOM declarations describe the same Web stream with different
191
+ // iterator helpers. Only the Node adapter needs the richer Node declaration.
192
+ await pipeline(Readable.fromWeb(body), response);
193
+ }
194
+ function matchesEtag(header, etag) {
195
+ if (header === undefined)
196
+ return false;
197
+ return header.trim() === "*"
198
+ || header.split(",").some((candidate) => candidate.trim().replace(/^W\//u, "") === etag);
199
+ }
200
+ function parseByteRange(header, size) {
201
+ const match = header === undefined ? null : /^bytes=(\d*)-(\d*)$/iu.exec(header);
202
+ const first = match?.[1];
203
+ const last = match?.[2];
204
+ if (first === undefined || last === undefined || (first === "" && last === ""))
205
+ return undefined;
206
+ // Decimal offsets can exceed JavaScript's integer precision. Compare before
207
+ // converting so even very large ranges can be clipped to the actual blob.
208
+ const length = BigInt(size);
209
+ if (first === "") {
210
+ const suffix = BigInt(last);
211
+ if (suffix === 0n || length === 0n)
212
+ return "unsatisfiable";
213
+ return { start: Number(suffix >= length ? 0n : length - suffix), end: size };
214
+ }
215
+ const start = BigInt(first);
216
+ const end = last === "" ? length : BigInt(last) + 1n;
217
+ if (last !== "" && end <= start)
218
+ return undefined;
219
+ if (start >= length)
220
+ return "unsatisfiable";
221
+ return { start: Number(start), end: Number(end > length ? length : end) };
222
+ }
98
223
  function requestPath(request) {
99
224
  try {
100
225
  return new URL(request.url ?? "", "http://autofile.local").pathname;
@@ -145,6 +270,7 @@ function hostHeaderName(host) {
145
270
  }
146
271
  function refuse(response, status, body) {
147
272
  response.setHeader("Connection", "close");
273
+ response.setHeader("Content-Type", "text/plain; charset=utf-8");
148
274
  response.writeHead(status).end(body);
149
275
  }
150
276
  function setCorsHeaders(response, origin) {