@allourthings/mcp-server 0.1.1 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +118 -151
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -11140,10 +11140,44 @@ class StdioServerTransport {
11140
11140
  }
11141
11141
  }
11142
11142
 
11143
- // src/backends/filesystem.ts
11144
- import { readFile, writeFile, mkdir, readdir, rename, rm } from "fs/promises";
11145
- import { existsSync } from "fs";
11146
- import { join } from "path";
11143
+ // src/backends/native.ts
11144
+ import { createRequire } from "module";
11145
+ var require2 = createRequire(import.meta.url);
11146
+ var { JsCatalogStore } = require2("@allourthings/core");
11147
+
11148
+ class NativeBackend {
11149
+ store;
11150
+ constructor(dataDir) {
11151
+ this.store = new JsCatalogStore(dataDir);
11152
+ }
11153
+ async addItem(newItem) {
11154
+ return this.store.addItem(newItem);
11155
+ }
11156
+ async getItem(idOrName) {
11157
+ return this.store.getItem(idOrName);
11158
+ }
11159
+ async listItems(filter) {
11160
+ return this.store.listItems(filter ?? null);
11161
+ }
11162
+ async updateItem(id, updates) {
11163
+ return this.store.updateItem(id, updates);
11164
+ }
11165
+ async deleteItem(id) {
11166
+ return this.store.deleteItem(id);
11167
+ }
11168
+ async searchItems(query) {
11169
+ return this.store.searchItems(query);
11170
+ }
11171
+ async addAttachment(itemId, filename, kind, data, label) {
11172
+ return this.store.addAttachment(itemId, filename, kind, data, label ?? null);
11173
+ }
11174
+ async getAttachment(itemId, filename) {
11175
+ return this.store.getAttachment(itemId, filename);
11176
+ }
11177
+ async deleteAttachment(itemId, filename) {
11178
+ return this.store.deleteAttachment(itemId, filename);
11179
+ }
11180
+ }
11147
11181
 
11148
11182
  // ../../node_modules/zod/v3/external.js
11149
11183
  var exports_external = {};
@@ -15118,148 +15152,6 @@ var coerce = {
15118
15152
  date: (arg) => ZodDate.create({ ...arg, coerce: true })
15119
15153
  };
15120
15154
  var NEVER2 = INVALID;
