@mcp-z/mcp-outlook 1.1.0 → 1.1.2

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
@@ -1,7 +1,6 @@
1
1
  # @mcp-z/mcp-outlook
2
2
 
3
- Docs: https://mcp-z.github.io/mcp-outlook
4
- Outlook MCP server for searching, reading, and sending Microsoft 365 mail.
3
+ Docs: https://mcp-z.github.io/mcp-outlook Outlook MCP server for searching, reading, and sending Microsoft 365 mail.
5
4
 
6
5
  ## Common uses
7
6
 
@@ -106,8 +105,7 @@ Example (http) - Create .mcp.json:
106
105
  }
107
106
  ```
108
107
 
109
- Local (default): omit REDIRECT_URI → ephemeral loopback.
110
- Cloud: set REDIRECT_URI to your public /oauth/callback and expose the service publicly.
108
+ Local (default): omit REDIRECT_URI → ephemeral loopback. Cloud: set REDIRECT_URI to your public /oauth/callback and expose the service publicly.
111
109
 
112
110
  Note: start block is a helper in "npx @mcp-z/cli up" for starting an http server from your .mpc.json. See [@mcp-z/cli](https://github.com/mcp-z/cli) for details.
113
111
 
@@ -132,8 +130,7 @@ Useful for headless or remote environments.
132
130
 
133
131
  ### DCR (self-hosted)
134
132
 
135
- HTTP only. Requires a public base URL.
136
- CSV export and `/files` are disabled in DCR mode; `resourceStoreUri` is ignored.
133
+ HTTP only. Requires a public base URL. CSV export and `/files` are disabled in DCR mode; `resourceStoreUri` is ignored.
137
134
 
138
135
  ```json
