@cloudinary/environment-config-mcp 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +3 -2
  2. package/bin/mcp-server.js +45394 -44720
  3. package/bin/mcp-server.js.map +53 -238
  4. package/esm/landing-page.d.ts +2 -1
  5. package/esm/landing-page.d.ts.map +1 -1
  6. package/esm/landing-page.js +51 -28
  7. package/esm/landing-page.js.map +1 -1
  8. package/esm/lib/config.d.ts +3 -3
  9. package/esm/lib/config.js +3 -3
  10. package/esm/mcp-server/cli/serve/impl.js +51 -25
  11. package/esm/mcp-server/cli/serve/impl.js.map +1 -1
  12. package/esm/mcp-server/cli/start/impl.js +11 -8
  13. package/esm/mcp-server/cli/start/impl.js.map +1 -1
  14. package/esm/mcp-server/extensions.d.ts +3 -3
  15. package/esm/mcp-server/extensions.d.ts.map +1 -1
  16. package/esm/mcp-server/mcp-server.js +1 -1
  17. package/esm/mcp-server/prompts.d.ts +7 -8
  18. package/esm/mcp-server/prompts.d.ts.map +1 -1
  19. package/esm/mcp-server/prompts.js +12 -12
  20. package/esm/mcp-server/prompts.js.map +1 -1
  21. package/esm/mcp-server/resources.d.ts +6 -7
  22. package/esm/mcp-server/resources.d.ts.map +1 -1
  23. package/esm/mcp-server/resources.js +19 -3
  24. package/esm/mcp-server/resources.js.map +1 -1
  25. package/esm/mcp-server/server.d.ts +1 -1
  26. package/esm/mcp-server/server.d.ts.map +1 -1
  27. package/esm/mcp-server/server.js +2 -2
  28. package/esm/mcp-server/server.js.map +1 -1
  29. package/esm/mcp-server/shared.d.ts +7 -0
  30. package/esm/mcp-server/shared.d.ts.map +1 -1
  31. package/esm/mcp-server/shared.js +184 -0
  32. package/esm/mcp-server/shared.js.map +1 -1
  33. package/esm/mcp-server/tools/streamingProfilesCreateStreamingProfile.js +1 -1
  34. package/esm/mcp-server/tools/streamingProfilesCreateStreamingProfile.js.map +1 -1
  35. package/esm/mcp-server/tools/streamingProfilesDeleteStreamingProfile.js +1 -1
  36. package/esm/mcp-server/tools/streamingProfilesDeleteStreamingProfile.js.map +1 -1
  37. package/esm/mcp-server/tools/streamingProfilesGetStreamingProfile.js +1 -1
  38. package/esm/mcp-server/tools/streamingProfilesGetStreamingProfile.js.map +1 -1
  39. package/esm/mcp-server/tools/streamingProfilesGetStreamingProfiles.js +1 -1
  40. package/esm/mcp-server/tools/streamingProfilesGetStreamingProfiles.js.map +1 -1
  41. package/esm/mcp-server/tools/streamingProfilesUpdateStreamingProfile.js +1 -1
  42. package/esm/mcp-server/tools/streamingProfilesUpdateStreamingProfile.js.map +1 -1
  43. package/esm/mcp-server/tools/transformationsCreateTransformation.js +1 -1
  44. package/esm/mcp-server/tools/transformationsCreateTransformation.js.map +1 -1
  45. package/esm/mcp-server/tools/transformationsDeleteTransformation.js +1 -1
  46. package/esm/mcp-server/tools/transformationsDeleteTransformation.js.map +1 -1
  47. package/esm/mcp-server/tools/transformationsGetTransformation.js +1 -1
  48. package/esm/mcp-server/tools/transformationsGetTransformation.js.map +1 -1
  49. package/esm/mcp-server/tools/transformationsListTransformations.js +1 -1
  50. package/esm/mcp-server/tools/transformationsListTransformations.js.map +1 -1
  51. package/esm/mcp-server/tools/transformationsUpdateTransformation.js +1 -1
  52. package/esm/mcp-server/tools/transformationsUpdateTransformation.js.map +1 -1
  53. package/esm/mcp-server/tools/triggersCreateTrigger.js +1 -1
  54. package/esm/mcp-server/tools/triggersCreateTrigger.js.map +1 -1
  55. package/esm/mcp-server/tools/triggersDeleteTrigger.js +1 -1
  56. package/esm/mcp-server/tools/triggersDeleteTrigger.js.map +1 -1
  57. package/esm/mcp-server/tools/triggersListTrigger.js +1 -1
  58. package/esm/mcp-server/tools/triggersListTrigger.js.map +1 -1
  59. package/esm/mcp-server/tools/triggersTestTrigger.js +1 -1
  60. package/esm/mcp-server/tools/triggersTestTrigger.js.map +1 -1
  61. package/esm/mcp-server/tools/triggersUpdateTrigger.js +1 -1
  62. package/esm/mcp-server/tools/triggersUpdateTrigger.js.map +1 -1
  63. package/esm/mcp-server/tools/uploadMappingsCreateUploadMapping.js +1 -1
  64. package/esm/mcp-server/tools/uploadMappingsCreateUploadMapping.js.map +1 -1
  65. package/esm/mcp-server/tools/uploadMappingsDeleteUploadMapping.js +1 -1
  66. package/esm/mcp-server/tools/uploadMappingsDeleteUploadMapping.js.map +1 -1
  67. package/esm/mcp-server/tools/uploadMappingsListUploadMappings.js +1 -1
  68. package/esm/mcp-server/tools/uploadMappingsListUploadMappings.js.map +1 -1
  69. package/esm/mcp-server/tools/uploadMappingsUpdateUploadMapping.js +1 -1
  70. package/esm/mcp-server/tools/uploadMappingsUpdateUploadMapping.js.map +1 -1
  71. package/esm/mcp-server/tools/uploadPresetsCreateUploadPreset.js +1 -1
  72. package/esm/mcp-server/tools/uploadPresetsCreateUploadPreset.js.map +1 -1
  73. package/esm/mcp-server/tools/uploadPresetsDeleteUploadPreset.js +1 -1
  74. package/esm/mcp-server/tools/uploadPresetsDeleteUploadPreset.js.map +1 -1
  75. package/esm/mcp-server/tools/uploadPresetsGetUploadPreset.js +1 -1
  76. package/esm/mcp-server/tools/uploadPresetsGetUploadPreset.js.map +1 -1
  77. package/esm/mcp-server/tools/uploadPresetsListUploadPresets.js +1 -1
  78. package/esm/mcp-server/tools/uploadPresetsListUploadPresets.js.map +1 -1
  79. package/esm/mcp-server/tools/uploadPresetsUpdateUploadPreset.js +1 -1
  80. package/esm/mcp-server/tools/uploadPresetsUpdateUploadPreset.js.map +1 -1
  81. package/esm/mcp-server/tools.d.ts +11 -9
  82. package/esm/mcp-server/tools.d.ts.map +1 -1
  83. package/esm/mcp-server/tools.js +20 -19
  84. package/esm/mcp-server/tools.js.map +1 -1
  85. package/package.json +9 -4
  86. package/src/landing-page.ts +81 -28
  87. package/src/lib/config.ts +3 -3
  88. package/src/mcp-server/cli/serve/impl.ts +55 -25
  89. package/src/mcp-server/cli/start/impl.ts +16 -9
  90. package/src/mcp-server/extensions.ts +3 -5
  91. package/src/mcp-server/mcp-server.ts +1 -1
  92. package/src/mcp-server/prompts.ts +30 -43
  93. package/src/mcp-server/resources.ts +32 -17
  94. package/src/mcp-server/server.ts +2 -2
  95. package/src/mcp-server/shared.ts +201 -0
  96. package/src/mcp-server/tools/streamingProfilesCreateStreamingProfile.ts +1 -1
  97. package/src/mcp-server/tools/streamingProfilesDeleteStreamingProfile.ts +1 -1
  98. package/src/mcp-server/tools/streamingProfilesGetStreamingProfile.ts +1 -1
  99. package/src/mcp-server/tools/streamingProfilesGetStreamingProfiles.ts +1 -1
  100. package/src/mcp-server/tools/streamingProfilesUpdateStreamingProfile.ts +1 -1
  101. package/src/mcp-server/tools/transformationsCreateTransformation.ts +1 -1
  102. package/src/mcp-server/tools/transformationsDeleteTransformation.ts +1 -1
  103. package/src/mcp-server/tools/transformationsGetTransformation.ts +1 -1
  104. package/src/mcp-server/tools/transformationsListTransformations.ts +1 -1
  105. package/src/mcp-server/tools/transformationsUpdateTransformation.ts +1 -1
  106. package/src/mcp-server/tools/triggersCreateTrigger.ts +1 -1
  107. package/src/mcp-server/tools/triggersDeleteTrigger.ts +1 -1
  108. package/src/mcp-server/tools/triggersListTrigger.ts +1 -1
  109. package/src/mcp-server/tools/triggersTestTrigger.ts +1 -1
  110. package/src/mcp-server/tools/triggersUpdateTrigger.ts +1 -1
  111. package/src/mcp-server/tools/uploadMappingsCreateUploadMapping.ts +1 -1
  112. package/src/mcp-server/tools/uploadMappingsDeleteUploadMapping.ts +1 -1
  113. package/src/mcp-server/tools/uploadMappingsListUploadMappings.ts +1 -1
  114. package/src/mcp-server/tools/uploadMappingsUpdateUploadMapping.ts +1 -1
  115. package/src/mcp-server/tools/uploadPresetsCreateUploadPreset.ts +1 -1
  116. package/src/mcp-server/tools/uploadPresetsDeleteUploadPreset.ts +1 -1
  117. package/src/mcp-server/tools/uploadPresetsGetUploadPreset.ts +1 -1
  118. package/src/mcp-server/tools/uploadPresetsListUploadPresets.ts +1 -1
  119. package/src/mcp-server/tools/uploadPresetsUpdateUploadPreset.ts +1 -1
  120. package/src/mcp-server/tools.ts +42 -45