15121
- // src/schema.ts
15122
- var AttachmentSchema = exports_external.object({
15123
- filename: exports_external.string(),
15124
- type: exports_external.enum(["manual", "receipt", "photo", "warranty", "other"]),
15125
- label: exports_external.string().optional()
15126
- });
15127
- var ItemSchema = exports_external.object({
15128
- id: exports_external.string(),
15129
- name: exports_external.string(),
15130
- created_at: exports_external.string().datetime(),
15131
- updated_at: exports_external.string().datetime(),
15132
- category: exports_external.string().optional(),
15133
- brand: exports_external.string().optional(),
15134
- model: exports_external.string().optional(),
15135
- purchase_date: exports_external.string().optional(),
15136
- purchase_price: exports_external.number().optional(),
15137
- currency: exports_external.string().optional(),
15138
- warranty_expires: exports_external.string().optional(),
15139
- retailer: exports_external.string().optional(),
15140
- location: exports_external.string().optional(),
15141
- features: exports_external.array(exports_external.string()).optional(),
15142
- notes: exports_external.string().optional(),
15143
- tags: exports_external.array(exports_external.string()).optional(),
15144
- attachments: exports_external.array(AttachmentSchema).optional()
15145
- }).passthrough();
15146
- var NewItemSchema = ItemSchema.omit({
15147
- id: true,
15148
- created_at: true,
15149
- updated_at: true
15150
- }).passthrough();
15151
-
15152
- // src/utils.ts
15153
- import { randomBytes } from "crypto";
15154
- function generateId() {
15155
- return randomBytes(4).toString("hex");
15156
- }
15157
- function toSlug(name) {
15158
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50).replace(/-+$/, "");
15159
- }
15160
-
15161
- // src/backends/filesystem.ts
15162
- class FilesystemBackend {
15163
- dataDir;
15164
- constructor(dataDir) {
15165
- this.dataDir = dataDir;
15166
- }
15167
- get itemsDir() {
15168
- return join(this.dataDir, "items");
15169
- }
15170
- itemDirPath(name, id) {
15171
- return join(this.itemsDir, `${toSlug(name)}-${id}`);
15172
- }
15173
- async findDirById(id) {
15174
- if (!existsSync(this.itemsDir))
15175
- return null;
15176
- const entries = await readdir(this.itemsDir);
15177
- const match = entries.find((e) => e.slice(-8) === id);
15178
- return match ? join(this.itemsDir, match) : null;
15179
- }
15180
- async readItemFromDir(dir) {
15181
- const raw = await readFile(join(dir, "item.json"), "utf-8");
15182
- return ItemSchema.parse(JSON.parse(raw));
15183
- }
15184
- async writeItemToDir(dir, item) {
15185
- await mkdir(dir, { recursive: true });
15186
- await writeFile(join(dir, "item.json"), JSON.stringify(item, null, 2));
15187
- }
15188
- async loadAll() {
15189
- if (!existsSync(this.itemsDir))
15190
- return [];
15191
- const entries = await readdir(this.itemsDir);
15192
- const items = [];
15193
- for (const entry of entries) {
15194
- const itemPath = join(this.itemsDir, entry, "item.json");
15195
- if (!existsSync(itemPath))
15196
- continue;
15197
- try {
15198
- const raw = await readFile(itemPath, "utf-8");
15199
- items.push(ItemSchema.parse(JSON.parse(raw)));
15200
- } catch {}
15201
- }
15202
- return items;
15203
- }
15204
- async addItem(newItem) {
15205
- const id = generateId();
15206
- const now = new Date().toISOString();
15207
- const item = { ...newItem, id, created_at: now, updated_at: now };
15208
- await this.writeItemToDir(this.itemDirPath(item.name, id), item);
15209
- return item;
15210
- }
15211
- async getItem(idOrName) {
15212
- const dirById = await this.findDirById(idOrName);
15213
- if (dirById)
15214
- return this.readItemFromDir(dirById);
15215
- const items = await this.loadAll();
15216
- const lower = idOrName.toLowerCase();
15217
- return items.find((i) => i.name.toLowerCase() === lower) ?? items.find((i) => i.name.toLowerCase().includes(lower)) ?? null;
15218
- }
15219
- async listItems(filter) {
15220
- let items = await this.loadAll();
15221
- if (filter?.category) {
15222
- items = items.filter((i) => i.category === filter.category);
15223
- }
15224
- if (filter?.location) {
15225
- items = items.filter((i) => i.location?.toLowerCase() === filter.location.toLowerCase());
15226
- }
15227
- if (filter?.tags?.length) {
15228
- items = items.filter((i) => filter.tags.every((tag) => i.tags?.includes(tag)));
15229
- }
15230
- return items;
15231
- }
15232
- async updateItem(id, updates) {
15233
- const oldDir = await this.findDirById(id);
15234
- if (!oldDir)
15235
- return null;
15236
- const existing = await this.readItemFromDir(oldDir);
15237
- const updated = {
15238
- ...existing,
15239
- ...updates,
15240
- id,
15241
- updated_at: new Date().toISOString()
15242
- };
15243
- const newDir = this.itemDirPath(updated.name, id);
15244
- if (oldDir !== newDir) {
15245
- await rename(oldDir, newDir);
15246
- }
15247
- await this.writeItemToDir(newDir, updated);
15248
- return updated;
15249
- }
15250
- async deleteItem(id) {
15251
- const dir = await this.findDirById(id);
15252
- if (!dir)
15253
- return false;
15254
- await rm(dir, { recursive: true });
15255
- return true;
15256
- }
15257
- async searchItems(query) {
15258
- const items = await this.loadAll();
15259
- const lower = query.toLowerCase();
15260
- return items.filter((i) => JSON.stringify(i).toLowerCase().includes(lower));
15261
- }
15262
- }
15263
15155
  // ../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
15264
15156
  function isZ4Schema(s) {
15265
15157
  const schema = s;
@@ -17905,7 +17797,6 @@ class Server extends Protocol {
17905
17797
  return this.notification({ method: "notifications/prompts/list_changed" });
17906
17798
  }
17907
17799
  }
17908
-
17909
17800
  // src/tools/add-item.ts
