powerautomate-mcp 0.7.4 → 0.7.5

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
@@ -20,13 +20,16 @@ An MCP (Model Context Protocol) server that connects Claude to Microsoft Power A
20
20
  - Microsoft 365 work account with Power Automate access
21
21
  - **Linux only**: libsecret for secure token storage
22
22
  ```bash
23
- # Ubuntu/Debian
24
- sudo apt-get install libsecret-1-dev gnome-keyring
23
+ # Ubuntu/Debian runtime
24
+ sudo apt-get install libsecret-1-0 gnome-keyring
25
25
 
26
- # Fedora/RHEL
27
- sudo dnf install libsecret-devel gnome-keyring
26
+ # Fedora/RHEL runtime
27
+ sudo dnf install libsecret gnome-keyring
28
28
  ```
29
29
 
30
+ If setup fails with `libsecret-1.so.0: cannot open shared object file`, the
31
+ runtime package above is missing.
32
+
30
33
  ### Installation
31
34
 
32
35
  ```bash
@@ -215,7 +218,7 @@ npm run build
215
218
 
216
219
  This server implements defense-in-depth security:
217
220
 
218
- - **Secure Token Storage**: DPAPI (Windows), Keychain (macOS), libsecret (Linux) no plaintext fallback
221
+ - **Secure Token Storage**: DPAPI (Windows), Keychain (macOS), libsecret on Linux when available, with a 0o600 file-cache fallback when it is not
219
222
  - **Input Validation**: GUID validation on all IDs, OData injection protection (ASCII-only), path traversal blocking (including URL-encoded), SharePoint hostname allowlist
220
223
  - **SSRF Prevention**: Domain allowlists on Dataverse URLs, resource links, and token resources
221
224
  - **Injection Prevention**: Power Automate expression injection blocking (`@{`/`}@`), OData filter sanitization, command injection prevention (`execFile` over `exec`)
package/dist/index.js CHANGED
@@ -13,7 +13,6 @@ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/
13
13
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourceTemplatesRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
14
14
  import { PublicClientApplication, LogLevel } from '@azure/msal-node';
15
15
  import { execFile } from 'child_process';
16
- import { PersistenceCreator, DataProtectionScope, PersistenceCachePlugin } from '@azure/msal-node-extensions';
17
16
  import { request } from 'undici';
18
17
  import Database from 'better-sqlite3';
19
18
  import { fileURLToPath } from 'url';
@@ -725,6 +724,23 @@ function validateEnvironmentId(envId) {
725
724
  }
726
725
  return envId;
727
726
  }
727
+ var msalNodeExtensionsPromise = null;
728
+ async function loadMsalNodeExtensions() {
729
+ if (!msalNodeExtensionsPromise) {
730
+ msalNodeExtensionsPromise = import('@azure/msal-node-extensions').then((mod) => {
731
+ const moduleWithOptionalDefault = mod;
732
+ const resolved = moduleWithOptionalDefault.default ?? moduleWithOptionalDefault;
733
+ if (!resolved || !("PersistenceCreator" in resolved)) {
734
+ throw new Error("msal-node-extensions did not expose the expected exports");
735
+ }
736
+ return resolved;
737
+ });
738
+ }
739
+ return msalNodeExtensionsPromise;
740
+ }
741
+ function formatError(error) {
742
+ return error instanceof Error ? error.message : String(error);
743
+ }
728
744
  var NativeFileCachePlugin = class {
729
745
  cachePath;
730
746
  constructor(cachePath) {
@@ -765,6 +781,11 @@ async function createPersistentCachePlugin(cachePath) {
765
781
  logger.debug({ cacheLocation, platform: platform }, "Creating persistent token cache");
766
782
  if (platform === "win32" || platform === "darwin") {
767
783
  try {
784
+ const {
785
+ DataProtectionScope,
786
+ PersistenceCreator,
787
+ PersistenceCachePlugin
788
+ } = await loadMsalNodeExtensions();
768
789
  const persistence = await PersistenceCreator.createPersistence({
769
790
  cachePath: cacheLocation,
770
791
  dataProtectionScope: platform === "win32" ? DataProtectionScope.CurrentUser : void 0,
@@ -777,11 +798,15 @@ async function createPersistentCachePlugin(cachePath) {
777
798
  } catch (err) {
778
799
  logger.error({ err, cacheLocation }, "Failed to create persistent cache");
779
800
  throw new Error(
780
- `Failed to initialize token cache at ${cacheLocation}: ${err instanceof Error ? err.message : String(err)}`
801
+ `Failed to initialize token cache at ${cacheLocation}: ${formatError(err)}`
781
802
  );
782
803
  }
783
804
  }
784
805
  try {
806
+ const {
807
+ PersistenceCreator,
808
+ PersistenceCachePlugin
809
+ } = await loadMsalNodeExtensions();
785
810
  const persistence = await PersistenceCreator.createPersistence({
786
811
  cachePath: cacheLocation,
787
812
  serviceName: "powerautomate-mcp",
@@ -793,7 +818,7 @@ async function createPersistentCachePlugin(cachePath) {
793
818
  return new PersistenceCachePlugin(persistence);
794
819
  } catch (libsecretError) {
795
820
  logger.warn(
796
- { err: libsecretError instanceof Error ? libsecretError.message : String(libsecretError) },
821
+ { err: formatError(libsecretError) },
797
822
  "libsecret unavailable \u2014 using native file cache fallback (0o600 permissions)"
798
823
  );
799
824
  logger.info({ cacheLocation }, "Persistent token cache initialized (native file)");
@@ -15134,6 +15159,7 @@ var c = {
15134
15159
  var icons = {
15135
15160
  check: `${c.green}\u2713${c.reset}`,
15136
15161
  cross: `${c.red}\u2717${c.reset}`,
15162
+ info: `${c.blue}i${c.reset}`,
15137
15163
  arrow: `${c.cyan}\u2192${c.reset}`,
15138
15164
  bullet: `${c.dim}\u2022${c.reset}`,
15139
15165
  star: `${c.yellow}\u2605${c.reset}`