@mcp-z/mcp-sheets 1.1.2 → 1.2.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/bin/server.js CHANGED
@@ -1,5 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // biome-ignore lint/security/noGlobalEval: dual esm and cjs
4
- if (typeof require === 'undefined') eval("import('../dist/esm/index.js').then((cli) => cli.default(process.argv.slice(2), 'mcp-sheets')).catch((err) => { console.error(err); process.exit(-1); });");
5
- else require('../dist/cjs/index.js')(process.argv.slice(2), 'mcp-sheets');
3
+ // Checks --version/--help/`version` via the dependency-free version-help module before ever
4
+ // touching index.js, which statically re-exports the mcp/setup/schemas namespaces (googleapis,
5
+ // @modelcontextprotocol/sdk, @mcp-z/oauth-google, @mcp-z/server et al.) -- importing index.js at
6
+ // all, even without calling anything in it, evaluates that whole graph.
7
+ if (typeof require === 'undefined') {
8
+ // biome-ignore lint/security/noGlobalEval: dual esm and cjs
9
+ eval(
10
+ "import('../dist/esm/setup/version-help.js').then(({ handleVersionHelp }) => { const result = handleVersionHelp(process.argv.slice(2)); if (result.handled) { console.log(result.output); process.exit(0); } return import('../dist/esm/index.js').then((cli) => cli.default(process.argv.slice(2), 'mcp-sheets')); }).catch((err) => { console.error(err); process.exit(-1); });"
11
+ );
12
+ } else {
13
+ const { handleVersionHelp } = require('../dist/cjs/setup/version-help.js');
14
+ const result = handleVersionHelp(process.argv.slice(2));
15
+ if (result.handled) {
16
+ console.log(result.output);
17
+ process.exit(0);
18
+ }
19
+ require('../dist/cjs/index.js')(process.argv.slice(2), 'mcp-sheets');
20
+ }
package/dist/cjs/index.js CHANGED
@@ -28,9 +28,7 @@ _export(exports, {
28
28
  return startServer;
29
29
  }
30
30
  });
31
- var _configts = require("./setup/config.js");
32
- var _httpts = require("./setup/http.js");
33
- var _stdiots = require("./setup/stdio.js");
31
+ var _versionhelpts = require("./setup/version-help.js");
34
32
  var _constantsts = require("./constants.js");
35
33
  var _indexts = /*#__PURE__*/ _interop_require_wildcard(require("./mcp/index.js"));
36
34
  var _indexts1 = /*#__PURE__*/ _interop_require_wildcard(require("./schemas/index.js"));
@@ -206,33 +204,49 @@ function _ts_generator(thisArg, body) {
206
204
  }