17910
17801
  var addItemInputSchema = exports_external.object({
17911
17802
  name: exports_external.string().describe("Name of the item"),
@@ -18031,6 +17922,61 @@ ${summary}` }]
18031
17922
  };
18032
17923
  }
18033
17924
 
17925
+ // src/tools/add-attachment.ts
17926
+ var addAttachmentInputSchema = exports_external.object({
17927
+ item_id: exports_external.string().describe("ID of the item to attach the file to"),
17928
+ filename: exports_external.string().describe("Filename to store the attachment as (e.g. manual.pdf)"),
17929
+ kind: exports_external.enum(["manual", "receipt", "photo", "warranty", "other"]).describe("Type of attachment"),
17930
+ data_base64: exports_external.string().describe("Base64-encoded file contents"),
17931
+ label: exports_external.string().optional().describe("Human-readable label (e.g. 'Washing machine manual')")
17932
+ });
17933
+ async function addAttachment(backend, input) {
17934
+ const data = Buffer.from(input.data_base64, "base64");
17935
+ const item = await backend.addAttachment(input.item_id, input.filename, input.kind, data, input.label);
17936
+ return {
17937
+ content: [
17938
+ {
17939
+ type: "text",
17940
+ text: JSON.stringify(item, null, 2)
17941
+ }
17942
+ ]
17943
+ };
17944
+ }
17945
+
17946
+ // src/tools/get-attachment.ts
17947
+ var getAttachmentInputSchema = exports_external.object({
17948
+ item_id: exports_external.string().describe("ID of the item"),
17949
+ filename: exports_external.string().describe("Filename of the attachment to retrieve")
17950
+ });
17951
+ async function getAttachment(backend, input) {
17952
+ const data = await backend.getAttachment(input.item_id, input.filename);
17953
+ return {
17954
+ content: [
17955
+ {
17956
+ type: "text",
17957
+ text: data.toString("base64")
17958
+ }
17959
+ ]
17960
+ };
17961
+ }
17962
+
17963
+ // src/tools/delete-attachment.ts
17964
+ var deleteAttachmentInputSchema = exports_external.object({
17965
+ item_id: exports_external.string().describe("ID of the item"),
17966
+ filename: exports_external.string().describe("Filename of the attachment to delete")
17967
+ });
17968
+ async function deleteAttachment(backend, input) {
17969
+ const item = await backend.deleteAttachment(input.item_id, input.filename);
17970
+ return {
17971
+ content: [
17972
+ {
17973
+ type: "text",
17974
+ text: item ? JSON.stringify(item, null, 2) : "Attachment deleted (item not found)"
17975
+ }
17976
+ ]
17977
+ };
17978
+ }
17979
+
18034
17980
  // src/server.ts
18035
17981
  function createServer(backend) {
18036
17982
  const server = new Server({ name: "allourthings", version: "0.1.0" }, { capabilities: { tools: {} } });
@@ -18065,6 +18011,21 @@ function createServer(backend) {
18065
18011
  name: "search_items",
18066
18012
  description: "Full-text search across all item fields",
18067
18013
  inputSchema: zodToJsonSchema(searchItemsInputSchema)
18014
+ },
18015
+ {
18016
+ name: "add_attachment",
18017
+ description: "Attach a file (manual, receipt, photo, warranty, etc.) to an item. File contents must be base64-encoded.",
18018
+ inputSchema: zodToJsonSchema(addAttachmentInputSchema)
18019
+ },
18020
+ {
18021
+ name: "get_attachment",
18022
+ description: "Retrieve an attachment's contents as a base64-encoded string",
18023
+ inputSchema: zodToJsonSchema(getAttachmentInputSchema)
18024
+ },
18025
+ {
18026
+ name: "delete_attachment",
18027
+ description: "Delete an attachment from an item",
18028
+ inputSchema: zodToJsonSchema(deleteAttachmentInputSchema)
18068
18029
  }
18069
18030
  ]
18070
18031
  }));
@@ -18083,6 +18044,12 @@ function createServer(backend) {
18083
18044
  return deleteItem(backend, deleteItemInputSchema.parse(args));
18084
18045
  case "search_items":
18085
18046
  return searchItems(backend, searchItemsInputSchema.parse(args));
18047
+ case "add_attachment":
18048
+ return addAttachment(backend, addAttachmentInputSchema.parse(args));
18049
+ case "get_attachment":
18050
+ return getAttachment(backend, getAttachmentInputSchema.parse(args));
18051
+ case "delete_attachment":
18052
+ return deleteAttachment(backend, deleteAttachmentInputSchema.parse(args));
18086
18053
  default:
18087
18054
  throw new Error(`Unknown tool: ${name}`);
18088
18055
  }
@@ -18092,10 +18059,10 @@ function createServer(backend) {
18092
18059
 
18093
18060
  // src/config.ts
18094
18061
  import { homedir } from "os";
18095
- import { join as join2 } from "path";
18062
+ import { join } from "path";
18096
18063
  function expandTilde(p) {
18097
18064
  if (p === "~" || p.startsWith("~/")) {
18098
- return join2(homedir(), p.slice(2));
18065
+ return join(homedir(), p.slice(2));
18099
18066
  }
18100
18067
  return p;
18101
18068
  }
@@ -18107,13 +18074,13 @@ function resolveDataDir(argv = process.argv, env = process.env) {
18107
18074
  if (env.ALLOURTHINGS_DATA_DIR) {
18108
18075
  return expandTilde(env.ALLOURTHINGS_DATA_DIR);
18109
18076
  }
18110
- return join2(homedir(), "Documents", "AllOurThings");
18077
+ return join(homedir(), "Documents", "AllOurThings");
18111
18078
  }
18112
18079
 
18113
18080
  // src/index.ts
18114
18081
  var dataDir = resolveDataDir();
18115
18082
  console.error(`[allourthings] data directory: ${dataDir}`);
18116
- var backend = new FilesystemBackend(dataDir);
18083
+ var backend = new NativeBackend(dataDir);
18117
18084
  var server = createServer(backend);
18118
18085
  var transport = new StdioServerTransport;
18119
18086
  await server.connect(transport);
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@allourthings/mcp-server",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "mcpName": "io.allourthings/mcp-server",
5
5
  "description": "MCP server for All Our Things — AI-powered household inventory",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/matt-harding/AllOurThings.git"
9
+ "url": "https://github.com/matt-harding/allourthings-mcp.git"
10
10
  },
11
11
  "type": "module",
12
12
  "files": [
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@modelcontextprotocol/sdk": "^1.27.1",
27
+ "@allourthings/core": "^0.1.10",
27
28
  "zod": "^3.24.0",
28
29
  "zod-to-json-schema": "^3.25.1"
29
30
  },