TypeScript SDK for building apps on top of Markie — your personal asset library.
Browse, search, upload, and display images, videos, PDFs, and design assets from your local Markie library in any web app.
- Markie desktop app must be running (the SDK talks to its local server on
localhost:3210) - Developer Access must be enabled in Markie Settings > Developer tab
npm install @vitgranen/markie-sdkimport { MarkieClient } from '@vitgranen/markie-sdk';
const markie = new MarkieClient();
await markie.connect();
// Browse assets
const { assets, total } = await markie.getCatalog({ limit: 20 });
// Display thumbnails
for (const asset of assets) {
const url = markie.getThumbnailUrl(asset.id, 'sm');
console.log(asset.originalName, url);
}Thumbnail and file URLs don't require auth headers, so you can use them directly:
<img src="http://localhost:3210/api/assets/{id}/thumbnail" />Or with the SDK:
<img src={markie.getThumbnailUrl(asset.id)} alt={asset.originalName} />const markie = new MarkieClient({
baseUrl?: string, // Default: 'http://localhost:3210'
token?: string, // Pre-known token (skip connect())
});| Method | Returns | Description |
|---|---|---|
connect() |
Promise<void> |
Register and obtain a bearer token |
health() |
Promise<boolean> |
Check if Markie is running |
getInfo() |
Promise<ServerInfo> |
Server name, version, API version |
const { assets, total } = await markie.getCatalog({
limit: 50, // Max assets to return
offset: 0, // Skip N assets (for pagination)
since: '2024-01-01' // Only assets saved after this ISO date
});| Method | Returns | Description |
|---|---|---|
getAsset(id) |
Promise<Asset> |
Get a single asset by ID |
updateAsset(id, patch) |
Promise<Asset> |
Update tags, description, or category |
deleteAsset(id) |
Promise<void> |
Delete an asset |
| Method | Returns | Description |
|---|---|---|
getThumbnailUrl(id, size?) |
string |
URL for thumbnail ('full', 'sm', 'xs') |
getFileUrl(id) |
string |
URL for original file |
getFile(id) |
Promise<Blob> |
Download original file as Blob |
const file = new File([buffer], 'photo.jpg', { type: 'image/jpeg' });
const { id } = await markie.save(file, {
sourceUrl: 'https://example.com/photo.jpg',
pageTitle: 'Example Gallery',
});// Requires Ollama embedding model configured in Markie
const results = await markie.search('mountain landscape');
// [{ id: '...', score: 0.87 }, ...]
const status = await markie.getSearchStatus();
// { available: true, model: 'nomic-embed-text', indexed: 450, total: 500 }const plan = await markie.getPlan();
// { isPro: false, assetCount: 123, limit: 500 }import {
MarkieOfflineError,
MarkieUnauthorizedError,
MarkieLimitError,
} from '@vitgranen/markie-sdk';
try {
await markie.save(file);
} catch (err) {
if (err instanceof MarkieOfflineError) {
// Markie desktop app is not running
} else if (err instanceof MarkieLimitError) {
// Free plan limit reached (500 assets)
} else if (err instanceof MarkieUnauthorizedError) {
// Token is invalid — call connect() again
}
}MIT