lithtrix_blob_signed_url
Generate a time-limited HTTPS read URL for a blob. Anyone with the URL can access the data until the expiry time.
Instructions
Mint a time-limited HTTPS read URL for a blob (GET /v1/blobs/{blob_id}/signed-url). Anyone with the URL can GET bytes until expiry — share carefully. Requires LITHTRIX_API_KEY.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| blob_id | Yes | Content-addressed blob id (b_ + 16 hex chars) | |
| expires_in | No | TTL seconds (min 60; max from server). Omit for API default. |
Implementation Reference
- tools/blobs.js:295-330 (handler)The tool handler for 'lithtrix_blob_signed_url'. It mints a time-limited HTTPS read URL by calling GET /v1/blobs/{blob_id}/signed-url. Requires LITHTRIX_API_KEY. Accepts optional expires_in parameter (min 60 seconds). Returns the API JSON response containing the signed URL.
server.tool( "lithtrix_blob_signed_url", "Mint a time-limited HTTPS read URL for a blob (GET /v1/blobs/{blob_id}/signed-url). " + "Anyone with the URL can GET bytes until expiry — share carefully. Requires LITHTRIX_API_KEY.", { blob_id: blobIdSchema, expires_in: z .number() .int() .min(60) .optional() .describe("TTL seconds (min 60; max from server). Omit for API default."), }, async ({ blob_id, expires_in }) => { const apiKey = process.env.LITHTRIX_API_KEY; if (!apiKey) return missingApiKeyResponse(); const url = new URL( `/v1/blobs/${encodeURIComponent(blob_id)}/signed-url`, LITHTRIX_API_URL ); if (expires_in !== undefined) { url.searchParams.set("expires_in", String(expires_in)); } let response; try { response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${apiKey}` }, }); } catch (err) { return networkErrorResponse(err); } return apiJsonResponse(response); } ); - tools/blobs.js:299-307 (schema)Input schema for the tool: blob_id (string, 19 chars, pattern b_ + 16 hex chars) and optional expires_in (integer, min 60).
{ blob_id: blobIdSchema, expires_in: z .number() .int() .min(60) .optional() .describe("TTL seconds (min 60; max from server). Omit for API default."), }, - tools/blobs.js:295-331 (registration)The tool is registered via server.tool('lithtrix_blob_signed_url', ...) inside the exported registerBlobTools function.
server.tool( "lithtrix_blob_signed_url", "Mint a time-limited HTTPS read URL for a blob (GET /v1/blobs/{blob_id}/signed-url). " + "Anyone with the URL can GET bytes until expiry — share carefully. Requires LITHTRIX_API_KEY.", { blob_id: blobIdSchema, expires_in: z .number() .int() .min(60) .optional() .describe("TTL seconds (min 60; max from server). Omit for API default."), }, async ({ blob_id, expires_in }) => { const apiKey = process.env.LITHTRIX_API_KEY; if (!apiKey) return missingApiKeyResponse(); const url = new URL( `/v1/blobs/${encodeURIComponent(blob_id)}/signed-url`, LITHTRIX_API_URL ); if (expires_in !== undefined) { url.searchParams.set("expires_in", String(expires_in)); } let response; try { response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${apiKey}` }, }); } catch (err) { return networkErrorResponse(err); } return apiJsonResponse(response); } ); } - index.js:48-48 (registration)registerBlobTools(server) is called from index.js, which registers the tool on the MCP server.
registerBlobTools(server); - tools/blobs.js:46-73 (helper)Helper function apiJsonResponse that formats the API response into MCP text content. Used by the signed_url handler to return results.
async function apiJsonResponse(response) { let body; try { body = await response.json(); } catch { body = { message: `Invalid JSON (HTTP ${response.status})` }; } if (!response.ok) { return { content: [ { type: "text", text: JSON.stringify({ error: body.message ?? `Lithtrix API error (HTTP ${response.status})`, error_code: body.error_code ?? "UNKNOWN", status: body.status, }), }, ], isError: true, }; } return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }], }; }