@mcp-z/mcp-sheets 1.1.3 → 1.2.1

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
@@ -209,3 +209,21 @@ mcp-z call sheets spreadsheet-find '{"spreadsheetRef":"Quarterly Report"}'
209
209
  ## Configuration reference
210
210
 
211
211
  See `server.json` for all supported environment variables, CLI arguments, and defaults.
212
+
213
+ ## Storage backends
214
+
215
+ OAuth tokens (`TOKEN_STORE_URI`) and DCR registrations (`DCR_STORE_URI`) are stored through
216
+ [keyv-registry](https://www.npmjs.com/package/keyv-registry), which picks an adapter from the URI protocol.
217
+
218
+ `file://` (the default, under `~/.mcp-z/`) and `memory://` work with no extra setup.
219
+
220
+ Any other backend needs its adapter installed alongside this server. Adapters are resolved with
221
+ `require()`, so a globally installed server finds a globally installed adapter:
222
+
223
+ ```bash
224
+ npm install -g @mcp-z/mcp-sheets @keyv/redis
225
+
226
+ TOKEN_STORE_URI=redis://localhost:6379 mcp-sheets
227
+ ```
228
+
229
+ A protocol whose adapter is missing fails at startup naming the package to install.
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "default", {
5
+ Object.defineProperty(exports, // keyv-file is a direct dependency so the default file:// URIs resolve; keyv-registry
6
+ // loads adapters with require() rather than depending on any of them itself.
7
+ "default", {
6
8
  enumerable: true,
7
9
  get: function() {
8
10
  return createStore;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["createStore","uri","store","keyvRegistry","Error"],"mappings":";;;;+BAGA;;;eAA8BA;;;mEAFL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEV,SAAeA,YAAeC,GAAW;;YAChDC;;;;oBAAQ;;wBAAMC,IAAAA,qBAAY,EAAIF;;;oBAA9BC,QAAQ;oBACd,IAAI,CAACA,OAAO,MAAM,IAAIE,MAAM,AAAC,mCAAsC,OAAJH;oBAC/D;;wBAAOC;;;;IACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\n// keyv-file is a direct dependency so the default file:// URIs resolve; keyv-registry\n// loads adapters with require() rather than depending on any of them itself.\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["createStore","uri","store","keyvRegistry","Error"],"mappings":";;;;+BAGA,sFAAsF;AACtF,6EAA6E;AAE7E;;;eAA8BA;;;mEALL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKV,SAAeA,YAAeC,GAAW;;YAChDC;;;;oBAAQ;;wBAAMC,IAAAA,qBAAY,EAAIF;;;oBAA9BC,QAAQ;oBACd,IAAI,CAACA,OAAO,MAAM,IAAIE,MAAM,AAAC,mCAAsC,OAAJH;oBAC/D;;wBAAOC;;;;IACT"}
@@ -7,7 +7,7 @@ export declare function readPkg(): {
7
7
  };
8
8
  };
9
9
  /**
10
- * Handle --version/--help flags and the `version` subcommand before config parsing.
10
+ * Handle --version/--help flags before config parsing.
11
11
  * These must work without requiring any configuration or heavy dependency.
12
12
  */
13
13
  export declare function handleVersionHelp(args: string[]): {
@@ -7,7 +7,7 @@ export declare function readPkg(): {
7
7
  };
8
8
  };
9
9
  /**
10
- * Handle --version/--help flags and the `version` subcommand before config parsing.
10
+ * Handle --version/--help flags before config parsing.
11
11
  * These must work without requiring any configuration or heavy dependency.
12
12
  */
13
13
  export declare function handleVersionHelp(args: string[]): {
@@ -56,29 +56,31 @@ function _interop_require_wildcard(obj, nodeInterop) {
56
56
  if (cache) cache.set(obj, newObj);
57
57
  return newObj;
58
58
  }
59
- // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`
59
+ // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`
60
60
  // resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and
61
61
  // @mcp-z/server, which this path must not touch.
62
62
  var pkg = JSON.parse(_fs.readFileSync(_path.join((0, _modulerootsync.default)(_url.fileURLToPath(require("url").pathToFileURL(__filename).toString())), 'package.json'), 'utf-8'));
63
- var HELP_TEXT = "\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version Show version number\n --help Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets version # Print version number\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n".trim();
63
+ var HELP_TEXT = "\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version, -v Show version number\n --help, -h Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nStorage Backends:\n TOKEN_STORE_URI and DCR_STORE_URI accept any keyv-registry protocol.\n file:// (the default) and memory:// work out of the box. Any other backend\n needs its adapter installed alongside this server:\n npm install -g @keyv/redis\n TOKEN_STORE_URI=redis://localhost:6379 mcp-sheets\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n".trim();
64
64
  function readPkg() {
65
65
  return pkg;
66
66
  }
67
67
  function handleVersionHelp(args) {
68
- var _parseArgs = (0, _util.parseArgs)({
68
+ var values = (0, _util.parseArgs)({
69
69
  args: args,
70
70
  options: {
71
71
  version: {
72
- type: 'boolean'
72
+ type: 'boolean',
73
+ short: 'v'
73
74
  },
74
75
  help: {
75
- type: 'boolean'
76
+ type: 'boolean',
77
+ short: 'h'
76
78
  }
77
79
  },
78
80
  strict: false,
79
81
  allowPositionals: true
80
- }), values = _parseArgs.values, positionals = _parseArgs.positionals;
81
- if (values.version || positionals[0] === 'version') return {
82
+ }).values;
83
+ if (values.version) return {
82
84
  handled: true,
83
85
  output: pkg.version
84
86
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/version-help.ts"],"sourcesContent":["import * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\n\n// Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`\n// resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and\n// @mcp-z/server, which this path must not touch.\nconst pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));\n\nconst HELP_TEXT = `\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version Show version number\n --help Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets version # Print version number\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n`.trim();\n\n/** Package metadata read from package.json, resolved relative to this file. */\nexport function readPkg(): { name: string; version: string; repository?: string | { url?: string } } {\n return pkg;\n}\n\n/**\n * Handle --version/--help flags and the `version` subcommand before config parsing.\n * These must work without requiring any configuration or heavy dependency.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values, positionals } = parseArgs({\n args,\n options: {\n version: { type: 'boolean' },\n help: { type: 'boolean' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n if (values.version || positionals[0] === 'version') return { handled: true, output: pkg.version };\n if (values.help) return { handled: true, output: HELP_TEXT };\n return { handled: false };\n}\n"],"names":["handleVersionHelp","readPkg","pkg","JSON","parse","fs","readFileSync","path","join","moduleRoot","url","fileURLToPath","HELP_TEXT","trim","args","parseArgs","options","version","type","help","strict","allowPositionals","values","positionals","handled","output"],"mappings":";;;;;;;;;;;QAsEgBA;eAAAA;;QARAC;eAAAA;;;0DA9DI;qEACG;4DACD;2DACD;oBACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE1B,6FAA6F;AAC7F,gGAAgG;AAChG,iDAAiD;AACjD,IAAMC,MAAMC,KAAKC,KAAK,CAACC,IAAGC,YAAY,CAACC,MAAKC,IAAI,CAACC,IAAAA,uBAAU,EAACC,KAAIC,aAAa,CAAC,uDAAmB,iBAAiB;AAElH,IAAMC,YAAY,2lFAgDhBC,IAAI;AAGC,SAASZ;IACd,OAAOC;AACT;AAMO,SAASF,kBAAkBc,IAAc;IAC9C,IAAgCC,aAAAA,IAAAA,eAAS,EAAC;QACxCD,MAAAA;QACAE,SAAS;YACPC,SAAS;gBAAEC,MAAM;YAAU;YAC3BC,MAAM;gBAAED,MAAM;YAAU;QAC1B;QACAE,QAAQ;QACRC,kBAAkB;IACpB,IARQC,SAAwBP,WAAxBO,QAAQC,cAAgBR,WAAhBQ;IAUhB,IAAID,OAAOL,OAAO,IAAIM,WAAW,CAAC,EAAE,KAAK,WAAW,OAAO;QAAEC,SAAS;QAAMC,QAAQvB,IAAIe,OAAO;IAAC;IAChG,IAAIK,OAAOH,IAAI,EAAE,OAAO;QAAEK,SAAS;QAAMC,QAAQb;IAAU;IAC3D,OAAO;QAAEY,SAAS;IAAM;AAC1B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/version-help.ts"],"sourcesContent":["import * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\n\n// Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`\n// resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and\n// @mcp-z/server, which this path must not touch.\nconst pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));\n\nconst HELP_TEXT = `\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version, -v Show version number\n --help, -h Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nStorage Backends:\n TOKEN_STORE_URI and DCR_STORE_URI accept any keyv-registry protocol.\n file:// (the default) and memory:// work out of the box. Any other backend\n needs its adapter installed alongside this server:\n npm install -g @keyv/redis\n TOKEN_STORE_URI=redis://localhost:6379 mcp-sheets\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n`.trim();\n\n/** Package metadata read from package.json, resolved relative to this file. */\nexport function readPkg(): { name: string; version: string; repository?: string | { url?: string } } {\n return pkg;\n}\n\n/**\n * Handle --version/--help flags before config parsing.\n * These must work without requiring any configuration or heavy dependency.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values } = parseArgs({\n args,\n options: {\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n if (values.version) return { handled: true, output: pkg.version };\n if (values.help) return { handled: true, output: HELP_TEXT };\n return { handled: false };\n}\n"],"names":["handleVersionHelp","readPkg","pkg","JSON","parse","fs","readFileSync","path","join","moduleRoot","url","fileURLToPath","HELP_TEXT","trim","args","values","parseArgs","options","version","type","short","help","strict","allowPositionals","handled","output"],"mappings":";;;;;;;;;;;QAyEgBA;eAAAA;;QARAC;eAAAA;;;0DAjEI;qEACG;4DACD;2DACD;oBACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE1B,mFAAmF;AACnF,gGAAgG;AAChG,iDAAiD;AACjD,IAAMC,MAAMC,KAAKC,KAAK,CAACC,IAAGC,YAAY,CAACC,MAAKC,IAAI,CAACC,IAAAA,uBAAU,EAACC,KAAIC,aAAa,CAAC,uDAAmB,iBAAiB;AAElH,IAAMC,YAAY,yxFAmDhBC,IAAI;AAGC,SAASZ;IACd,OAAOC;AACT;AAMO,SAASF,kBAAkBc,IAAc;IAC9C,IAAM,AAAEC,SAAWC,IAAAA,eAAS,EAAC;QAC3BF,MAAAA;QACAG,SAAS;YACPC,SAAS;gBAAEC,MAAM;gBAAWC,OAAO;YAAI;YACvCC,MAAM;gBAAEF,MAAM;gBAAWC,OAAO;YAAI;QACtC;QACAE,QAAQ;QACRC,kBAAkB;IACpB,GARQR;IAUR,IAAIA,OAAOG,OAAO,EAAE,OAAO;QAAEM,SAAS;QAAMC,QAAQvB,IAAIgB,OAAO;IAAC;IAChE,IAAIH,OAAOM,IAAI,EAAE,OAAO;QAAEG,SAAS;QAAMC,QAAQb;IAAU;IAC3D,OAAO;QAAEY,SAAS;IAAM;AAC1B"}
@@ -1,4 +1,6 @@
1
1
  import keyvRegistry from 'keyv-registry';
2
+ // keyv-file is a direct dependency so the default file:// URIs resolve; keyv-registry
3
+ // loads adapters with require() rather than depending on any of them itself.
2
4
  export default async function createStore(uri) {
3
5
  const store = await keyvRegistry(uri);
4
6
  if (!store) throw new Error(`Failed to create store for URI: ${uri}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["keyvRegistry","createStore","uri","store","Error"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,eAAe,eAAeC,YAAeC,GAAW;IACtD,MAAMC,QAAQ,MAAMH,aAAgBE;IACpC,IAAI,CAACC,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAEF,KAAK;IACpE,OAAOC;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\n// keyv-file is a direct dependency so the default file:// URIs resolve; keyv-registry\n// loads adapters with require() rather than depending on any of them itself.\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["keyvRegistry","createStore","uri","store","Error"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,sFAAsF;AACtF,6EAA6E;AAE7E,eAAe,eAAeC,YAAeC,GAAW;IACtD,MAAMC,QAAQ,MAAMH,aAAgBE;IACpC,IAAI,CAACC,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAEF,KAAK;IACpE,OAAOC;AACT"}
@@ -7,7 +7,7 @@ export declare function readPkg(): {
7
7
  };
8
8
  };
9
9
  /**
10
- * Handle --version/--help flags and the `version` subcommand before config parsing.
10
+ * Handle --version/--help flags before config parsing.
11
11
  * These must work without requiring any configuration or heavy dependency.
12
12
  */
13
13
  export declare function handleVersionHelp(args: string[]): {
@@ -3,7 +3,7 @@ import moduleRoot from 'module-root-sync';
3
3
  import * as path from 'path';
4
4
  import * as url from 'url';
5
5
  import { parseArgs } from 'util';
6
- // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`
6
+ // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`
7
7
  // resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and
8
8
  // @mcp-z/server, which this path must not touch.
9
9
  const pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));
@@ -13,8 +13,8 @@ Usage: mcp-sheets [options]
13
13
  MCP server for Google Sheets spreadsheet management with OAuth authentication.
14
14
 
15
15
  Options:
16
- --version Show version number
17
- --help Show this help message
16
+ --version, -v Show version number
17
+ --help, -h Show this help message
18
18
  --auth=<mode> Authentication mode (default: loopback-oauth)
19
19
  Modes: loopback-oauth, service-account, dcr
20
20
  --headless Disable browser auto-open, return auth URL instead
@@ -28,9 +28,6 @@ Options:
28
28
  --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)
29
29
  --base-url=<url> Base URL for HTTP file serving (optional)
30
30
 
31
- Commands:
32
- version Show version number
33
-
34
31
  Environment Variables:
35
32
  GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)
36
33
  GOOGLE_CLIENT_SECRET OAuth client secret (optional)
@@ -45,12 +42,18 @@ Environment Variables:
45
42
  RESOURCE_STORE_URI Resource store URI (optional, file://)
46
43
  BASE_URL Base URL for HTTP file serving (optional)
47
44
 
45
+ Storage Backends:
46
+ TOKEN_STORE_URI and DCR_STORE_URI accept any keyv-registry protocol.
47
+ file:// (the default) and memory:// work out of the box. Any other backend
48
+ needs its adapter installed alongside this server:
49
+ npm install -g @keyv/redis
50
+ TOKEN_STORE_URI=redis://localhost:6379 mcp-sheets
51
+
48
52
  OAuth Scopes:
49
53
  openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive
50
54
 
51
55
  Examples:
52
56
  mcp-sheets # Use default settings
53
- mcp-sheets version # Print version number
54
57
  mcp-sheets --auth=service-account # Use service account auth
55
58
  mcp-sheets --port=3000 # HTTP transport on port 3000
56
59
  mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI
@@ -60,23 +63,25 @@ Examples:
60
63
  return pkg;
61
64
  }
62
65
  /**
63
- * Handle --version/--help flags and the `version` subcommand before config parsing.
66
+ * Handle --version/--help flags before config parsing.
64
67
  * These must work without requiring any configuration or heavy dependency.
65
68
  */ export function handleVersionHelp(args) {
66
- const { values, positionals } = parseArgs({
69
+ const { values } = parseArgs({
67
70
  args,
68
71
  options: {
69
72
  version: {
70
- type: 'boolean'
73
+ type: 'boolean',
74
+ short: 'v'
71
75
  },
72
76
  help: {
73
- type: 'boolean'
77
+ type: 'boolean',
78
+ short: 'h'
74
79
  }
75
80
  },
76
81
  strict: false,
77
82
  allowPositionals: true
78
83
  });
79
- if (values.version || positionals[0] === 'version') return {
84
+ if (values.version) return {
80
85
  handled: true,
81
86
  output: pkg.version
82
87
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/version-help.ts"],"sourcesContent":["import * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\n\n// Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`\n// resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and\n// @mcp-z/server, which this path must not touch.\nconst pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));\n\nconst HELP_TEXT = `\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version Show version number\n --help Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets version # Print version number\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n`.trim();\n\n/** Package metadata read from package.json, resolved relative to this file. */\nexport function readPkg(): { name: string; version: string; repository?: string | { url?: string } } {\n return pkg;\n}\n\n/**\n * Handle --version/--help flags and the `version` subcommand before config parsing.\n * These must work without requiring any configuration or heavy dependency.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values, positionals } = parseArgs({\n args,\n options: {\n version: { type: 'boolean' },\n help: { type: 'boolean' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n if (values.version || positionals[0] === 'version') return { handled: true, output: pkg.version };\n if (values.help) return { handled: true, output: HELP_TEXT };\n return { handled: false };\n}\n"],"names":["fs","moduleRoot","path","url","parseArgs","pkg","JSON","parse","readFileSync","join","fileURLToPath","HELP_TEXT","trim","readPkg","handleVersionHelp","args","values","positionals","options","version","type","help","strict","allowPositionals","handled","output"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,OAAOC,gBAAgB,mBAAmB;AAC1C,YAAYC,UAAU,OAAO;AAC7B,YAAYC,SAAS,MAAM;AAC3B,SAASC,SAAS,QAAQ,OAAO;AAEjC,6FAA6F;AAC7F,gGAAgG;AAChG,iDAAiD;AACjD,MAAMC,MAAMC,KAAKC,KAAK,CAACP,GAAGQ,YAAY,CAACN,KAAKO,IAAI,CAACR,WAAWE,IAAIO,aAAa,CAAC,YAAYP,GAAG,IAAI,iBAAiB;AAElH,MAAMQ,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDnB,CAAC,CAACC,IAAI;AAEN,6EAA6E,GAC7E,OAAO,SAASC;IACd,OAAOR;AACT;AAEA;;;CAGC,GACD,OAAO,SAASS,kBAAkBC,IAAc;IAC9C,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGb,UAAU;QACxCW;QACAG,SAAS;YACPC,SAAS;gBAAEC,MAAM;YAAU;YAC3BC,MAAM;gBAAED,MAAM;YAAU;QAC1B;QACAE,QAAQ;QACRC,kBAAkB;IACpB;IAEA,IAAIP,OAAOG,OAAO,IAAIF,WAAW,CAAC,EAAE,KAAK,WAAW,OAAO;QAAEO,SAAS;QAAMC,QAAQpB,IAAIc,OAAO;IAAC;IAChG,IAAIH,OAAOK,IAAI,EAAE,OAAO;QAAEG,SAAS;QAAMC,QAAQd;IAAU;IAC3D,OAAO;QAAEa,SAAS;IAAM;AAC1B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/version-help.ts"],"sourcesContent":["import * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\n\n// Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`\n// resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and\n// @mcp-z/server, which this path must not touch.\nconst pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));\n\nconst HELP_TEXT = `\nUsage: mcp-sheets [options]\n\nMCP server for Google Sheets spreadsheet management with OAuth authentication.\n\nOptions:\n --version, -v Show version number\n --help, -h Show this help message\n --auth=<mode> Authentication mode (default: loopback-oauth)\n Modes: loopback-oauth, service-account, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)\n --dcr-verify-url=<url> External verification endpoint (required for external mode)\n --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)\n --port=<port> Enable HTTP transport on specified port\n --stdio Enable stdio transport (default if no port)\n --log-level=<level> Logging level (default: info)\n --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)\n --base-url=<url> Base URL for HTTP file serving (optional)\n\nEnvironment Variables:\n GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)\n GOOGLE_CLIENT_SECRET OAuth client secret (optional)\n AUTH_MODE Default authentication mode (optional)\n HEADLESS Disable browser auto-open (optional)\n DCR_MODE DCR mode (optional, same format as --dcr-mode)\n DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)\n DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)\n TOKEN_STORE_URI Token storage URI (optional)\n PORT Default HTTP port (optional)\n LOG_LEVEL Default logging level (optional)\n RESOURCE_STORE_URI Resource store URI (optional, file://)\n BASE_URL Base URL for HTTP file serving (optional)\n\nStorage Backends:\n TOKEN_STORE_URI and DCR_STORE_URI accept any keyv-registry protocol.\n file:// (the default) and memory:// work out of the box. Any other backend\n needs its adapter installed alongside this server:\n npm install -g @keyv/redis\n TOKEN_STORE_URI=redis://localhost:6379 mcp-sheets\n\nOAuth Scopes:\n openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive\n\nExamples:\n mcp-sheets # Use default settings\n mcp-sheets --auth=service-account # Use service account auth\n mcp-sheets --port=3000 # HTTP transport on port 3000\n mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI\n GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var\n`.trim();\n\n/** Package metadata read from package.json, resolved relative to this file. */\nexport function readPkg(): { name: string; version: string; repository?: string | { url?: string } } {\n return pkg;\n}\n\n/**\n * Handle --version/--help flags before config parsing.\n * These must work without requiring any configuration or heavy dependency.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values } = parseArgs({\n args,\n options: {\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n if (values.version) return { handled: true, output: pkg.version };\n if (values.help) return { handled: true, output: HELP_TEXT };\n return { handled: false };\n}\n"],"names":["fs","moduleRoot","path","url","parseArgs","pkg","JSON","parse","readFileSync","join","fileURLToPath","HELP_TEXT","trim","readPkg","handleVersionHelp","args","values","options","version","type","short","help","strict","allowPositionals","handled","output"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,OAAOC,gBAAgB,mBAAmB;AAC1C,YAAYC,UAAU,OAAO;AAC7B,YAAYC,SAAS,MAAM;AAC3B,SAASC,SAAS,QAAQ,OAAO;AAEjC,mFAAmF;AACnF,gGAAgG;AAChG,iDAAiD;AACjD,MAAMC,MAAMC,KAAKC,KAAK,CAACP,GAAGQ,YAAY,CAACN,KAAKO,IAAI,CAACR,WAAWE,IAAIO,aAAa,CAAC,YAAYP,GAAG,IAAI,iBAAiB;AAElH,MAAMQ,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDnB,CAAC,CAACC,IAAI;AAEN,6EAA6E,GAC7E,OAAO,SAASC;IACd,OAAOR;AACT;AAEA;;;CAGC,GACD,OAAO,SAASS,kBAAkBC,IAAc;IAC9C,MAAM,EAAEC,MAAM,EAAE,GAAGZ,UAAU;QAC3BW;QACAE,SAAS;YACPC,SAAS;gBAAEC,MAAM;gBAAWC,OAAO;YAAI;YACvCC,MAAM;gBAAEF,MAAM;gBAAWC,OAAO;YAAI;QACtC;QACAE,QAAQ;QACRC,kBAAkB;IACpB;IAEA,IAAIP,OAAOE,OAAO,EAAE,OAAO;QAAEM,SAAS;QAAMC,QAAQpB,IAAIa,OAAO;IAAC;IAChE,IAAIF,OAAOK,IAAI,EAAE,OAAO;QAAEG,SAAS;QAAMC,QAAQd;IAAU;IAC3D,OAAO;QAAEa,SAAS;IAAM;AAC1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-z/mcp-sheets",
3
- "version": "1.1.3",
3
+ "version": "1.2.1",
4
4
  "description": "MCP server for Google Sheets integration with OAuth authentication, spreadsheet management, batch operations, and advanced formatting",
5
5
  "keywords": [
6
6
  "sheets",
@@ -60,11 +60,9 @@
60
60
  "format": "tsds format",
61
61
  "prepublish:check": "ncp",
62
62
  "prepublishOnly": "tsds validate",
63
- "test": "npm run test:unit && npm run test:integration",
64
- "test:engines": "nvu engines tsds test:node --no-timeouts 'test/**/*.test.ts'",
65
- "test:integration": "tsds test:node --no-timeouts 'test/integration/**/*.test.ts'",
63
+ "test": "tsds test:node --no-timeouts",
64
+ "test:engines": "nvu engines tsds test:node --no-timeouts",
66
65
  "test:setup": "node scripts/setup-test.ts",
67
- "test:unit": "tsds test:node --no-timeouts 'test/unit/**/*.test.ts'",
68
66
  "version": "tsds version"
69
67
  },
70
68
  "dependencies": {
@@ -76,8 +74,9 @@
76
74
  "csv-parse": "^7.0.2",
77
75
  "express": "^5.0.0",
78
76
  "google-auth-library": "10.5.0",
79
- "googleapis": "^174.0.1",
80
- "keyv-registry": "^1.0.0",
77
+ "googleapis": "174.0.1",
78
+ "keyv-file": "5.3.3",
79
+ "keyv-registry": "^2.0.0",
81
80
  "module-root-sync": "^2.0.0",
82
81
  "pino": "^10.0.0",
83
82
  "zod": "^4.0.0"
@@ -89,6 +88,7 @@
89
88
  "@types/mocha": "^10.0.10",
90
89
  "@types/node": "^26.2.0",
91
90
  "dotenv": "^17.2.3",
91
+ "fs-remove-compat": "^1.0.4",
92
92
  "get-port": "5.1.1",
93
93
  "keyv": "^5.0.0",
94
94
  "node-version-use": "^2.4.7",