@@ -12,13 +12,28 @@ import { toolNames } from "./tool-names.js";
12
12
  // Cloudflare-specific wrapper
13
13
  export function landingPage(req: Request): Response {
14
14
  const origin = new URL(req.url).origin;
15
- return new Response(landingPageHTML(origin), {
15
+ return new Response(landingPageHTML(origin, "http", "cloudflare"), {
16
16
  headers: { "Content-Type": "text/html" },
17
17
  });
18
18
  }
19
19
 
20
20
  // express wrapper
21
21
  export function landingPageExpress(req: ExpressRequest, res: ExpressResponse) {
22
+ sendLandingPage(req, res, "sse");
23
+ }
24
+
25
+ export function landingPageExpressHTTP(
26
+ req: ExpressRequest,
27
+ res: ExpressResponse,
28
+ ) {
29
+ sendLandingPage(req, res, "http");
30
+ }
31
+
32
+ function sendLandingPage(
33
+ req: ExpressRequest,
34
+ res: ExpressResponse,
35
+ transport: "sse" | "http",
36
+ ) {
22
37
  const proto = req.get("x-forwarded-proto")?.split(",")[0]?.trim()
23
38
  || req.protocol;
24
39
  const host = req.get("host");
@@ -26,33 +41,71 @@ export function landingPageExpress(req: ExpressRequest, res: ExpressResponse) {
26
41
  res.status(400).send("Missing Host header");
27
42
  return;
28
43
  }
29
- res.type("html").send(landingPageHTML(`${proto}://${host}`));
44
+ res.type("html").send(landingPageHTML(`${proto}://${host}`, transport));
30
45
  }
31
46
 
32
- export function landingPageHTML(origin: string): string {
47
+ export function landingPageHTML(
48
+ origin: string,
49
+ transport: "sse" | "http" = "sse",
50
+ runtime: "node" | "cloudflare" = "node",
51
+ ): string {
33
52
  const o = origin;
53
+ const endpoint = transport === "sse" ? "sse" : "mcp";
54
+ const headers: Array<{ name: string; env: string }> = runtime === "cloudflare"
55
+ ? [{ "name": "x-cloudinary-auth", "env": "CLOUDINARY_AUTH" }, {
56
+ "name": "x-oauth2",
57
+ "env": "OAUTH2",
58
+ }]
59
+ : transport === "sse"
60
+ ? [{ "name": "api-key", "env": "API_KEY" }, {
61
+ "name": "api-secret",
62
+ "env": "API_SECRET",
63
+ }, { "name": "oauth2", "env": "OAUTH2" }]
64
+ : [
65
+ { "name": "api-key", "env": "API_KEY" },
66
+ { "name": "api-secret", "env": "API_SECRET" },
67
+ { "name": "oauth2", "env": "OAUTH2" },
68
+ { "name": "cloud-name", "env": "CLOUD_NAME" },
69
+ { "name": "region", "env": "REGION" },
70
+ { "name": "api-host", "env": "API_HOST" },
71
+ ];
34
72
  const mcpConfig = {
35
- "command": "npx",
36
- "args": [
73
+ command: "npx",
74
+ args: [
37
75
  "-y",
38
76
  "mcp-remote@0.1.25",
39
- `${o}/sse`,
40
- "--header",
41
- "api-key:${API_KEY}",
42
- "--header",
43
- "api-secret:${API_SECRET}",
44
- "--header",
45
- "cloud-name:${CLOUD_NAME}",
77
+ `${o}/${endpoint}`,
78
+ ...headers.flatMap(({ name, env }) => ["--header", `${name}:\${${env}}`]),
46
79
  ],
47
- "env": {
48
- "API_KEY": "YOUR_VALUE_HERE",
49
- "API_SECRET": "YOUR_VALUE_HERE",
50
- "CLOUD_NAME": "YOUR_VALUE_HERE",
51
- },
80
+ env: Object.fromEntries(headers.map(({ env }) => [env, "YOUR_VALUE_HERE"])),
52
81
  };
53
- const codexConfig = `[mcp_servers.CloudinaryEnvConfig]
54
- url = "${o}/sse"
55
- http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "cloud-name" = "YOUR_CLOUD_NAME" }`;
82
+ const cliHeaders = headers.map(({ name }) => `--header "${name}: ..."`).join(
83
+ " ",
84
+ );
85
+ const codexConfig = transport === "sse"
86
+ ? `[mcp_servers.CloudinaryEnvConfig]
87
+ command = ${JSON.stringify(mcpConfig.command)}
88
+ args = ${JSON.stringify(mcpConfig.args)}
89
+ env = { ${
90
+ Object.entries(mcpConfig.env).map(([name, value]) =>
91
+ `${JSON.stringify(name)} = ${JSON.stringify(value)}`
92
+ ).join(", ")
93
+ } }`
94
+ : `[mcp_servers.CloudinaryEnvConfig]
95
+ url = ${JSON.stringify(`${o}/${endpoint}`)}
96
+ http_headers = { ${
97
+ headers.map(({ name, env }) =>
98
+ `${JSON.stringify(name)} = ${JSON.stringify(`YOUR_${env}`)}`
99
+ ).join(", ")
100
+ } }`;
101
+ const encodedConfig = encodeURIComponent(
102
+ btoa(
103
+ Array.from(
104
+ new TextEncoder().encode(JSON.stringify(mcpConfig)),
105
+ byte => String.fromCharCode(byte),
106
+ ).join(""),
107
+ ),
108
+ );
56
109
 
57
110
  return `
58
111
  <!DOCTYPE html>
@@ -690,7 +743,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
690
743
  </svg>
691
744
  </button>
692
745
  <div class="popover-menu hidden" id="popover-menu">
693
- <a class="popover-button install-link" href="cursor://anysphere.cursor-deeplink/mcp/install?name=CloudinaryEnvConfig&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAY2xvdWRpbmFyeS9lbnZpcm9ubWVudC1jb25maWctbWNwIiwic3RhcnQiLCItLWFwaS1rZXkiLCIiLCItLWFwaS1zZWNyZXQiLCIiLCItLWNsb3VkLW5hbWUiLCIiXX0=">
746
+ <a class="popover-button install-link" href="cursor://anysphere.cursor-deeplink/mcp/install?name=CloudinaryEnvConfig&config=${encodedConfig}">
694
747
  Cursor
695
748
  </a>
696
749
  <button class="popover-button" onclick="showModal('claude-code')">
@@ -699,7 +752,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
699
752
  <button class="popover-button" onclick="showModal('claude-desktop')">
700
753
  Claude Desktop
701
754
  </button>
702
- <a class="popover-button install-link" href="vscode://ms-vscode.vscode-mcp/install?name=CloudinaryEnvConfig&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAY2xvdWRpbmFyeS9lbnZpcm9ubWVudC1jb25maWctbWNwIiwic3RhcnQiLCItLWFwaS1rZXkiLCIiLCItLWFwaS1zZWNyZXQiLCIiLCItLWNsb3VkLW5hbWUiLCIiXX0=">
755
+ <a class="popover-button install-link" href="vscode://ms-vscode.vscode-mcp/install?name=CloudinaryEnvConfig&config=${encodedConfig}">
703
756
  VS Code
704
757
  </a>
705
758
  <button class="popover-button" onclick="showModal('gemini')">
@@ -722,7 +775,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
722
775
  </div>
723
776
  </header>
724
777
  <div class="install-targets">
725
- <a tabindex="0" class="card install-target install-link" href="cursor://anysphere.cursor-deeplink/mcp/install?name=CloudinaryEnvConfig&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAY2xvdWRpbmFyeS9lbnZpcm9ubWVudC1jb25maWctbWNwIiwic3RhcnQiLCItLWFwaS1rZXkiLCIiLCItLWFwaS1zZWNyZXQiLCIiLCItLWNsb3VkLW5hbWUiLCIiXX0=">
778
+ <a tabindex="0" class="card install-target install-link" href="cursor://anysphere.cursor-deeplink/mcp/install?name=CloudinaryEnvConfig&config=${encodedConfig}">
726
779
  <div class="target">
727
780
  <img src="https://cursor.com/assets/images/logo.svg" alt="Cursor">
728
781
  <span>Cursor</span>
@@ -744,7 +797,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
744
797
  <span>Claude Desktop</span>
745
798
  </div>
746
799
  </div>
747
- <a tabindex="0" class="card install-target install-link" href="vscode://ms-vscode.vscode-mcp/install?name=CloudinaryEnvConfig&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAY2xvdWRpbmFyeS9lbnZpcm9ubWVudC1jb25maWctbWNwIiwic3RhcnQiLCItLWFwaS1rZXkiLCIiLCItLWFwaS1zZWNyZXQiLCIiLCItLWNsb3VkLW5hbWUiLCIiXX0=">
800
+ <a tabindex="0" class="card install-target install-link" href="vscode://ms-vscode.vscode-mcp/install?name=CloudinaryEnvConfig&config=${encodedConfig}">
748
801
  <div class="target">
749
802
  <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
750
803
  <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
@@ -866,7 +919,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
866
919
  <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path>
867
920
  </svg>
868
921
  </button>
869
- <code class="code-snippet" id="server-url">${o}/mcp</code>
922
+ <code class="code-snippet" id="server-url">${o}/${endpoint}</code>
870
923
  </div>
871
924
  </section>
872
925
 
@@ -923,7 +976,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
923
976
  <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path>
924
977
  </svg>
925
978
  </button>
926
- <code class="code-snippet language-json" id="claude-cli-cmd">claude mcp add CloudinaryEnvConfig -- npx -y @cloudinary/environment-config-mcp start --api-key --api-secret --cloud-name </code>
979
+ <code class="code-snippet language-json" id="claude-cli-cmd">claude mcp add --transport ${transport} CloudinaryEnvConfig ${o}/${endpoint} ${cliHeaders}</code>
927
980
  </div>
928
981
  </div>
929
982
  </div>
@@ -939,7 +992,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
939
992
  <h1>Instructions</h1>
940
993
  <p>One-click installation for Claude Desktop users</p>
941
994
  <div class="instruction-item">
942
- <a href="https://github.com/cloudinary/environment-config-mcp/releases/download/v0.6.2/mcp-server.mcpb" download="mcp-server.mcpb" class="action-button header-action" style="display: inline-flex; margin-bottom: 16px;">
995
+ <a href="https://github.com/cloudinary/environment-config-mcp/releases/download/v0.6.3/mcp-server.mcpb" download="mcp-server.mcpb" class="action-button header-action" style="display: inline-flex; margin-bottom: 16px;">
943
996
  📥 Download MCP Bundle
944
997
  </a>
945
998
  </div>
@@ -974,7 +1027,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
974
1027
  <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path>
975
1028
  </svg>
976
1029
  </button>
977
- <code class="code-snippet language-json" id="gemini-config">gemini mcp add CloudinaryEnvConfig -- npx -y @cloudinary/environment-config-mcp start --api-key --api-secret --cloud-name </code>
1030
+ <code class="code-snippet language-json" id="gemini-config">gemini mcp add --transport ${transport} CloudinaryEnvConfig ${o}/${endpoint} ${cliHeaders}</code>
978
1031
  </div>
979
1032
  </div>
980
1033
  </div>
package/src/lib/config.ts CHANGED
@@ -113,8 +113,8 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
113
113
  export const SDK_METADATA = {
114
114
  language: "typescript",
115
115
  openapiDocVersion: "0.5.5",
116
- sdkVersion: "0.6.2",
117
- genVersion: "2.943.0",
116
+ sdkVersion: "0.6.3",
117
+ genVersion: "2.950.2",
118
118
  userAgent:
119
- "speakeasy-sdk/mcp-typescript 0.6.2 2.943.0 0.5.5 @cloudinary/environment-config-mcp",
119
+ "speakeasy-sdk/mcp-typescript 0.6.3 2.950.2 0.5.5 @cloudinary/environment-config-mcp",
120
120
  } as const;
@@ -3,8 +3,8 @@
3
3
  * @generated-id: 03e83f226068
4
4
  */
5
5
 
6
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
7
- import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
6
+ import { toNodeHandler } from "@modelcontextprotocol/node";
7
+ import { createMcpHandler } from "@modelcontextprotocol/server";
8
8
  import express from "express";
9
9
  import { LocalContext } from "../../cli.js";
10
10
  import {
@@ -16,7 +16,7 @@ import { createMCPServer } from "../../server.js";
16
16
  import { buildAnnotationFilter } from "../../tools.js";
17
17
  import { buildSDK } from "../../tools.js";
18
18
 
19
- import { landingPageExpress } from "../../../landing-page.js";
19
+ import { landingPageExpressHTTP } from "../../../landing-page.js";
20
20
 
21
21
  interface ServeCommandFlags extends MCPServerFlags {
22
22
  readonly port: number;
@@ -40,7 +40,7 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
40
40
  // Enable CORS for cross-origin requests
41
41
  app.use((req, res, next) => {
42
42
  res.header("Access-Control-Allow-Origin", "*");
43
- res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
43
+ res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
44
44
  res.header("Access-Control-Allow-Headers", "*");
45
45
  if (req.method === "OPTIONS") {
46
46
  res.sendStatus(204);
@@ -49,19 +49,10 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
49
49
  next();
50
50
  });
51
51
 
52
- app.use(express.json());
52
+ app.use(express.json({ inflate: false }));
53
53
 
54
- app.post("/mcp", async (req, res) => {
55
- const headers = new Headers();
56
- for (const [key, value] of Object.entries(req.headers)) {
57
- if (Array.isArray(value)) {
58
- for (const v of value) headers.append(key, v);
59
- } else if (value !== undefined) {
60
- headers.set(key, value);
61
- }
62
- }
63
-
64
- const transport = new StreamableHTTPServerTransport({});
54
+ const handler = createMcpHandler(({ requestInfo }) => {
55
+ const headers = requestInfo?.headers ?? new Headers();
65
56
 
66
57
  const { server: mcpServer } = createMCPServer({
67
58
  logger,
@@ -85,11 +76,41 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
85
76
  });
86
77
  };
87
78
 
88
- await mcpServer.connect(transport as Transport);
89
- await transport.handleRequest(req, res, req.body);
79
+ return mcpServer;
80
+ });
81
+ const nodeHandler = toNodeHandler(handler);
82
+ const activeResponses = new Set<Promise<void>>();
83
+ let closing = false;
84
+ app.use((_req, res, next) => {
85
+ if (closing) {
86
+ res.set("Connection", "close").status(503).send(
87
+ "Server is shutting down",
88
+ );
89
+ return;
90
+ }
91
+ next();
92
+ });
93
+ app.all("/mcp", (req, res) => {
94
+ // Notification streams remain open until handler.close().
95
+ if (req.method !== "GET" && req.body?.method !== "subscriptions/listen") {
96
+ let finish!: () => void;
97
+ const completed = new Promise<void>((resolve) => {
98
+ finish = resolve;
99
+ });
100
+ const done = () => {
101
+ res.off("finish", done);
102
+ res.off("close", done);
103
+ activeResponses.delete(completed);
104
+ finish();
105
+ };
106
+ activeResponses.add(completed);
107
+ res.once("finish", done);
108
+ res.once("close", done);
109
+ }
110
+ return nodeHandler(req, res, req.body);
90
111
  });
91
112
 
92
- app.get("/", landingPageExpress);
113
+ app.get("/", landingPageExpressHTTP);
93
114
 
94
115
  const httpServer = app.listen(cliFlags.port, "0.0.0.0", () => {
95
116
  const ha = httpServer.address();
@@ -97,7 +118,11 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
97
118
  logger.info("MCP Streamable HTTP server started", { host });
98
119
  });
99
120
 
100
- const shutdown = () => {
121
+ const shutdown = async () => {
122
+ if (closing) {
123
+ process.exit(1);
124
+ }
125
+ closing = true;
101
126
  logger.info("Shutting down HTTP server");
102
127
 
103
128
  const timer = setTimeout(() => {
@@ -105,11 +130,16 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
105
130
  process.exit(1);
106
131
  }, 5000);
107
132
 
108
- httpServer.close(() => {
109
- clearTimeout(timer);
110
- logger.info("Graceful shutdown complete");
111
- process.exit(0);
112
- });
133
+ const stopped = new Promise<void>((resolve) =>
134
+ httpServer.close(() => resolve())
135
+ );
136
+ await Promise.all(activeResponses);
137
+ await handler.close();
138
+ httpServer.closeAllConnections();
139
+ await stopped;
140
+ clearTimeout(timer);
141
+ logger.info("Graceful shutdown complete");
142
+ process.exit(0);
113
143
  };
114
144
 
115
145
  process.on("SIGTERM", shutdown);
@@ -3,8 +3,8 @@
3
3
  * @generated-id: 37494f674015
4
4
  */
5
5
 
6
- import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
7
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { SSEServerTransport } from "@modelcontextprotocol/server-legacy/sse";
7
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
8
8
  import express from "express";
9
9
  import { LocalContext } from "../../cli.js";
10
10
  import {
@@ -49,8 +49,7 @@ export async function main(this: LocalContext, flags: StartCommandFlags) {
49
49
 
50
50
  async function startStdio(flags: StartCommandFlags) {
51
51
  const logger = createConsoleLogger(flags["log-level"]);
52
- const transport = new StdioServerTransport();
53
- const { server } = createMCPServer({
52
+ const createServer = createMCPServerFactory({
54
53
  logger,
55
54
  allowedTools: flags.tool,
56
55
  dynamic: flags.mode === "dynamic",
@@ -71,16 +70,22 @@ async function startStdio(flags: StartCommandFlags) {
71
70
  region: flags.region,
72
71
  host: flags["api-host"],
73
72
  });
74
- await server.connect(transport);
73
+ const handle = serveStdio(createServer);
75
74
 
76
75
  const abort = async () => {
77
- await server.close();
76
+ await handle.close();
78
77
  process.exit(0);
79
78
  };
80
79
  process.on("SIGTERM", abort);
81
80
  process.on("SIGINT", abort);
82
81
  }
83
82
 
83
+ function createMCPServerFactory(
84
+ options: Parameters<typeof createMCPServer>[0],
85
+ ) {
86
+ return () => createMCPServer(options).server;
87
+ }
88
+
84
89
  async function startSSE(cliFlags: StartCommandFlags) {
85
90
  const logger = createConsoleLogger(cliFlags["log-level"]);
86
91
  const app = express();
@@ -108,9 +113,11 @@ async function startSSE(cliFlags: StartCommandFlags) {
108
113
  const flags: StartCommandFlags = {
109
114
  ...cliFlags,
110
115
  // Security fields can be overridden via headers
111
- "api-key": (req.headers["api_key"] as string) ?? cliFlags["api-key"],
112
- "api-secret": (req.headers["api_secret"] as string)
113
- ?? cliFlags["api-secret"],
116
+ "api-key": ((req.headers["api-key"] ?? req.headers["api_key"]) as string)
117
+ ?? cliFlags["api-key"],
118
+ "api-secret":
119
+ ((req.headers["api-secret"] ?? req.headers["api_secret"]) as string)
120
+ ?? cliFlags["api-secret"],
114
121
  "oauth2": (req.headers["oauth2"] as string) ?? cliFlags["oauth2"],
115
122
  };
116
123
 
@@ -3,18 +3,16 @@
3
3
  * @generated-id: 3d9d20ff158f
4
4
  */
5
5
 
6
- import { ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
6
+ import * as z from "zod";
7
7
  import { PromptDefinition } from "./prompts.js";
8
8
  import { ResourceDefinition, ResourceTemplateDefinition } from "./resources.js";
9
9
  import { ToolDefinition } from "./tools.js";
10
10
 
11
11
  export type Register = {
12
- tool: <A extends ZodRawShapeCompat | undefined>(
13
- def: ToolDefinition<A>,
14
- ) => void;
12
+ tool: <A extends z.ZodRawShape | undefined>(def: ToolDefinition<A>) => void;
15
13
  resource: (def: ResourceDefinition) => void;
16
14
  resourceTemplate: (def: ResourceTemplateDefinition) => void;
17
- prompt: <A extends ZodRawShapeCompat | undefined>(
15
+ prompt: <A extends z.ZodRawShape | undefined>(
18
16
  prompt: PromptDefinition<A>,
19
17
  ) => void;
20
18
  };
@@ -22,7 +22,7 @@ const routes = buildRouteMap({
22
22
  export const app = buildApplication(routes, {
23
23
  name: "mcp",
24
24
  versionInfo: {
25
- currentVersion: "0.6.2",
25
+ currentVersion: "0.6.3",
26
26
  },
27
27
  });
28
28
 
@@ -3,32 +3,28 @@
3
3
  * @generated-id: 26f3d73cbf31
4
4
  */
5
5
 
6
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
- import {
8
- ShapeOutput,
9
- ZodRawShapeCompat,
10
- } from "@modelcontextprotocol/sdk/server/zod-compat.js";
11
- import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
12
- import {
13
- GetPromptResult,
14
- ServerNotification,
15
- ServerRequest,
16
- } from "@modelcontextprotocol/sdk/types.js";
6
+ import { GetPromptResult, McpServer } from "@modelcontextprotocol/server";
7
+ import * as z from "zod";
17
8
  import { CloudinaryEnvConfigCore } from "../core.js";
18
9
  import { ConsoleLogger } from "./console-logger.js";
19
10
  import { MCPScope } from "./scopes.js";
11
+ import {
12
+ mcpInputSchema,
13
+ MCPServerContext,
14
+ mcpServerContext,
15
+ } from "./shared.js";
20
16
 
21
17
  export type PromptDefinition<
22
- Args extends undefined | ZodRawShapeCompat = undefined,
23
- > = Args extends ZodRawShapeCompat ? {
18
+ Args extends undefined | z.ZodRawShape = undefined,
19
+ > = Args extends z.ZodRawShape ? {
24
20
  name: string;
25
21
  description?: string;
26
22
  scopes?: MCPScope[];
27
23
  args: Args;
28
24
  prompt: (
29
25
  client: CloudinaryEnvConfigCore,
30
- args: ShapeOutput<Args>,
31
- extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
26
+ args: z.output<z.ZodObject<Args>>,
27
+ extra: MCPServerContext,
32
28
  ) => GetPromptResult | Promise<GetPromptResult>;
33
29
  }
34
30
  : {
@@ -38,7 +34,7 @@ export type PromptDefinition<
38
34
  args?: undefined;
39
35
  prompt: (
40
36
  client: CloudinaryEnvConfigCore,
41
- extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
37
+ extra: MCPServerContext,
42
38
  ) => GetPromptResult | Promise<GetPromptResult>;
43
39
  };
44
40
 
@@ -62,10 +58,8 @@ export function createRegisterPrompt(
62
58
  server: McpServer,
63
59
  getSDK: () => CloudinaryEnvConfigCore,
64
60
  allowedScopes: Set<MCPScope>,
65
- ): <A extends ZodRawShapeCompat | undefined>(
66
- prompt: PromptDefinition<A>,
67
- ) => void {
68
- return <A extends ZodRawShapeCompat | undefined>(
61
+ ): <A extends z.ZodRawShape | undefined>(prompt: PromptDefinition<A>) => void {
62
+ return <A extends z.ZodRawShape | undefined>(
69
63
  prompt: PromptDefinition<A>,
70
64
  ): void => {
71
65
  const scopes = prompt.scopes ?? [];
@@ -81,30 +75,23 @@ export function createRegisterPrompt(
81
75
  }
82
76
 
83
77
  if (prompt.args) {
84
- if (prompt.description) {
85
- server.prompt(
86
- prompt.name,
87
- prompt.description,
88
- prompt.args,
89
- async (args, ctx) => prompt.prompt(getSDK(), args, ctx),
90
- );
91
- } else {
92
- server.prompt(
93
- prompt.name,
94
- prompt.args,
95
- async (args, ctx) => prompt.prompt(getSDK(), args, ctx),
96
- );
97
- }
78
+ server.registerPrompt(
79
+ prompt.name,
80
+ {
81
+ ...(prompt.description === undefined
82
+ ? {}
83
+ : { description: prompt.description }),
84
+ argsSchema: { ...mcpInputSchema(prompt.args), shape: prompt.args },
85
+ },
86
+ async (args, ctx) =>
87
+ prompt.prompt(getSDK(), args, mcpServerContext(ctx)),
88
+ );
98
89
  } else {
99
- if (prompt.description) {
100
- server.prompt(
101
- prompt.name,
102
- prompt.description,
103
- async (ctx) => prompt.prompt(getSDK(), ctx),
104
- );
105
- } else {
106
- server.prompt(prompt.name, async (ctx) => prompt.prompt(getSDK(), ctx));
107
- }
90
+ server.registerPrompt(prompt.name, {
91
+ ...(prompt.description === undefined
92
+ ? {}
93
+ : { description: prompt.description }),
94
+ }, async (ctx) => prompt.prompt(getSDK(), mcpServerContext(ctx)));
108
95
  }
109
96
 
110
97
  logger.debug("Registered prompt", { name: prompt.name });
@@ -3,27 +3,23 @@
3
3
  * @generated-id: cb0c57ebeaea
4
4
  */
5
5
 
6
+ import type { ResourceTemplate as LegacyResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
6
7
  import {
7
8
  McpServer,
9
+ ReadResourceResult,
8
10
  ResourceMetadata,
9
11
  ResourceTemplate,
10
- } from "@modelcontextprotocol/sdk/server/mcp.js";
11
- import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
12
- import { Variables } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
13
- import {
14
- ReadResourceResult,
15
- ServerNotification,
16
- ServerRequest,
17
- } from "@modelcontextprotocol/sdk/types.js";
12
+ Variables,
13
+ } from "@modelcontextprotocol/server";
18
14
  import { CloudinaryEnvConfigCore } from "../core.js";
19
15
  import { ConsoleLogger } from "./console-logger.js";
20
16
  import { MCPScope } from "./scopes.js";
21
- import { valueToBase64 } from "./shared.js";
17
+ import { MCPServerContext, mcpServerContext, valueToBase64 } from "./shared.js";
22
18
 
23
19
  export type ReadResourceCallback = (
24
20
  client: CloudinaryEnvConfigCore,
25
21
  uri: URL,
26
- extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
22
+ extra: MCPServerContext,
27
23
  ) => ReadResourceResult | Promise<ReadResourceResult>;
28
24
 
29
25
  export type ResourceDefinition = {
@@ -39,7 +35,7 @@ export type ReadResourceTemplateCallback = (
39
35
  client: CloudinaryEnvConfigCore,
40
36
  uri: URL,
41
37
  vars: Variables,
42
- extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
38
+ extra: MCPServerContext,
43
39
  ) => ReadResourceResult | Promise<ReadResourceResult>;
44
40
 
45
41
  export type ResourceTemplateDefinition = {
@@ -47,7 +43,7 @@ export type ResourceTemplateDefinition = {
47
43
  description: string;
48
44
  metadata?: ResourceMetadata;
49
45
  scopes?: MCPScope[];
50
- resource: ResourceTemplate;
46
+ resource: ResourceTemplate | LegacyResourceTemplate;
51
47
  read: ReadResourceTemplateCallback;
52
48
  };
53
49
 
@@ -95,11 +91,11 @@ export function createRegisterResource(
95
91
  description: resource.description,
96
92
  };
97
93
 
98
- server.resource(
94
+ server.registerResource(
99
95
  resource.name,
100
96
  resource.resource,
101
97
  metadata,
102
- async (uri, ctx) => resource.read(getSDK(), uri, ctx),
98
+ async (uri, ctx) => resource.read(getSDK(), uri, mcpServerContext(ctx)),
103
99
  );
104
100
 
105
101
  logger.debug("Registered resource", { name: resource.name });
@@ -130,13 +126,32 @@ export function createRegisterResourceTemplate(
130
126
  description: resource.description,
131
127
  };
132
128
 
133
- server.resource(
129
+ server.registerResource(
134
130
  resource.name,
135
- resource.resource,
131
+ normalizeResourceTemplate(resource.resource),
136
132
  metadata,
137
- async (uri, vars, ctx) => resource.read(getSDK(), uri, vars, ctx),
133
+ async (uri, vars, ctx) =>
134
+ resource.read(getSDK(), uri, vars, mcpServerContext(ctx)),
138
135
  );
139
136
 
140
137
  logger.debug("Registered resource template", { name: resource.name });
141
138
  };
142
139
  }
140
+
141
+ function normalizeResourceTemplate(
142
+ resource: ResourceTemplate | LegacyResourceTemplate,
143
+ ): ResourceTemplate {
144
+ if (resource instanceof ResourceTemplate) return resource;
145
+ const complete: NonNullable<
146
+ ConstructorParameters<typeof ResourceTemplate>[1]["complete"]
147
+ > = {};
148
+ for (const variable of resource.uriTemplate.variableNames) {
149
+ const callback = resource.completeCallback(variable);
150
+ if (callback) complete[variable] = callback;
151
+ }
152
+ const list = resource.listCallback;
153
+ return new ResourceTemplate(resource.uriTemplate.toString(), {
154
+ list: list ? (ctx) => list(mcpServerContext(ctx)) : undefined,
155
+ complete,
156
+ });
157
+ }
@@ -3,7 +3,7 @@
3
3
  * @generated-id: 2784dd48e82a
4
4
  */
5
5
 
6
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { McpServer } from "@modelcontextprotocol/server";
7
7
  import { CloudinaryEnvConfigCore } from "../core.js";
8
8
  import { SDKOptions } from "../lib/config.js";
9
9
  import type { ConsoleLogger } from "./console-logger.js";
@@ -60,7 +60,7 @@ export function createMCPServer(deps: {
60
60
  }) {
61
61
  const server = new McpServer({
62
62
  name: "CloudinaryEnvConfig",
63
- version: "0.6.2",
63
+ version: "0.6.3",
64
64
  ...serverInfo,
65
65
  }, { instructions });
66
66