207
205
  function startServer(config) {
208
206
  return _async_to_generator(function() {
209
- var _ref, logger, close, _tmp;
207
+ var createHTTPServer, createStdioServer, _ref, logger, close, _tmp;
210
208
  return _ts_generator(this, function(_state) {
211
209
  switch(_state.label){
212
210
  case 0:
213
- if (!(config.transport.type === 'stdio')) return [
214
- 3,
215
- 2
216
- ];
217
211
  return [
218
212
  4,
219
- (0, _stdiots.createStdioServer)(config)
213
+ Promise.resolve().then(function() {
214
+ return /*#__PURE__*/ _interop_require_wildcard(require("./setup/http.js"));
215
+ })
220
216
  ];
221
217
  case 1:
222
- _tmp = _state.sent();
218
+ createHTTPServer = _state.sent().createHTTPServer;
223
219
  return [
220
+ 4,
221
+ Promise.resolve().then(function() {
222
+ return /*#__PURE__*/ _interop_require_wildcard(require("./setup/stdio.js"));
223
+ })
224
+ ];
225
+ case 2:
226
+ createStdioServer = _state.sent().createStdioServer;
227
+ if (!(config.transport.type === 'stdio')) return [
224
228
  3,
225
229
  4
226
230
  ];
227
- case 2:
228
231
  return [
229
232
  4,
230
- (0, _httpts.createHTTPServer)(config)
233
+ createStdioServer(config)
231
234
  ];
232
235
  case 3:
233
236
  _tmp = _state.sent();
234
- _state.label = 4;
237
+ return [
238
+ 3,
239
+ 6
240
+ ];
235
241
  case 4:
242
+ return [
243
+ 4,
244
+ createHTTPServer(config)
245
+ ];
246
+ case 5:
247
+ _tmp = _state.sent();
248
+ _state.label = 6;
249
+ case 6:
236
250
  _ref = _tmp, logger = _ref.logger, close = _ref.close;
237
251
  process.on('SIGINT', function() {
238
252
  return _async_to_generator(function() {
@@ -258,7 +272,7 @@ function startServer(config) {
258
272
  4,
259
273
  new Promise(function() {})
260
274
  ];
261
- case 5:
275
+ case 7:
262
276
  _state.sent();
263
277
  return [
264
278
  2
@@ -269,23 +283,30 @@ function startServer(config) {
269
283
  }
270
284
  function main() {
271
285
  return _async_to_generator(function() {
272
- var versionHelpResult, config;
286
+ var versionHelpResult, createConfig, config;
273
287
  return _ts_generator(this, function(_state) {
274
288
  switch(_state.label){
275
289
  case 0:
276
290
  // Check for help/version flags FIRST, before config parsing
277
- versionHelpResult = (0, _configts.handleVersionHelp)(process.argv);
291
+ versionHelpResult = (0, _versionhelpts.handleVersionHelp)(process.argv);
278
292
  if (versionHelpResult.handled) {
279
293
  console.log(versionHelpResult.output);
280
294
  process.exit(0);
281
295
  }
282
- // Only parse config if no help/version flags
283
- config = (0, _configts.createConfig)();
284
296
  return [
285
297
  4,
286
- startServer(config)
298
+ Promise.resolve().then(function() {
299
+ return /*#__PURE__*/ _interop_require_wildcard(require("./setup/config.js"));
300
+ })
287
301
  ];
288
302
  case 1:
303
+ createConfig = _state.sent().createConfig;
304
+ config = createConfig();
305
+ return [
306
+ 4,
307
+ startServer(config)
308
+ ];
309
+ case 2:
289
310
  _state.sent();
290
311
  return [
291
312
  2
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/index.ts"],"sourcesContent":["import { createConfig, handleVersionHelp } from './setup/config.ts';\nimport { createHTTPServer } from './setup/http.ts';\nimport { createStdioServer } from './setup/stdio.ts';\nimport type { ServerConfig } from './types.ts';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.ts';\nexport * as schemas from './schemas/index.ts';\nexport * as setup from './setup/index.ts';\nexport * from './types.ts';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["GOOGLE_SCOPE","main","mcp","schemas","setup","startServer","config","logger","close","transport","type","createStdioServer","createHTTPServer","process","on","exit","info","Promise","versionHelpResult","handleVersionHelp","argv","handled","console","log","output","createConfig","URL","pathname"],"mappings":";;;;;;;;;;;QAKSA;eAAAA,yBAAY;;QAkBrB;eAA8BC;;QAjBlBC;;;QACAC;;;QACAC;;;QAGUC;eAAAA;;;wBAX0B;sBACf;uBACC;2BAGL;+DACR;gEACI;gEACF;qBACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEP,SAAeA,YAAYC,MAAoB;;YAC1BA,MAAlBC,QAAQC;;;;yBAAUF,CAAAA,OAAOG,SAAS,CAACC,IAAI,KAAK,OAAM,GAAhCJ;;;;oBAAoC;;wBAAMK,IAAAA,0BAAiB,EAACL;;;2BAAxB;;;;;;oBAAkC;;wBAAMM,IAAAA,wBAAgB,EAACN;;;2BAAvB;;;oBAAtEA,aAAlBC,SAAkBD,KAAlBC,QAAQC,QAAUF,KAAVE;oBAEhBK,QAAQC,EAAE,CAAC,UAAU;;;;;wCACnB;;4CAAMN;;;wCAAN;wCACAK,QAAQE,IAAI,CAAC;;;;;;wBACf;;oBAEAR,OAAOS,IAAI,CAAC,AAAC,uBAA4C,OAAtBV,OAAOG,SAAS,CAACC,IAAI,EAAC;oBACzD;;wBAAM,IAAIO,QAAQ,YAAO;;;oBAAzB;;;;;;IACF;;AAEe,SAAehB;;YAEtBiB,mBAOAZ;;;;oBARN,4DAA4D;oBACtDY,oBAAoBC,IAAAA,2BAAiB,EAACN,QAAQO,IAAI;oBACxD,IAAIF,kBAAkBG,OAAO,EAAE;wBAC7BC,QAAQC,GAAG,CAACL,kBAAkBM,MAAM;wBACpCX,QAAQE,IAAI,CAAC;oBACf;oBAEA,6CAA6C;oBACvCT,SAASmB,IAAAA,sBAAY;oBAC3B;;wBAAMpB,YAAYC;;;oBAAlB;;;;;;IACF;;AAEA,IAAIO,QAAQO,IAAI,CAAC,EAAE,KAAK,IAAIM,IAAI,qDAAiBC,QAAQ,EAAE;IACzD1B;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/index.ts"],"sourcesContent":["import { handleVersionHelp } from './setup/version-help.ts';\nimport type { ServerConfig } from './types.ts';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.ts';\nexport * as schemas from './schemas/index.ts';\nexport * as setup from './setup/index.ts';\nexport * from './types.ts';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n // createHTTPServer/createStdioServer pull in @modelcontextprotocol/sdk and every mcp/tools/*.ts\n // (googleapis included); deferred so a --version/--help run never reaches them.\n const { createHTTPServer } = await import('./setup/http.ts');\n const { createStdioServer } = await import('./setup/stdio.ts');\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags. config.ts's own heavy imports (@mcp-z/oauth-google,\n // @mcp-z/server) are deferred internally, so this static-looking call stays cheap until here.\n const { createConfig } = await import('./setup/config.ts');\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["GOOGLE_SCOPE","main","mcp","schemas","setup","startServer","config","createHTTPServer","createStdioServer","logger","close","transport","type","process","on","exit","info","Promise","versionHelpResult","createConfig","handleVersionHelp","argv","handled","console","log","output","URL","pathname"],"mappings":";;;;;;;;;;;QAGSA;eAAAA,yBAAY;;QAsBrB;eAA8BC;;QArBlBC;;;QACAC;;;QACAC;;;QAGUC;eAAAA;;;6BATY;2BAGL;+DACR;gEACI;gEACF;qBACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEP,SAAeA,YAAYC,MAAoB;;YAG5CC,kBACAC,mBACkBF,MAAlBG,QAAQC;;;;oBAFa;;wBAAM;2EAAA,QAAO;;;;oBAAlCH,mBAAqB,cAArBA;oBACsB;;wBAAM;2EAAA,QAAO;;;;oBAAnCC,oBAAsB,cAAtBA;yBACkBF,CAAAA,OAAOK,SAAS,CAACC,IAAI,KAAK,OAAM,GAAhCN;;;;oBAAoC;;wBAAME,kBAAkBF;;;2BAAxB;;;;;;oBAAkC;;wBAAMC,iBAAiBD;;;2BAAvB;;;oBAAtEA,aAAlBG,SAAkBH,KAAlBG,QAAQC,QAAUJ,KAAVI;oBAEhBG,QAAQC,EAAE,CAAC,UAAU;;;;;wCACnB;;4CAAMJ;;;wCAAN;wCACAG,QAAQE,IAAI,CAAC;;;;;;wBACf;;oBAEAN,OAAOO,IAAI,CAAC,AAAC,uBAA4C,OAAtBV,OAAOK,SAAS,CAACC,IAAI,EAAC;oBACzD;;wBAAM,IAAIK,QAAQ,YAAO;;;oBAAzB;;;;;;IACF;;AAEe,SAAehB;;YAEtBiB,mBAQEC,cACFb;;;;oBAVN,4DAA4D;oBACtDY,oBAAoBE,IAAAA,gCAAiB,EAACP,QAAQQ,IAAI;oBACxD,IAAIH,kBAAkBI,OAAO,EAAE;wBAC7BC,QAAQC,GAAG,CAACN,kBAAkBO,MAAM;wBACpCZ,QAAQE,IAAI,CAAC;oBACf;oBAIyB;;wBAAM;2EAAA,QAAO;;;;oBAA9BI,eAAiB,cAAjBA;oBACFb,SAASa;oBACf;;wBAAMd,YAAYC;;;oBAAlB;;;;;;IACF;;AAEA,IAAIO,QAAQQ,IAAI,CAAC,EAAE,KAAK,IAAIK,IAAI,qDAAiBC,QAAQ,EAAE;IACzD1B;AACF"}
@@ -1,12 +1,4 @@
1
1
  import type { ServerConfig } from '../types.js';
2
- /**
3
- * Handle --version and --help flags before config parsing.
4
- * These should work without requiring any configuration.
5
- */
6
- export declare function handleVersionHelp(args: string[]): {
7
- handled: boolean;
8
- output?: string;
9
- };
10
2
  /**
11
3
  * Parse Sheets server configuration from CLI arguments and environment.
12
4
  *
@@ -1,12 +1,4 @@
1
1
  import type { ServerConfig } from '../types.js';
2
- /**
3
- * Handle --version and --help flags before config parsing.
4
- * These should work without requiring any configuration.
5
- */
6
- export declare function handleVersionHelp(args: string[]): {
7
- handled: boolean;
8
- output?: string;
9
- };
10
2
  /**
11
3
  * Parse Sheets server configuration from CLI arguments and environment.
12
4
  *
@@ -12,22 +12,16 @@ _export(exports, {
12
12
  get createConfig () {
13
13
  return createConfig;
14
14
  },
15
- get handleVersionHelp () {
16
- return handleVersionHelp;
17
- },
18
15
  get parseConfig () {
19
16
  return parseConfig;
20
17
  }
21
18
  });
22
- var _oauthgoogle = require("@mcp-z/oauth-google");
23
- var _server = require("@mcp-z/server");
24
- var _fs = /*#__PURE__*/ _interop_require_wildcard(require("fs"));
25
- var _modulerootsync = /*#__PURE__*/ _interop_require_default(require("module-root-sync"));
19
+ var _module = require("module");
26
20
  var _os = require("os");
27
21
  var _path = /*#__PURE__*/ _interop_require_wildcard(require("path"));
28
- var _url = /*#__PURE__*/ _interop_require_wildcard(require("url"));
29
22
  var _util = require("util");
30
23
  var _constantsts = require("../constants.js");
24
+ var _versionhelpts = require("./version-help.js");
31
25
  function _define_property(obj, key, value) {
32
26
  if (key in obj) {
33
27
  Object.defineProperty(obj, key, {
@@ -39,11 +33,6 @@ function _define_property(obj, key, value) {
39
33
  } else obj[key] = value;
40
34
  return obj;
41
35
  }
42
- function _interop_require_default(obj) {
43
- return obj && obj.__esModule ? obj : {
44
- default: obj
45
- };
46
- }
47
36
  function _getRequireWildcardCache(nodeInterop) {
48
37
  if (typeof WeakMap !== "function") return null;
49
38
  var cacheBabelInterop = new WeakMap();
@@ -116,39 +105,18 @@ function _type_of(obj) {
116
105
  "@swc/helpers - typeof";
117
106
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
118
107
  }
119
- var pkg = JSON.parse(_fs.readFileSync(_path.join((0, _modulerootsync.default)(_url.fileURLToPath(require("url").pathToFileURL(__filename).toString())), 'package.json'), 'utf-8'));
120
- 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\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 --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();
121
- function handleVersionHelp(args) {
122
- var values = (0, _util.parseArgs)({
123
- args: args,
124
- options: {
125
- version: {
126
- type: 'boolean'
127
- },
128
- help: {
129
- type: 'boolean'
130
- }
131
- },
132
- strict: false
133
- }).values;
134
- if (values.version) return {
135
- handled: true,
136
- output: pkg.version
137
- };
138
- if (values.help) return {
139
- handled: true,
140
- output: HELP_TEXT
141
- };
142
- return {
143
- handled: false
144
- };
145
- }
108
+ var pkg = (0, _versionhelpts.readPkg)();
109
+ // @mcp-z/oauth-google and @mcp-z/server are requireable at the >=20 floor; deferred so
110
+ // --version/--help (handled via version-help.ts, never this file) load neither package.
111
+ var _require = typeof require === 'undefined' ? _module.Module.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
146
112
  function parseConfig(args, env) {
147
113
  var _ref, _ref1, _ref2;
148
- var transportConfig = (0, _server.parseConfig)(args, env);
149
- var oauthConfig = (0, _oauthgoogle.parseConfig)(args, env);
114
+ var oauthGoogle = _require('@mcp-z/oauth-google');
115
+ var mcpServer = _require('@mcp-z/server');
116
+ var transportConfig = mcpServer.parseConfig(args, env);
117
+ var oauthConfig = oauthGoogle.parseConfig(args, env);
150
118
  // Parse DCR configuration if DCR mode is enabled
151
- var dcrConfig = oauthConfig.auth === 'dcr' ? (0, _oauthgoogle.parseDcrConfig)(args, env, _constantsts.GOOGLE_SCOPE) : undefined;
119
+ var dcrConfig = oauthConfig.auth === 'dcr' ? oauthGoogle.parseDcrConfig(args, env, _constantsts.GOOGLE_SCOPE) : undefined;
152
120
  // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)
153
121
  var values = (0, _util.parseArgs)({
154
122
  args: args,
@@ -172,7 +140,7 @@ function parseConfig(args, env) {
172
140
  var repositoryUrl = (_ref = rawRepoUrl === null || rawRepoUrl === void 0 ? void 0 : rawRepoUrl.replace(/^git\+/, '').replace(/\.git$/, '')) !== null && _ref !== void 0 ? _ref : "https://github.com/mcp-z/".concat(name);
173
141
  var rootDir = (0, _os.homedir)();
174
142
  try {
175
- var configPath = (0, _server.findConfigPath)({
143
+ var configPath = mcpServer.findConfigPath({
176
144
  config: '.mcp.json',
177
145
  cwd: process.cwd(),
178
146
  stopDir: (0, _os.homedir)()
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/config.ts"],"sourcesContent":["import { parseDcrConfig, parseConfig as parseOAuthConfig } from '@mcp-z/oauth-google';\nimport { findConfigPath, parseConfig as parseTransportConfig } from '@mcp-z/server';\nimport * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\nimport { GOOGLE_SCOPE } from '../constants.ts';\nimport type { ServerConfig } from '../types.ts';\n\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\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 --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/**\n * Handle --version and --help flags before config parsing.\n * These should work without requiring any configuration.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values } = parseArgs({\n args,\n options: {\n version: { type: 'boolean' },\n help: { type: 'boolean' },\n },\n strict: false,\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\n/**\n * Parse Sheets server configuration from CLI arguments and environment.\n *\n * CLI Arguments (all optional):\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 *\n * Environment 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 *\n * OAuth Scopes (from constants.ts):\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 */\nexport function parseConfig(args: string[], env: Record<string, string | undefined>): ServerConfig {\n const transportConfig = parseTransportConfig(args, env);\n const oauthConfig = parseOAuthConfig(args, env);\n\n // Parse DCR configuration if DCR mode is enabled\n const dcrConfig = oauthConfig.auth === 'dcr' ? parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;\n\n // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)\n const { values } = parseArgs({\n args,\n options: {\n 'log-level': { type: 'string' },\n 'base-url': { type: 'string' },\n 'resource-store-uri': { type: 'string' },\n },\n strict: false, // Allow other arguments\n allowPositionals: true,\n });\n\n const name = pkg.name.replace(/^@[^/]+\\//, '');\n // Parse repository URL from package.json, stripping git+ prefix and .git suffix\n const rawRepoUrl = typeof pkg.repository === 'object' ? pkg.repository.url : pkg.repository;\n const repositoryUrl = rawRepoUrl?.replace(/^git\\+/, '').replace(/\\.git$/, '') ?? `https://github.com/mcp-z/${name}`;\n let rootDir = homedir();\n try {\n const configPath = findConfigPath({ config: '.mcp.json', cwd: process.cwd(), stopDir: homedir() });\n rootDir = path.dirname(configPath);\n } catch {\n rootDir = homedir();\n }\n const baseDir = path.join(rootDir, '.mcp-z');\n const cliLogLevel = typeof values['log-level'] === 'string' ? values['log-level'] : undefined;\n const envLogLevel = env.LOG_LEVEL;\n const logLevel = cliLogLevel ?? envLogLevel ?? 'info';\n\n // Parse storage configuration\n const cliResourceStoreUri = typeof values['resource-store-uri'] === 'string' ? values['resource-store-uri'] : undefined;\n const envResourceStoreUri = env.RESOURCE_STORE_URI;\n const defaultResourceStorePath = path.join(baseDir, name, 'files');\n const resourceStoreUri = normalizeResourceStoreUri(cliResourceStoreUri ?? envResourceStoreUri ?? defaultResourceStorePath);\n\n const cliBaseUrl = typeof values['base-url'] === 'string' ? values['base-url'] : undefined;\n const envBaseUrl = env.BASE_URL;\n const baseUrl = cliBaseUrl ?? envBaseUrl;\n\n // Combine configs\n return {\n ...oauthConfig, // Includes clientId, auth, headless, redirectUri\n transport: transportConfig.transport,\n logLevel,\n baseDir,\n name,\n version: pkg.version,\n repositoryUrl,\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n ...(dcrConfig && { dcrConfig }),\n };\n}\n\nfunction normalizeResourceStoreUri(resourceStoreUri: string): string {\n const filePrefix = 'file://';\n if (resourceStoreUri.startsWith(filePrefix)) {\n const rawPath = resourceStoreUri.slice(filePrefix.length);\n const expandedPath = rawPath.startsWith('~') ? rawPath.replace(/^~/, homedir()) : rawPath;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n }\n\n if (resourceStoreUri.includes('://')) return resourceStoreUri;\n\n const expandedPath = resourceStoreUri.startsWith('~') ? resourceStoreUri.replace(/^~/, homedir()) : resourceStoreUri;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n}\n\n/**\n * Build production configuration from process globals.\n * Entry point for production server.\n */\nexport function createConfig(): ServerConfig {\n return parseConfig(process.argv, process.env);\n}\n"],"names":["createConfig","handleVersionHelp","parseConfig","pkg","JSON","parse","fs","readFileSync","path","join","moduleRoot","url","fileURLToPath","HELP_TEXT","trim","args","values","parseArgs","options","version","type","help","strict","handled","output","env","cliLogLevel","cliResourceStoreUri","transportConfig","parseTransportConfig","oauthConfig","parseOAuthConfig","dcrConfig","auth","parseDcrConfig","GOOGLE_SCOPE","undefined","allowPositionals","name","replace","rawRepoUrl","repository","repositoryUrl","rootDir","homedir","configPath","findConfigPath","config","cwd","process","stopDir","dirname","baseDir","envLogLevel","LOG_LEVEL","logLevel","envResourceStoreUri","RESOURCE_STORE_URI","defaultResourceStorePath","resourceStoreUri","normalizeResourceStoreUri","cliBaseUrl","envBaseUrl","BASE_URL","baseUrl","transport","filePrefix","startsWith","rawPath","slice","length","expandedPath","resolve","includes","argv"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/config.ts"],"sourcesContent":["import type * as OAuthGoogle from '@mcp-z/oauth-google';\nimport type * as McpServer from '@mcp-z/server';\nimport { Module } from 'module';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport { parseArgs } from 'util';\nimport { GOOGLE_SCOPE } from '../constants.ts';\nimport type { ServerConfig } from '../types.ts';\nimport { readPkg } from './version-help.ts';\n\nconst pkg = readPkg();\n\n// @mcp-z/oauth-google and @mcp-z/server are requireable at the >=20 floor; deferred so\n// --version/--help (handled via version-help.ts, never this file) load neither package.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n/**\n * Parse Sheets server configuration from CLI arguments and environment.\n *\n * CLI Arguments (all optional):\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 *\n * Environment 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 *\n * OAuth Scopes (from constants.ts):\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 */\nexport function parseConfig(args: string[], env: Record<string, string | undefined>): ServerConfig {\n const oauthGoogle = _require('@mcp-z/oauth-google') as typeof OAuthGoogle;\n const mcpServer = _require('@mcp-z/server') as typeof McpServer;\n\n const transportConfig = mcpServer.parseConfig(args, env);\n const oauthConfig = oauthGoogle.parseConfig(args, env);\n\n // Parse DCR configuration if DCR mode is enabled\n const dcrConfig = oauthConfig.auth === 'dcr' ? oauthGoogle.parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;\n\n // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)\n const { values } = parseArgs({\n args,\n options: {\n 'log-level': { type: 'string' },\n 'base-url': { type: 'string' },\n 'resource-store-uri': { type: 'string' },\n },\n strict: false, // Allow other arguments\n allowPositionals: true,\n });\n\n const name = pkg.name.replace(/^@[^/]+\\//, '');\n // Parse repository URL from package.json, stripping git+ prefix and .git suffix\n const rawRepoUrl = typeof pkg.repository === 'object' ? pkg.repository.url : pkg.repository;\n const repositoryUrl = rawRepoUrl?.replace(/^git\\+/, '').replace(/\\.git$/, '') ?? `https://github.com/mcp-z/${name}`;\n let rootDir = homedir();\n try {\n const configPath = mcpServer.findConfigPath({ config: '.mcp.json', cwd: process.cwd(), stopDir: homedir() });\n rootDir = path.dirname(configPath);\n } catch {\n rootDir = homedir();\n }\n const baseDir = path.join(rootDir, '.mcp-z');\n const cliLogLevel = typeof values['log-level'] === 'string' ? values['log-level'] : undefined;\n const envLogLevel = env.LOG_LEVEL;\n const logLevel = cliLogLevel ?? envLogLevel ?? 'info';\n\n // Parse storage configuration\n const cliResourceStoreUri = typeof values['resource-store-uri'] === 'string' ? values['resource-store-uri'] : undefined;\n const envResourceStoreUri = env.RESOURCE_STORE_URI;\n const defaultResourceStorePath = path.join(baseDir, name, 'files');\n const resourceStoreUri = normalizeResourceStoreUri(cliResourceStoreUri ?? envResourceStoreUri ?? defaultResourceStorePath);\n\n const cliBaseUrl = typeof values['base-url'] === 'string' ? values['base-url'] : undefined;\n const envBaseUrl = env.BASE_URL;\n const baseUrl = cliBaseUrl ?? envBaseUrl;\n\n // Combine configs\n return {\n ...oauthConfig, // Includes clientId, auth, headless, redirectUri\n transport: transportConfig.transport,\n logLevel,\n baseDir,\n name,\n version: pkg.version,\n repositoryUrl,\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n ...(dcrConfig && { dcrConfig }),\n };\n}\n\nfunction normalizeResourceStoreUri(resourceStoreUri: string): string {\n const filePrefix = 'file://';\n if (resourceStoreUri.startsWith(filePrefix)) {\n const rawPath = resourceStoreUri.slice(filePrefix.length);\n const expandedPath = rawPath.startsWith('~') ? rawPath.replace(/^~/, homedir()) : rawPath;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n }\n\n if (resourceStoreUri.includes('://')) return resourceStoreUri;\n\n const expandedPath = resourceStoreUri.startsWith('~') ? resourceStoreUri.replace(/^~/, homedir()) : resourceStoreUri;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n}\n\n/**\n * Build production configuration from process globals.\n * Entry point for production server.\n */\nexport function createConfig(): ServerConfig {\n return parseConfig(process.argv, process.env);\n}\n"],"names":["createConfig","parseConfig","pkg","readPkg","_require","require","Module","createRequire","args","env","cliLogLevel","cliResourceStoreUri","oauthGoogle","mcpServer","transportConfig","oauthConfig","dcrConfig","auth","parseDcrConfig","GOOGLE_SCOPE","undefined","values","parseArgs","options","type","strict","allowPositionals","name","replace","rawRepoUrl","repository","url","repositoryUrl","rootDir","homedir","configPath","findConfigPath","config","cwd","process","stopDir","path","dirname","baseDir","join","envLogLevel","LOG_LEVEL","logLevel","envResourceStoreUri","RESOURCE_STORE_URI","defaultResourceStorePath","resourceStoreUri","normalizeResourceStoreUri","cliBaseUrl","envBaseUrl","BASE_URL","baseUrl","transport","version","filePrefix","startsWith","rawPath","slice","length","expandedPath","resolve","includes","argv"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Package metadata read from package.json, resolved relative to this file. */
2
+ export declare function readPkg(): {
3
+ name: string;
4
+ version: string;
5
+ repository?: string | {
6
+ url?: string;
7
+ };
8
+ };
9
+ /**
10
+ * Handle --version/--help flags and the `version` subcommand before config parsing.
11
+ * These must work without requiring any configuration or heavy dependency.
12
+ */
13
+ export declare function handleVersionHelp(args: string[]): {
14
+ handled: boolean;
15
+ output?: string;
16
+ };
@@ -0,0 +1,16 @@
1
+ /** Package metadata read from package.json, resolved relative to this file. */
2
+ export declare function readPkg(): {
3
+ name: string;
4
+ version: string;
5
+ repository?: string | {
6
+ url?: string;
7
+ };
8
+ };
9
+ /**
10
+ * Handle --version/--help flags and the `version` subcommand before config parsing.
11
+ * These must work without requiring any configuration or heavy dependency.
12
+ */
13
+ export declare function handleVersionHelp(args: string[]): {
14
+ handled: boolean;
15
+ output?: string;
16
+ };
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get handleVersionHelp () {
13
+ return handleVersionHelp;
14
+ },
15
+ get readPkg () {
16
+ return readPkg;
17
+ }
18
+ });
19
+ var _fs = /*#__PURE__*/ _interop_require_wildcard(require("fs"));
20
+ var _modulerootsync = /*#__PURE__*/ _interop_require_default(require("module-root-sync"));
21
+ var _path = /*#__PURE__*/ _interop_require_wildcard(require("path"));
22
+ var _url = /*#__PURE__*/ _interop_require_wildcard(require("url"));
23
+ var _util = require("util");
24
+ function _interop_require_default(obj) {
25
+ return obj && obj.__esModule ? obj : {
26
+ default: obj
27
+ };
28
+ }
29
+ function _getRequireWildcardCache(nodeInterop) {
30
+ if (typeof WeakMap !== "function") return null;
31
+ var cacheBabelInterop = new WeakMap();
32
+ var cacheNodeInterop = new WeakMap();
33
+ return (_getRequireWildcardCache = function(nodeInterop) {
34
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
35
+ })(nodeInterop);
36
+ }
37
+ function _interop_require_wildcard(obj, nodeInterop) {
38
+ if (!nodeInterop && obj && obj.__esModule) return obj;
39
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") return {
40
+ default: obj
41
+ };
42
+ var cache = _getRequireWildcardCache(nodeInterop);
43
+ if (cache && cache.has(obj)) return cache.get(obj);
44
+ var newObj = {
45
+ __proto__: null
46
+ };
47
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
48
+ for(var key in obj){
49
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
50
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
51
+ if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);
52
+ else newObj[key] = obj[key];
53
+ }
54
+ }
55
+ newObj.default = obj;
56
+ if (cache) cache.set(obj, newObj);
57
+ return newObj;
58
+ }
59
+ // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`
60
+ // resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and
61
+ // @mcp-z/server, which this path must not touch.
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();
64
+ function readPkg() {
65
+ return pkg;
66
+ }
67
+ function handleVersionHelp(args) {
68
+ var _parseArgs = (0, _util.parseArgs)({
69
+ args: args,
70
+ options: {
71
+ version: {
72
+ type: 'boolean'
73
+ },
74
+ help: {
75
+ type: 'boolean'
76
+ }
77
+ },
78
+ strict: false,
79
+ allowPositionals: true
80
+ }), values = _parseArgs.values, positionals = _parseArgs.positionals;
81
+ if (values.version || positionals[0] === 'version') return {
82
+ handled: true,
83
+ output: pkg.version
84
+ };
85
+ if (values.help) return {
86
+ handled: true,
87
+ output: HELP_TEXT
88
+ };
89
+ return {
90
+ handled: false
91
+ };
92
+ }
93
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +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"}
package/dist/esm/index.js CHANGED
@@ -1,6 +1,4 @@
1
- import { createConfig, handleVersionHelp } from './setup/config.js';
2
- import { createHTTPServer } from './setup/http.js';
3
- import { createStdioServer } from './setup/stdio.js';
1
+ import { handleVersionHelp } from './setup/version-help.js';
4
2
  export { GOOGLE_SCOPE } from './constants.js';
5
3
  import * as _mcp from './mcp/index.js';
6
4
  export { _mcp as mcp };
@@ -10,6 +8,10 @@ import * as _setup from './setup/index.js';
10
8
  export { _setup as setup };
11
9
  export * from './types.js';
12
10
  export async function startServer(config) {
11
+ // createHTTPServer/createStdioServer pull in @modelcontextprotocol/sdk and every mcp/tools/*.ts
12
+ // (googleapis included); deferred so a --version/--help run never reaches them.
13
+ const { createHTTPServer } = await import('./setup/http.js');
14
+ const { createStdioServer } = await import('./setup/stdio.js');
13
15
  const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);
14
16
  process.on('SIGINT', async ()=>{
15
17
  await close();
@@ -25,7 +27,9 @@ export default async function main() {
25
27
  console.log(versionHelpResult.output);
26
28
  process.exit(0);
27
29
  }
28
- // Only parse config if no help/version flags
30
+ // Only parse config if no help/version flags. config.ts's own heavy imports (@mcp-z/oauth-google,
31
+ // @mcp-z/server) are deferred internally, so this static-looking call stays cheap until here.
32
+ const { createConfig } = await import('./setup/config.js');
29
33
  const config = createConfig();
30
34
  await startServer(config);
31
35
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/index.ts"],"sourcesContent":["import { createConfig, handleVersionHelp } from './setup/config.ts';\nimport { createHTTPServer } from './setup/http.ts';\nimport { createStdioServer } from './setup/stdio.ts';\nimport type { ServerConfig } from './types.ts';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.ts';\nexport * as schemas from './schemas/index.ts';\nexport * as setup from './setup/index.ts';\nexport * from './types.ts';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["createConfig","handleVersionHelp","createHTTPServer","createStdioServer","GOOGLE_SCOPE","mcp","schemas","setup","startServer","config","logger","close","transport","type","process","on","exit","info","Promise","main","versionHelpResult","argv","handled","console","log","output","URL","url","pathname"],"mappings":"AAAA,SAASA,YAAY,EAAEC,iBAAiB,QAAQ,oBAAoB;AACpE,SAASC,gBAAgB,QAAQ,kBAAkB;AACnD,SAASC,iBAAiB,QAAQ,mBAAmB;AAGrD,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,sBAAqB,iBAAiB;AAAtC,SAAO,QAAKC,GAAG,GAAuB;AACtC,0BAAyB,qBAAqB;AAA9C,SAAO,YAAKC,OAAO,GAA2B;AAC9C,wBAAuB,mBAAmB;AAA1C,SAAO,UAAKC,KAAK,GAAyB;AAC1C,cAAc,aAAa;AAE3B,OAAO,eAAeC,YAAYC,MAAoB;IACpD,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAGF,OAAOG,SAAS,CAACC,IAAI,KAAK,UAAU,MAAMV,kBAAkBM,UAAU,MAAMP,iBAAiBO;IAEvHK,QAAQC,EAAE,CAAC,UAAU;QACnB,MAAMJ;QACNG,QAAQE,IAAI,CAAC;IACf;IAEAN,OAAOO,IAAI,CAAC,CAAC,oBAAoB,EAAER,OAAOG,SAAS,CAACC,IAAI,CAAC,UAAU,CAAC;IACpE,MAAM,IAAIK,QAAQ,KAAO;AAC3B;AAEA,eAAe,eAAeC;IAC5B,4DAA4D;IAC5D,MAAMC,oBAAoBnB,kBAAkBa,QAAQO,IAAI;IACxD,IAAID,kBAAkBE,OAAO,EAAE;QAC7BC,QAAQC,GAAG,CAACJ,kBAAkBK,MAAM;QACpCX,QAAQE,IAAI,CAAC;IACf;IAEA,6CAA6C;IAC7C,MAAMP,SAAST;IACf,MAAMQ,YAAYC;AACpB;AAEA,IAAIK,QAAQO,IAAI,CAAC,EAAE,KAAK,IAAIK,IAAI,YAAYC,GAAG,EAAEC,QAAQ,EAAE;IACzDT;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/index.ts"],"sourcesContent":["import { handleVersionHelp } from './setup/version-help.ts';\nimport type { ServerConfig } from './types.ts';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.ts';\nexport * as schemas from './schemas/index.ts';\nexport * as setup from './setup/index.ts';\nexport * from './types.ts';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n // createHTTPServer/createStdioServer pull in @modelcontextprotocol/sdk and every mcp/tools/*.ts\n // (googleapis included); deferred so a --version/--help run never reaches them.\n const { createHTTPServer } = await import('./setup/http.ts');\n const { createStdioServer } = await import('./setup/stdio.ts');\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags. config.ts's own heavy imports (@mcp-z/oauth-google,\n // @mcp-z/server) are deferred internally, so this static-looking call stays cheap until here.\n const { createConfig } = await import('./setup/config.ts');\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["handleVersionHelp","GOOGLE_SCOPE","mcp","schemas","setup","startServer","config","createHTTPServer","createStdioServer","logger","close","transport","type","process","on","exit","info","Promise","main","versionHelpResult","argv","handled","console","log","output","createConfig","URL","url","pathname"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,0BAA0B;AAG5D,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,sBAAqB,iBAAiB;AAAtC,SAAO,QAAKC,GAAG,GAAuB;AACtC,0BAAyB,qBAAqB;AAA9C,SAAO,YAAKC,OAAO,GAA2B;AAC9C,wBAAuB,mBAAmB;AAA1C,SAAO,UAAKC,KAAK,GAAyB;AAC1C,cAAc,aAAa;AAE3B,OAAO,eAAeC,YAAYC,MAAoB;IACpD,gGAAgG;IAChG,gFAAgF;IAChF,MAAM,EAAEC,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC;IAC1C,MAAM,EAAEC,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC;IAC3C,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAGJ,OAAOK,SAAS,CAACC,IAAI,KAAK,UAAU,MAAMJ,kBAAkBF,UAAU,MAAMC,iBAAiBD;IAEvHO,QAAQC,EAAE,CAAC,UAAU;QACnB,MAAMJ;QACNG,QAAQE,IAAI,CAAC;IACf;IAEAN,OAAOO,IAAI,CAAC,CAAC,oBAAoB,EAAEV,OAAOK,SAAS,CAACC,IAAI,CAAC,UAAU,CAAC;IACpE,MAAM,IAAIK,QAAQ,KAAO;AAC3B;AAEA,eAAe,eAAeC;IAC5B,4DAA4D;IAC5D,MAAMC,oBAAoBnB,kBAAkBa,QAAQO,IAAI;IACxD,IAAID,kBAAkBE,OAAO,EAAE;QAC7BC,QAAQC,GAAG,CAACJ,kBAAkBK,MAAM;QACpCX,QAAQE,IAAI,CAAC;IACf;IAEA,kGAAkG;IAClG,8FAA8F;IAC9F,MAAM,EAAEU,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC;IACtC,MAAMnB,SAASmB;IACf,MAAMpB,YAAYC;AACpB;AAEA,IAAIO,QAAQO,IAAI,CAAC,EAAE,KAAK,IAAIM,IAAI,YAAYC,GAAG,EAAEC,QAAQ,EAAE;IACzDV;AACF"}
@@ -1,12 +1,4 @@
1
1
  import type { ServerConfig } from '../types.js';
2
- /**
3
- * Handle --version and --help flags before config parsing.
4
- * These should work without requiring any configuration.
5
- */
6
- export declare function handleVersionHelp(args: string[]): {
7
- handled: boolean;
8
- output?: string;
9
- };
10
2
  /**
11
3
  * Parse Sheets server configuration from CLI arguments and environment.
12
4
  *
@@ -1,86 +1,13 @@
1
- import { parseDcrConfig, parseConfig as parseOAuthConfig } from '@mcp-z/oauth-google';
2
- import { findConfigPath, parseConfig as parseTransportConfig } from '@mcp-z/server';
3
- import * as fs from 'fs';
4
- import moduleRoot from 'module-root-sync';
1
+ import { Module } from 'module';
5
2
  import { homedir } from 'os';
6
3
  import * as path from 'path';
7
- import * as url from 'url';
8
4
  import { parseArgs } from 'util';
9
5
  import { GOOGLE_SCOPE } from '../constants.js';
10
- const pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));
11
- const HELP_TEXT = `
12
- Usage: mcp-sheets [options]
13
-
14
- MCP server for Google Sheets spreadsheet management with OAuth authentication.
15
-
16
- Options:
17
- --version Show version number
18
- --help Show this help message
19
- --auth=<mode> Authentication mode (default: loopback-oauth)
20
- Modes: loopback-oauth, service-account, dcr
21
- --headless Disable browser auto-open, return auth URL instead
22
- --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)
23
- --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)
24
- --dcr-verify-url=<url> External verification endpoint (required for external mode)
25
- --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)
26
- --port=<port> Enable HTTP transport on specified port
27
- --stdio Enable stdio transport (default if no port)
28
- --log-level=<level> Logging level (default: info)
29
- --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)
30
- --base-url=<url> Base URL for HTTP file serving (optional)
31
-
32
- Environment Variables:
33
- GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)
34
- GOOGLE_CLIENT_SECRET OAuth client secret (optional)
35
- AUTH_MODE Default authentication mode (optional)
36
- HEADLESS Disable browser auto-open (optional)
37
- DCR_MODE DCR mode (optional, same format as --dcr-mode)
38
- DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)
39
- DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)
40
- TOKEN_STORE_URI Token storage URI (optional)
41
- PORT Default HTTP port (optional)
42
- LOG_LEVEL Default logging level (optional)
43
- RESOURCE_STORE_URI Resource store URI (optional, file://)
44
- BASE_URL Base URL for HTTP file serving (optional)
45
-
46
- OAuth Scopes:
47
- 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
48
-
49
- Examples:
50
- mcp-sheets # Use default settings
51
- mcp-sheets --auth=service-account # Use service account auth
52
- mcp-sheets --port=3000 # HTTP transport on port 3000
53
- mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI
54
- GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var
55
- `.trim();
56
- /**
57
- * Handle --version and --help flags before config parsing.
58
- * These should work without requiring any configuration.
59
- */ export function handleVersionHelp(args) {
60
- const { values } = parseArgs({
61
- args,
62
- options: {
63
- version: {
64
- type: 'boolean'
65
- },
66
- help: {
67
- type: 'boolean'
68
- }
69
- },
70
- strict: false
71
- });
72
- if (values.version) return {
73
- handled: true,
74
- output: pkg.version
75
- };
76
- if (values.help) return {
77
- handled: true,
78
- output: HELP_TEXT
79
- };
80
- return {
81
- handled: false
82
- };
83
- }
6
+ import { readPkg } from './version-help.js';
7
+ const pkg = readPkg();
8
+ // @mcp-z/oauth-google and @mcp-z/server are requireable at the >=20 floor; deferred so
9
+ // --version/--help (handled via version-help.ts, never this file) load neither package.
10
+ const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
84
11
  /**
85
12
  * Parse Sheets server configuration from CLI arguments and environment.
86
13
  *
@@ -116,10 +43,12 @@ Examples:
116
43
  * 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
117
44
  */ export function parseConfig(args, env) {
118
45
  var _ref, _ref1, _ref2;
119
- const transportConfig = parseTransportConfig(args, env);
120
- const oauthConfig = parseOAuthConfig(args, env);
46
+ const oauthGoogle = _require('@mcp-z/oauth-google');
47
+ const mcpServer = _require('@mcp-z/server');
48
+ const transportConfig = mcpServer.parseConfig(args, env);
49
+ const oauthConfig = oauthGoogle.parseConfig(args, env);
121
50
  // Parse DCR configuration if DCR mode is enabled
122
- const dcrConfig = oauthConfig.auth === 'dcr' ? parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;
51
+ const dcrConfig = oauthConfig.auth === 'dcr' ? oauthGoogle.parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;
123
52
  // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)
124
53
  const { values } = parseArgs({
125
54
  args,
@@ -143,7 +72,7 @@ Examples:
143
72
  const repositoryUrl = (_ref = rawRepoUrl === null || rawRepoUrl === void 0 ? void 0 : rawRepoUrl.replace(/^git\+/, '').replace(/\.git$/, '')) !== null && _ref !== void 0 ? _ref : `https://github.com/mcp-z/${name}`;
144
73
  let rootDir = homedir();
145
74
  try {
146
- const configPath = findConfigPath({
75
+ const configPath = mcpServer.findConfigPath({
147
76
  config: '.mcp.json',
148
77
  cwd: process.cwd(),
149
78
  stopDir: homedir()
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/config.ts"],"sourcesContent":["import { parseDcrConfig, parseConfig as parseOAuthConfig } from '@mcp-z/oauth-google';\nimport { findConfigPath, parseConfig as parseTransportConfig } from '@mcp-z/server';\nimport * as fs from 'fs';\nimport moduleRoot from 'module-root-sync';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { parseArgs } from 'util';\nimport { GOOGLE_SCOPE } from '../constants.ts';\nimport type { ServerConfig } from '../types.ts';\n\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\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 --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/**\n * Handle --version and --help flags before config parsing.\n * These should work without requiring any configuration.\n */\nexport function handleVersionHelp(args: string[]): { handled: boolean; output?: string } {\n const { values } = parseArgs({\n args,\n options: {\n version: { type: 'boolean' },\n help: { type: 'boolean' },\n },\n strict: false,\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\n/**\n * Parse Sheets server configuration from CLI arguments and environment.\n *\n * CLI Arguments (all optional):\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 *\n * Environment 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 *\n * OAuth Scopes (from constants.ts):\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 */\nexport function parseConfig(args: string[], env: Record<string, string | undefined>): ServerConfig {\n const transportConfig = parseTransportConfig(args, env);\n const oauthConfig = parseOAuthConfig(args, env);\n\n // Parse DCR configuration if DCR mode is enabled\n const dcrConfig = oauthConfig.auth === 'dcr' ? parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;\n\n // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)\n const { values } = parseArgs({\n args,\n options: {\n 'log-level': { type: 'string' },\n 'base-url': { type: 'string' },\n 'resource-store-uri': { type: 'string' },\n },\n strict: false, // Allow other arguments\n allowPositionals: true,\n });\n\n const name = pkg.name.replace(/^@[^/]+\\//, '');\n // Parse repository URL from package.json, stripping git+ prefix and .git suffix\n const rawRepoUrl = typeof pkg.repository === 'object' ? pkg.repository.url : pkg.repository;\n const repositoryUrl = rawRepoUrl?.replace(/^git\\+/, '').replace(/\\.git$/, '') ?? `https://github.com/mcp-z/${name}`;\n let rootDir = homedir();\n try {\n const configPath = findConfigPath({ config: '.mcp.json', cwd: process.cwd(), stopDir: homedir() });\n rootDir = path.dirname(configPath);\n } catch {\n rootDir = homedir();\n }\n const baseDir = path.join(rootDir, '.mcp-z');\n const cliLogLevel = typeof values['log-level'] === 'string' ? values['log-level'] : undefined;\n const envLogLevel = env.LOG_LEVEL;\n const logLevel = cliLogLevel ?? envLogLevel ?? 'info';\n\n // Parse storage configuration\n const cliResourceStoreUri = typeof values['resource-store-uri'] === 'string' ? values['resource-store-uri'] : undefined;\n const envResourceStoreUri = env.RESOURCE_STORE_URI;\n const defaultResourceStorePath = path.join(baseDir, name, 'files');\n const resourceStoreUri = normalizeResourceStoreUri(cliResourceStoreUri ?? envResourceStoreUri ?? defaultResourceStorePath);\n\n const cliBaseUrl = typeof values['base-url'] === 'string' ? values['base-url'] : undefined;\n const envBaseUrl = env.BASE_URL;\n const baseUrl = cliBaseUrl ?? envBaseUrl;\n\n // Combine configs\n return {\n ...oauthConfig, // Includes clientId, auth, headless, redirectUri\n transport: transportConfig.transport,\n logLevel,\n baseDir,\n name,\n version: pkg.version,\n repositoryUrl,\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n ...(dcrConfig && { dcrConfig }),\n };\n}\n\nfunction normalizeResourceStoreUri(resourceStoreUri: string): string {\n const filePrefix = 'file://';\n if (resourceStoreUri.startsWith(filePrefix)) {\n const rawPath = resourceStoreUri.slice(filePrefix.length);\n const expandedPath = rawPath.startsWith('~') ? rawPath.replace(/^~/, homedir()) : rawPath;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n }\n\n if (resourceStoreUri.includes('://')) return resourceStoreUri;\n\n const expandedPath = resourceStoreUri.startsWith('~') ? resourceStoreUri.replace(/^~/, homedir()) : resourceStoreUri;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n}\n\n/**\n * Build production configuration from process globals.\n * Entry point for production server.\n */\nexport function createConfig(): ServerConfig {\n return parseConfig(process.argv, process.env);\n}\n"],"names":["parseDcrConfig","parseConfig","parseOAuthConfig","findConfigPath","parseTransportConfig","fs","moduleRoot","homedir","path","url","parseArgs","GOOGLE_SCOPE","pkg","JSON","parse","readFileSync","join","fileURLToPath","HELP_TEXT","trim","handleVersionHelp","args","values","options","version","type","help","strict","handled","output","env","cliLogLevel","cliResourceStoreUri","transportConfig","oauthConfig","dcrConfig","auth","undefined","allowPositionals","name","replace","rawRepoUrl","repository","repositoryUrl","rootDir","configPath","config","cwd","process","stopDir","dirname","baseDir","envLogLevel","LOG_LEVEL","logLevel","envResourceStoreUri","RESOURCE_STORE_URI","defaultResourceStorePath","resourceStoreUri","normalizeResourceStoreUri","cliBaseUrl","envBaseUrl","BASE_URL","baseUrl","transport","filePrefix","startsWith","rawPath","slice","length","expandedPath","resolve","includes","createConfig","argv"],"mappings":"AAAA,SAASA,cAAc,EAAEC,eAAeC,gBAAgB,QAAQ,sBAAsB;AACtF,SAASC,cAAc,EAAEF,eAAeG,oBAAoB,QAAQ,gBAAgB;AACpF,YAAYC,QAAQ,KAAK;AACzB,OAAOC,gBAAgB,mBAAmB;AAC1C,SAASC,OAAO,QAAQ,KAAK;AAC7B,YAAYC,UAAU,OAAO;AAC7B,YAAYC,SAAS,MAAM;AAC3B,SAASC,SAAS,QAAQ,OAAO;AACjC,SAASC,YAAY,QAAQ,kBAAkB;AAG/C,MAAMC,MAAMC,KAAKC,KAAK,CAACT,GAAGU,YAAY,CAACP,KAAKQ,IAAI,CAACV,WAAWG,IAAIQ,aAAa,CAAC,YAAYR,GAAG,IAAI,iBAAiB;AAElH,MAAMS,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CnB,CAAC,CAACC,IAAI;AAEN;;;CAGC,GACD,OAAO,SAASC,kBAAkBC,IAAc;IAC9C,MAAM,EAAEC,MAAM,EAAE,GAAGZ,UAAU;QAC3BW;QACAE,SAAS;YACPC,SAAS;gBAAEC,MAAM;YAAU;YAC3BC,MAAM;gBAAED,MAAM;YAAU;QAC1B;QACAE,QAAQ;IACV;IAEA,IAAIL,OAAOE,OAAO,EAAE,OAAO;QAAEI,SAAS;QAAMC,QAAQjB,IAAIY,OAAO;IAAC;IAChE,IAAIF,OAAOI,IAAI,EAAE,OAAO;QAAEE,SAAS;QAAMC,QAAQX;IAAU;IAC3D,OAAO;QAAEU,SAAS;IAAM;AAC1B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCC,GACD,OAAO,SAAS3B,YAAYoB,IAAc,EAAES,GAAuC;cAiChEC,OAMkCC;IAtCnD,MAAMC,kBAAkB7B,qBAAqBiB,MAAMS;IACnD,MAAMI,cAAchC,iBAAiBmB,MAAMS;IAE3C,iDAAiD;IACjD,MAAMK,YAAYD,YAAYE,IAAI,KAAK,QAAQpC,eAAeqB,MAAMS,KAAKnB,gBAAgB0B;IAEzF,2EAA2E;IAC3E,MAAM,EAAEf,MAAM,EAAE,GAAGZ,UAAU;QAC3BW;QACAE,SAAS;YACP,aAAa;gBAAEE,MAAM;YAAS;YAC9B,YAAY;gBAAEA,MAAM;YAAS;YAC7B,sBAAsB;gBAAEA,MAAM;YAAS;QACzC;QACAE,QAAQ;QACRW,kBAAkB;IACpB;IAEA,MAAMC,OAAO3B,IAAI2B,IAAI,CAACC,OAAO,CAAC,aAAa;IAC3C,gFAAgF;IAChF,MAAMC,aAAa,OAAO7B,IAAI8B,UAAU,KAAK,WAAW9B,IAAI8B,UAAU,CAACjC,GAAG,GAAGG,IAAI8B,UAAU;IAC3F,MAAMC,wBAAgBF,uBAAAA,iCAAAA,WAAYD,OAAO,CAAC,UAAU,IAAIA,OAAO,CAAC,UAAU,0CAAO,CAAC,yBAAyB,EAAED,MAAM;IACnH,IAAIK,UAAUrC;IACd,IAAI;QACF,MAAMsC,aAAa1C,eAAe;YAAE2C,QAAQ;YAAaC,KAAKC,QAAQD,GAAG;YAAIE,SAAS1C;QAAU;QAChGqC,UAAUpC,KAAK0C,OAAO,CAACL;IACzB,EAAE,OAAM;QACND,UAAUrC;IACZ;IACA,MAAM4C,UAAU3C,KAAKQ,IAAI,CAAC4B,SAAS;IACnC,MAAMb,cAAc,OAAOT,MAAM,CAAC,YAAY,KAAK,WAAWA,MAAM,CAAC,YAAY,GAAGe;IACpF,MAAMe,cAActB,IAAIuB,SAAS;IACjC,MAAMC,YAAWvB,QAAAA,wBAAAA,yBAAAA,cAAeqB,yBAAfrB,mBAAAA,QAA8B;IAE/C,8BAA8B;IAC9B,MAAMC,sBAAsB,OAAOV,MAAM,CAAC,qBAAqB,KAAK,WAAWA,MAAM,CAAC,qBAAqB,GAAGe;IAC9G,MAAMkB,sBAAsBzB,IAAI0B,kBAAkB;IAClD,MAAMC,2BAA2BjD,KAAKQ,IAAI,CAACmC,SAASZ,MAAM;IAC1D,MAAMmB,mBAAmBC,2BAA0B3B,QAAAA,gCAAAA,iCAAAA,sBAAuBuB,iCAAvBvB,mBAAAA,QAA8CyB;IAEjG,MAAMG,aAAa,OAAOtC,MAAM,CAAC,WAAW,KAAK,WAAWA,MAAM,CAAC,WAAW,GAAGe;IACjF,MAAMwB,aAAa/B,IAAIgC,QAAQ;IAC/B,MAAMC,UAAUH,uBAAAA,wBAAAA,aAAcC;IAE9B,kBAAkB;IAClB,OAAO;QACL,GAAG3B,WAAW;QACd8B,WAAW/B,gBAAgB+B,SAAS;QACpCV;QACAH;QACAZ;QACAf,SAASZ,IAAIY,OAAO;QACpBmB;QACAe;QACA,GAAIK,WAAW;YAAEA;QAAQ,CAAC;QAC1B,GAAI5B,aAAa;YAAEA;QAAU,CAAC;IAChC;AACF;AAEA,SAASwB,0BAA0BD,gBAAwB;IACzD,MAAMO,aAAa;IACnB,IAAIP,iBAAiBQ,UAAU,CAACD,aAAa;QAC3C,MAAME,UAAUT,iBAAiBU,KAAK,CAACH,WAAWI,MAAM;QACxD,MAAMC,eAAeH,QAAQD,UAAU,CAAC,OAAOC,QAAQ3B,OAAO,CAAC,MAAMjC,aAAa4D;QAClF,OAAO,GAAGF,aAAazD,KAAK+D,OAAO,CAACD,eAAe;IACrD;IAEA,IAAIZ,iBAAiBc,QAAQ,CAAC,QAAQ,OAAOd;IAE7C,MAAMY,eAAeZ,iBAAiBQ,UAAU,CAAC,OAAOR,iBAAiBlB,OAAO,CAAC,MAAMjC,aAAamD;IACpG,OAAO,GAAGO,aAAazD,KAAK+D,OAAO,CAACD,eAAe;AACrD;AAEA;;;CAGC,GACD,OAAO,SAASG;IACd,OAAOxE,YAAY+C,QAAQ0B,IAAI,EAAE1B,QAAQlB,GAAG;AAC9C"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-sheets/src/setup/config.ts"],"sourcesContent":["import type * as OAuthGoogle from '@mcp-z/oauth-google';\nimport type * as McpServer from '@mcp-z/server';\nimport { Module } from 'module';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport { parseArgs } from 'util';\nimport { GOOGLE_SCOPE } from '../constants.ts';\nimport type { ServerConfig } from '../types.ts';\nimport { readPkg } from './version-help.ts';\n\nconst pkg = readPkg();\n\n// @mcp-z/oauth-google and @mcp-z/server are requireable at the >=20 floor; deferred so\n// --version/--help (handled via version-help.ts, never this file) load neither package.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n/**\n * Parse Sheets server configuration from CLI arguments and environment.\n *\n * CLI Arguments (all optional):\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 *\n * Environment 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 *\n * OAuth Scopes (from constants.ts):\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 */\nexport function parseConfig(args: string[], env: Record<string, string | undefined>): ServerConfig {\n const oauthGoogle = _require('@mcp-z/oauth-google') as typeof OAuthGoogle;\n const mcpServer = _require('@mcp-z/server') as typeof McpServer;\n\n const transportConfig = mcpServer.parseConfig(args, env);\n const oauthConfig = oauthGoogle.parseConfig(args, env);\n\n // Parse DCR configuration if DCR mode is enabled\n const dcrConfig = oauthConfig.auth === 'dcr' ? oauthGoogle.parseDcrConfig(args, env, GOOGLE_SCOPE) : undefined;\n\n // Parse application-level config (LOG_LEVEL, RESOURCE_STORE_URI, BASE_URL)\n const { values } = parseArgs({\n args,\n options: {\n 'log-level': { type: 'string' },\n 'base-url': { type: 'string' },\n 'resource-store-uri': { type: 'string' },\n },\n strict: false, // Allow other arguments\n allowPositionals: true,\n });\n\n const name = pkg.name.replace(/^@[^/]+\\//, '');\n // Parse repository URL from package.json, stripping git+ prefix and .git suffix\n const rawRepoUrl = typeof pkg.repository === 'object' ? pkg.repository.url : pkg.repository;\n const repositoryUrl = rawRepoUrl?.replace(/^git\\+/, '').replace(/\\.git$/, '') ?? `https://github.com/mcp-z/${name}`;\n let rootDir = homedir();\n try {\n const configPath = mcpServer.findConfigPath({ config: '.mcp.json', cwd: process.cwd(), stopDir: homedir() });\n rootDir = path.dirname(configPath);\n } catch {\n rootDir = homedir();\n }\n const baseDir = path.join(rootDir, '.mcp-z');\n const cliLogLevel = typeof values['log-level'] === 'string' ? values['log-level'] : undefined;\n const envLogLevel = env.LOG_LEVEL;\n const logLevel = cliLogLevel ?? envLogLevel ?? 'info';\n\n // Parse storage configuration\n const cliResourceStoreUri = typeof values['resource-store-uri'] === 'string' ? values['resource-store-uri'] : undefined;\n const envResourceStoreUri = env.RESOURCE_STORE_URI;\n const defaultResourceStorePath = path.join(baseDir, name, 'files');\n const resourceStoreUri = normalizeResourceStoreUri(cliResourceStoreUri ?? envResourceStoreUri ?? defaultResourceStorePath);\n\n const cliBaseUrl = typeof values['base-url'] === 'string' ? values['base-url'] : undefined;\n const envBaseUrl = env.BASE_URL;\n const baseUrl = cliBaseUrl ?? envBaseUrl;\n\n // Combine configs\n return {\n ...oauthConfig, // Includes clientId, auth, headless, redirectUri\n transport: transportConfig.transport,\n logLevel,\n baseDir,\n name,\n version: pkg.version,\n repositoryUrl,\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n ...(dcrConfig && { dcrConfig }),\n };\n}\n\nfunction normalizeResourceStoreUri(resourceStoreUri: string): string {\n const filePrefix = 'file://';\n if (resourceStoreUri.startsWith(filePrefix)) {\n const rawPath = resourceStoreUri.slice(filePrefix.length);\n const expandedPath = rawPath.startsWith('~') ? rawPath.replace(/^~/, homedir()) : rawPath;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n }\n\n if (resourceStoreUri.includes('://')) return resourceStoreUri;\n\n const expandedPath = resourceStoreUri.startsWith('~') ? resourceStoreUri.replace(/^~/, homedir()) : resourceStoreUri;\n return `${filePrefix}${path.resolve(expandedPath)}`;\n}\n\n/**\n * Build production configuration from process globals.\n * Entry point for production server.\n */\nexport function createConfig(): ServerConfig {\n return parseConfig(process.argv, process.env);\n}\n"],"names":["Module","homedir","path","parseArgs","GOOGLE_SCOPE","readPkg","pkg","_require","require","createRequire","url","parseConfig","args","env","cliLogLevel","cliResourceStoreUri","oauthGoogle","mcpServer","transportConfig","oauthConfig","dcrConfig","auth","parseDcrConfig","undefined","values","options","type","strict","allowPositionals","name","replace","rawRepoUrl","repository","repositoryUrl","rootDir","configPath","findConfigPath","config","cwd","process","stopDir","dirname","baseDir","join","envLogLevel","LOG_LEVEL","logLevel","envResourceStoreUri","RESOURCE_STORE_URI","defaultResourceStorePath","resourceStoreUri","normalizeResourceStoreUri","cliBaseUrl","envBaseUrl","BASE_URL","baseUrl","transport","version","filePrefix","startsWith","rawPath","slice","length","expandedPath","resolve","includes","createConfig","argv"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Package metadata read from package.json, resolved relative to this file. */
2
+ export declare function readPkg(): {
3
+ name: string;
4
+ version: string;
5
+ repository?: string | {
6
+ url?: string;
7
+ };
8
+ };
9
+ /**
10
+ * Handle --version/--help flags and the `version` subcommand before config parsing.
11
+ * These must work without requiring any configuration or heavy dependency.
12
+ */
13
+ export declare function handleVersionHelp(args: string[]): {
14
+ handled: boolean;
15
+ output?: string;
16
+ };
@@ -0,0 +1,90 @@
1
+ import * as fs from 'fs';
2
+ import moduleRoot from 'module-root-sync';
3
+ import * as path from 'path';
4
+ import * as url from 'url';
5
+ import { parseArgs } from 'util';
6
+ // Kept dependency-free (fs/path/url/module-root-sync only) so `--version`/`--help`/`version`
7
+ // resolve nothing beyond Node startup: config.ts's parseConfig pulls in @mcp-z/oauth-google and
8
+ // @mcp-z/server, which this path must not touch.
9
+ const pkg = JSON.parse(fs.readFileSync(path.join(moduleRoot(url.fileURLToPath(import.meta.url)), 'package.json'), 'utf-8'));
10
+ const HELP_TEXT = `
11
+ Usage: mcp-sheets [options]
12
+
13
+ MCP server for Google Sheets spreadsheet management with OAuth authentication.
14
+
15
+ Options:
16
+ --version Show version number
17
+ --help Show this help message
18
+ --auth=<mode> Authentication mode (default: loopback-oauth)
19
+ Modes: loopback-oauth, service-account, dcr
20
+ --headless Disable browser auto-open, return auth URL instead
21
+ --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)
22
+ --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)
23
+ --dcr-verify-url=<url> External verification endpoint (required for external mode)
24
+ --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)
25
+ --port=<port> Enable HTTP transport on specified port
26
+ --stdio Enable stdio transport (default if no port)
27
+ --log-level=<level> Logging level (default: info)
28
+ --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-sheets/files)
29
+ --base-url=<url> Base URL for HTTP file serving (optional)
30
+
31
+ Commands:
32
+ version Show version number
33
+
34
+ Environment Variables:
35
+ GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)
36
+ GOOGLE_CLIENT_SECRET OAuth client secret (optional)
37
+ AUTH_MODE Default authentication mode (optional)
38
+ HEADLESS Disable browser auto-open (optional)
39
+ DCR_MODE DCR mode (optional, same format as --dcr-mode)
40
+ DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)
41
+ DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)
42
+ TOKEN_STORE_URI Token storage URI (optional)
43
+ PORT Default HTTP port (optional)
44
+ LOG_LEVEL Default logging level (optional)
45
+ RESOURCE_STORE_URI Resource store URI (optional, file://)
46
+ BASE_URL Base URL for HTTP file serving (optional)
47
+
48
+ OAuth Scopes:
49
+ 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
+
51
+ Examples:
52
+ mcp-sheets # Use default settings
53
+ mcp-sheets version # Print version number
54
+ mcp-sheets --auth=service-account # Use service account auth
55
+ mcp-sheets --port=3000 # HTTP transport on port 3000
56
+ mcp-sheets --resource-store-uri=file:///tmp/sheets # Custom resource store URI
57
+ GOOGLE_CLIENT_ID=xxx mcp-sheets # Set client ID via env var
58
+ `.trim();
59
+ /** Package metadata read from package.json, resolved relative to this file. */ export function readPkg() {
60
+ return pkg;
61
+ }
62
+ /**
63
+ * Handle --version/--help flags and the `version` subcommand before config parsing.
64
+ * These must work without requiring any configuration or heavy dependency.
65
+ */ export function handleVersionHelp(args) {
66
+ const { values, positionals } = parseArgs({
67
+ args,
68
+ options: {
69
+ version: {
70
+ type: 'boolean'
71
+ },
72
+ help: {
73
+ type: 'boolean'
74
+ }
75
+ },
76
+ strict: false,
77
+ allowPositionals: true
78
+ });
79
+ if (values.version || positionals[0] === 'version') return {
80
+ handled: true,
81
+ output: pkg.version
82
+ };
83
+ if (values.help) return {
84
+ handled: true,
85
+ output: HELP_TEXT
86
+ };
87
+ return {
88
+ handled: false
89
+ };
90
+ }
@@ -0,0 +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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-z/mcp-sheets",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
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": {