139
136
  {
@@ -193,3 +190,19 @@ mcp-z call outlook message-search '{"query":"from:alice@example.com"}'
193
190
  ## Configuration reference
194
191
 
195
192
  See `server.json` for all supported environment variables, CLI arguments, and defaults.
193
+
194
+ ## Storage backends
195
+
196
+ OAuth tokens (`TOKEN_STORE_URI`) and DCR registrations (`DCR_STORE_URI`) are stored through [keyv-registry](https://www.npmjs.com/package/keyv-registry), which picks an adapter from the URI protocol.
197
+
198
+ `file://` (the default, under `~/.mcp-z/`) and `memory://` work with no extra setup.
199
+
200
+ Any other backend needs its adapter installed alongside this server. Adapters are resolved with `require()`, so a globally installed server finds a globally installed adapter:
201
+
202
+ ```bash
203
+ npm install -g @mcp-z/mcp-outlook @keyv/redis
204
+
205
+ TOKEN_STORE_URI=redis://localhost:6379 mcp-outlook
206
+ ```
207
+
208
+ 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-outlook/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-outlook/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-microsoft
61
61
  // and @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-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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 profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook version # Print version number\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # Set client ID via env var\n".trim();
63
+ var HELP_TEXT = "\nUsage: mcp-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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-outlook\n\nOAuth Scopes:\n openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # 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-outlook/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-microsoft\n// and @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-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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 profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook version # Print version number\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # 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":";;;;;;;;;;;QAyEgBA;eAAAA;;QARAC;eAAAA;;;0DAjEI;qEACG;4DACD;2DACD;oBACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE1B,6FAA6F;AAC7F,+FAA+F;AAC/F,qDAAqD;AACrD,IAAMC,MAAMC,KAAKC,KAAK,CAACC,IAAGC,YAAY,CAACC,MAAKC,IAAI,CAACC,IAAAA,uBAAU,EAACC,KAAIC,aAAa,CAAC,uDAAmB,iBAAiB;AAElH,IAAMC,YAAY,g1FAmDhBC,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-outlook/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-microsoft\n// and @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-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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-outlook\n\nOAuth Scopes:\n openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # 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":";;;;;;;;;;;QA4EgBA;eAAAA;;QARAC;eAAAA;;;0DApEI;qEACG;4DACD;2DACD;oBACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE1B,mFAAmF;AACnF,+FAA+F;AAC/F,qDAAqD;AACrD,IAAMC,MAAMC,KAAKC,KAAK,CAACC,IAAGC,YAAY,CAACC,MAAKC,IAAI,CAACC,IAAAA,uBAAU,EAACC,KAAIC,aAAa,CAAC,uDAAmB,iBAAiB;AAElH,IAAMC,YAAY,8gGAsDhBC,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-outlook/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-outlook/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-microsoft
8
8
  // and @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'));
@@ -29,9 +29,6 @@ Options:
29
29
  --resource-store-uri=<uri> Resource store URI for CSV file storage (default: file://~/.mcp-z/mcp-outlook/files)
30
30
  --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)
31
31
 
32
- Commands:
33
- version Show version number
34
-
35
32
  Environment Variables:
36
33
  MS_CLIENT_ID OAuth client ID (REQUIRED)
37
34
  MS_TENANT_ID Microsoft tenant ID (REQUIRED)
@@ -47,12 +44,18 @@ Environment Variables:
47
44
  RESOURCE_STORE_URI Resource store URI (optional, file://)
48
45
  BASE_URL Base URL for HTTP file serving (optional)
49
46
 
47
+ Storage Backends:
48
+ TOKEN_STORE_URI and DCR_STORE_URI accept any keyv-registry protocol.
49
+ file:// (the default) and memory:// work out of the box. Any other backend
50
+ needs its adapter installed alongside this server:
51
+ npm install -g @keyv/redis
52
+ TOKEN_STORE_URI=redis://localhost:6379 mcp-outlook
53
+
50
54
  OAuth Scopes:
51
55
  openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite
52
56
 
53
57
  Examples:
54
58
  mcp-outlook # Use default settings
55
- mcp-outlook version # Print version number
56
59
  mcp-outlook --auth=device-code # Use device code auth
57
60
  mcp-outlook --port=3000 # HTTP transport on port 3000
58
61
  mcp-outlook --tenant-id=xxx # Set tenant ID
@@ -63,23 +66,25 @@ Examples:
63
66
  return pkg;
64
67
  }
65
68
  /**
66
- * Handle --version/--help flags and the `version` subcommand before config parsing.
69
+ * Handle --version/--help flags before config parsing.
67
70
  * These must work without requiring any configuration or heavy dependency.
68
71
  */ export function handleVersionHelp(args) {
69
- const { values, positionals } = parseArgs({
72
+ const { values } = parseArgs({
70
73
  args,
71
74
  options: {
72
75
  version: {
73
- type: 'boolean'
76
+ type: 'boolean',
77
+ short: 'v'
74
78
  },
75
79
  help: {
76
- type: 'boolean'
80
+ type: 'boolean',
81
+ short: 'h'
77
82
  }
78
83
  },
79
84
  strict: false,
80
85
  allowPositionals: true
81
86
  });
82
- if (values.version || positionals[0] === 'version') return {
87
+ if (values.version) return {
83
88
  handled: true,
84
89
  output: pkg.version
85
90
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/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-microsoft\n// and @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-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nCommands:\n version Show version number\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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 profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook version # Print version number\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # 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,+FAA+F;AAC/F,qDAAqD;AACrD,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,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-outlook/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-microsoft\n// and @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-outlook [options]\n\nMCP server for Outlook/Microsoft email 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, device-code, dcr\n --headless Disable browser auto-open, return auth URL instead\n --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)\n --tenant-id=<id> Microsoft tenant ID (overrides MS_TENANT_ID env var)\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-outlook/files)\n --base-url=<url> Base URL for HTTP file serving (default: http://localhost for HTTP transports)\n\nEnvironment Variables:\n MS_CLIENT_ID OAuth client ID (REQUIRED)\n MS_TENANT_ID Microsoft tenant ID (REQUIRED)\n MS_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-outlook\n\nOAuth Scopes:\n openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite\n\nExamples:\n mcp-outlook # Use default settings\n mcp-outlook --auth=device-code # Use device code auth\n mcp-outlook --port=3000 # HTTP transport on port 3000\n mcp-outlook --tenant-id=xxx # Set tenant ID\n mcp-outlook --resource-store-uri=file:///tmp/emails # Custom resource store URI\n MS_CLIENT_ID=xxx mcp-outlook # 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,+FAA+F;AAC/F,qDAAqD;AACrD,MAAMC,MAAMC,KAAKC,KAAK,CAACP,GAAGQ,YAAY,CAACN,KAAKO,IAAI,CAACR,WAAWE,IAAIO,aAAa,CAAC,YAAYP,GAAG,IAAI,iBAAiB;AAElH,MAAMQ,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDnB,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-outlook",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "MCP server for Outlook integration with OAuth authentication, message search, and batch operations",
5
5
  "keywords": [
6
6
  "outlook",
@@ -78,7 +78,8 @@
78
78
  "cors": "^2.0.0",
79
79
  "csv-stringify": "^6.0.0",
80
80
  "express": "^5.0.0",
81
- "keyv-registry": "^1.0.0",
81
+ "keyv-file": "5.3.3",
82
+ "keyv-registry": "^2.0.0",
82
83
  "module-root-sync": "^2.0.0",
83
84
  "pino": "^10.0.0",
84
85
  "zod": "^4.0.0"
@@ -90,6 +91,7 @@
90
91
  "@types/mocha": "^10.0.10",
91
92
  "@types/node": "^26.2.0",
92
93
  "dotenv": "^17.2.3",
94
+ "fs-remove-compat": "^1.0.4",
93
95
  "get-port": "5.1.1",
94
96
  "keyv": "^5.0.0",
95
97
  "node-version-use": "^2.4.7",