@sonoma-security/mcp-gateway 0.1.4 → 0.1.6

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 (62) hide show
  1. package/README.md +104 -45
  2. package/dist/__tests__/config.test.js +28 -0
  3. package/dist/__tests__/config.test.js.map +1 -1
  4. package/dist/__tests__/ssrf-protection.test.d.ts +2 -0
  5. package/dist/__tests__/ssrf-protection.test.d.ts.map +1 -0
  6. package/dist/__tests__/ssrf-protection.test.js +389 -0
  7. package/dist/__tests__/ssrf-protection.test.js.map +1 -0
  8. package/dist/auth/client.d.ts +2 -0
  9. package/dist/auth/client.d.ts.map +1 -1
  10. package/dist/auth/client.js +17 -15
  11. package/dist/auth/client.js.map +1 -1
  12. package/dist/auth/crypto.d.ts +23 -0
  13. package/dist/auth/crypto.d.ts.map +1 -0
  14. package/dist/auth/crypto.js +78 -0
  15. package/dist/auth/crypto.js.map +1 -0
  16. package/dist/auth/index.d.ts +4 -1
  17. package/dist/auth/index.d.ts.map +1 -1
  18. package/dist/auth/index.js +4 -1
  19. package/dist/auth/index.js.map +1 -1
  20. package/dist/auth/server.d.ts +2 -0
  21. package/dist/auth/server.d.ts.map +1 -1
  22. package/dist/auth/server.js +337 -59
  23. package/dist/auth/server.js.map +1 -1
  24. package/dist/auth/storage.d.ts.map +1 -1
  25. package/dist/auth/storage.js +2 -72
  26. package/dist/auth/storage.js.map +1 -1
  27. package/dist/auth/upstream-oauth-provider.d.ts +41 -0
  28. package/dist/auth/upstream-oauth-provider.d.ts.map +1 -0
  29. package/dist/auth/upstream-oauth-provider.js +88 -0
  30. package/dist/auth/upstream-oauth-provider.js.map +1 -0
  31. package/dist/auth/upstream-oauth.d.ts +31 -0
  32. package/dist/auth/upstream-oauth.d.ts.map +1 -0
  33. package/dist/auth/upstream-oauth.js +79 -0
  34. package/dist/auth/upstream-oauth.js.map +1 -0
  35. package/dist/auth/upstream-token-store.d.ts +27 -0
  36. package/dist/auth/upstream-token-store.d.ts.map +1 -0
  37. package/dist/auth/upstream-token-store.js +103 -0
  38. package/dist/auth/upstream-token-store.js.map +1 -0
  39. package/dist/cli.js +91 -63
  40. package/dist/cli.js.map +1 -1
  41. package/dist/config.d.ts.map +1 -1
  42. package/dist/config.js +94 -9
  43. package/dist/config.js.map +1 -1
  44. package/dist/gateway.d.ts +23 -1
  45. package/dist/gateway.d.ts.map +1 -1
  46. package/dist/gateway.js +203 -41
  47. package/dist/gateway.js.map +1 -1
  48. package/dist/pattern-matcher.d.ts +47 -0
  49. package/dist/pattern-matcher.d.ts.map +1 -0
  50. package/dist/pattern-matcher.js +98 -0
  51. package/dist/pattern-matcher.js.map +1 -0
  52. package/dist/sonoma-client.d.ts +21 -6
  53. package/dist/sonoma-client.d.ts.map +1 -1
  54. package/dist/sonoma-client.js +45 -5
  55. package/dist/sonoma-client.js.map +1 -1
  56. package/dist/ssrf-protection.d.ts +59 -0
  57. package/dist/ssrf-protection.d.ts.map +1 -0
  58. package/dist/ssrf-protection.js +253 -0
  59. package/dist/ssrf-protection.js.map +1 -0
  60. package/dist/types.d.ts +6 -2
  61. package/dist/types.d.ts.map +1 -1
  62. package/package.json +2 -2
@@ -16,9 +16,11 @@ export function startCallbackServer(options = {}) {
16
16
  const port = options.port || DEFAULT_PORT;
17
17
  const timeout = options.timeout || TIMEOUT_MS;
18
18
  const debug = options.debug || false;
19
+ const serverName = options.serverName;
19
20
  const log = (message, ...args) => {
20
21
  if (debug) {
21
- console.error(`[callback-server] ${message}`, ...args);
22
+ // Security: message is from developer code, not user input
23
+ console.error(`[callback-server] ${message}`, ...args); // nosemgrep: unsafe-formatstring
22
24
  }
23
25
  };
24
26
  return new Promise((resolve, reject) => {
@@ -56,28 +58,7 @@ export function startCallbackServer(options = {}) {
56
58
  if (error) {
57
59
  log("OAuth error:", error, errorDescription);
58
60
  res.writeHead(400, { "Content-Type": "text/html" });
59
- res.end(`
60
- <!DOCTYPE html>
61
- <html>
62
- <head>
63
- <title>Authentication Failed</title>
64
- <style>
65
- body { font-family: system-ui, sans-serif; padding: 40px; max-width: 600px; margin: 0 auto; }
66
- h1 { color: #dc2626; }
67
- .error { background: #fef2f2; border: 1px solid #fecaca; padding: 16px; border-radius: 8px; }
68
- code { background: #f3f4f6; padding: 2px 6px; border-radius: 4px; }
69
- </style>
70
- </head>
71
- <body>
72
- <h1>Authentication Failed</h1>
73
- <div class="error">
74
- <p><strong>Error:</strong> <code>${error}</code></p>
75
- ${errorDescription ? `<p>${errorDescription}</p>` : ""}
76
- </div>
77
- <p>You can close this window and try again.</p>
78
- </body>
79
- </html>
80
- `);
61
+ res.end(renderErrorPage("Authorization failed. Please close this window and try again."));
81
62
  cleanup();
82
63
  reject(new Error(`OAuth error: ${error}${errorDescription ? ` - ${errorDescription}` : ""}`));
83
64
  return;
@@ -86,22 +67,7 @@ export function startCallbackServer(options = {}) {
86
67
  if (!code) {
87
68
  log("Missing authorization code");
88
69
  res.writeHead(400, { "Content-Type": "text/html" });
89
- res.end(`
90
- <!DOCTYPE html>
91
- <html>
92
- <head>
93
- <title>Authentication Failed</title>
94
- <style>
95
- body { font-family: system-ui, sans-serif; padding: 40px; max-width: 600px; margin: 0 auto; }
96
- h1 { color: #dc2626; }
97
- </style>
98
- </head>
99
- <body>
100
- <h1>Authentication Failed</h1>
101
- <p>No authorization code received. Please try again.</p>
102
- </body>
103
- </html>
104
- `);
70
+ res.end(renderErrorPage("No authorization code received. Please try again."));
105
71
  cleanup();
106
72
  reject(new Error("No authorization code received"));
107
73
  return;
@@ -109,26 +75,7 @@ export function startCallbackServer(options = {}) {
109
75
  // Success!
110
76
  log("Received authorization code");
111
77
  res.writeHead(200, { "Content-Type": "text/html" });
112
- res.end(`
113
- <!DOCTYPE html>
114
- <html>
115
- <head>
116
- <title>Authentication Successful</title>
117
- <style>
118
- body { font-family: system-ui, sans-serif; padding: 40px; max-width: 600px; margin: 0 auto; }
119
- h1 { color: #16a34a; }
120
- .success { background: #f0fdf4; border: 1px solid #bbf7d0; padding: 16px; border-radius: 8px; }
121
- </style>
122
- </head>
123
- <body>
124
- <h1>Authentication Successful</h1>
125
- <div class="success">
126
- <p>You have been authenticated with Sonoma MCP Gateway.</p>
127
- <p>You can close this window and return to your terminal.</p>
128
- </div>
129
- </body>
130
- </html>
131
- `);
78
+ res.end(renderSuccessPage(serverName));
132
79
  cleanup();
133
80
  resolve({ code, state: state || undefined });
134
81
  });
@@ -152,4 +99,335 @@ export function startCallbackServer(options = {}) {
152
99
  export function getCallbackUrl(port = DEFAULT_PORT) {
153
100
  return `http://localhost:${port}/callback`;
154
101
  }
102
+ // ============================================================================
103
+ // HTML page renderers (dark mode with topographic background)
104
+ // ============================================================================
105
+ function escapeHtml(str) {
106
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
107
+ }
108
+ /** Capitalize first letter of each word */
109
+ function capitalize(str) {
110
+ return str.replace(/\b\w/g, (c) => c.toUpperCase());
111
+ }
112
+ // Favicon: sonoma-icon.svg (dark bg, orange gradient hat, white strokes)
113
+ const FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 300 300" fill="none"><g clip-path="url(#c)"><rect width="300" height="300" fill="#111"/><g filter="url(#f)"><path d="M212.951 161.36C212.951 180.967 185.717 153.051 150.258 153.051C114.799 153.051 84.544 180.967 84.544 161.36C84.544 141.753 93.608 86.581 150.258 86.581C206.909 86.581 212.951 141.753 212.951 161.36Z" fill="url(#g)"/></g><path d="M89.856 170.851C84.708 156.435 84.945 140.645 90.524 126.39C96.102 112.136 106.645 100.379 120.21 93.286C133.775 86.194 149.446 84.244 164.336 87.797C179.225 91.35 192.327 100.165 201.228 112.618C210.129 125.072 214.228 140.323 212.769 155.56C211.31 170.798 204.391 184.994 193.289 195.532C182.187 206.07 167.649 212.239 152.357 212.902C137.064 213.565 122.047 208.677 110.075 199.139" stroke="#fff" stroke-width="18.128"/><path d="M45.754 199.564C59.378 185.94 75.553 175.133 93.353 167.76C111.154 160.386 130.233 156.591 149.5 156.591C168.768 156.591 187.847 160.386 205.647 167.76C223.448 175.133 239.622 185.94 253.247 199.564" stroke="#fff" stroke-width="19.563"/></g><defs><filter id="f" x="26.928" y="38.933" width="243.64" height="196.992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="bg"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="ha"/><feOffset dy="9.968"/><feGaussianBlur stdDeviation="28.808"/><feComposite in2="ha" operator="out"/><feColorMatrix values="0 0 0 0 0.857 0 0 0 0 0.463 0 0 0 0 0 0 0 0 0.8 0"/><feBlend in2="bg" result="e1"/><feBlend in="SourceGraphic" in2="e1"/></filter><linearGradient id="g" x1="114.002" y1="138.7" x2="201.621" y2="172.69" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6B00"/><stop offset="1" stop-color="#FFB800"/></linearGradient><clipPath id="c"><rect width="300" height="300" fill="#fff"/></clipPath></defs></svg>`;
114
+ // Sonoma logo SVG (uses currentColor for theme-adaptive strokes)
115
+ const SONOMA_LOGO = `<svg width="56" height="56" viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
116
+ <g clip-path="url(#clip0)">
117
+ <g filter="url(#filter0)">
118
+ <path d="M235.844 162.467C235.844 188.839 199.212 151.292 151.519 151.292C103.825 151.292 63.1299 188.839 63.1299 162.467C63.1299 136.096 75.3215 61.8868 151.519 61.8868C227.716 61.8868 235.844 136.096 235.844 162.467Z" fill="url(#paint0)"/>
119
+ </g>
120
+ <path d="M70.2747 175.233C63.3507 155.844 63.6696 134.605 71.1726 115.432C78.6757 96.2592 92.8571 80.4452 111.102 70.9054C129.347 61.3657 150.426 58.7434 170.453 63.5221C190.479 68.3008 208.103 80.1582 220.075 96.9083C232.047 113.658 237.56 134.172 235.597 154.667C233.635 175.162 224.33 194.256 209.397 208.43C194.464 222.604 174.91 230.902 154.341 231.794C133.771 232.685 113.573 226.111 97.4697 213.282" stroke="currentColor" stroke-width="24.3832"/>
121
+ <path d="M10.9567 213.854C29.2817 195.529 51.0367 180.993 74.9795 171.075C98.9222 161.158 124.584 156.054 150.499 156.054C176.415 156.054 202.077 161.158 226.019 171.075C249.962 180.993 271.717 195.529 290.042 213.854" stroke="currentColor" stroke-width="26.3124"/>
122
+ </g>
123
+ <defs>
124
+ <filter id="filter0" x="-14.3656" y="-2.20115" width="327.705" height="264.962" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
125
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
126
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
127
+ <feOffset dy="13.4075"/>
128
+ <feGaussianBlur stdDeviation="38.7478"/>
129
+ <feComposite in2="hardAlpha" operator="out"/>
130
+ <feColorMatrix type="matrix" values="0 0 0 0 0.856738 0 0 0 0 0.462638 0 0 0 0 0 0 0 0 0.8 0"/>
131
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1"/>
132
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1" result="shape"/>
133
+ </filter>
134
+ <linearGradient id="paint0" x1="102.753" y1="131.988" x2="220.604" y2="177.707" gradientUnits="userSpaceOnUse">
135
+ <stop stop-color="#FF6B00"/>
136
+ <stop offset="1" stop-color="#FFB800"/>
137
+ </linearGradient>
138
+ <clipPath id="clip0">
139
+ <rect width="300" height="300" fill="white"/>
140
+ </clipPath>
141
+ </defs>
142
+ </svg>`;
143
+ // Sonoma wordmark SVG (uses currentColor for theme-adaptive text + strokes)
144
+ const SONOMA_WORDMARK = `<svg width="200" height="44" viewBox="0 0 1270 280" fill="none" xmlns="http://www.w3.org/2000/svg">
145
+ <g clip-path="url(#wm_clip0)">
146
+ <path d="M525.022 87.417C493.624 87.417 469.948 110.614 469.948 141.395C469.948 172.16 493.624 195.358 525.022 195.358C556.421 195.358 580.097 172.16 580.097 141.395C580.097 110.63 556.421 87.417 525.022 87.417ZM525.022 176.577C505.315 176.577 490.458 161.457 490.458 141.395C490.458 121.333 505.315 106.213 525.022 106.213C544.729 106.213 559.587 121.333 559.587 141.395C559.587 161.457 544.729 176.577 525.022 176.577Z" fill="currentColor"/>
147
+ <path d="M777.275 87.417C745.876 87.417 722.2 110.614 722.2 141.395C722.2 172.16 745.876 195.358 777.275 195.358C808.673 195.358 832.349 172.16 832.349 141.395C832.349 110.63 808.673 87.417 777.275 87.417ZM777.275 176.577C757.568 176.577 742.71 161.457 742.71 141.395C742.71 121.333 757.568 106.213 777.275 106.213C796.982 106.213 811.839 121.333 811.839 141.395C811.839 161.457 796.982 176.577 777.275 176.577Z" fill="currentColor"/>
148
+ <path d="M649.658 106.213H652.624C661.288 106.244 669.52 110.167 674.663 116.7C677.968 120.792 681.041 126.615 681.041 141.38V193.118H700.934V142.492C700.934 125.657 697.906 114.645 690.817 105.657C681.721 94.0581 668.006 87.4016 653.195 87.4016H649.056C634.26 87.4016 620.546 94.0581 611.449 105.657C604.36 114.63 601.333 125.657 601.333 142.492V193.118H621.225V141.38C621.225 126.599 624.299 120.777 627.604 116.684C632.762 110.151 640.994 106.244 649.658 106.213Z" fill="currentColor"/>
149
+ <path d="M452.743 163.913C452.743 143.712 433.716 136.098 415.105 131.326C403.862 128.453 395.908 125.858 395.908 118.445C395.908 110.321 403.954 104.653 415.491 104.653C423.538 104.653 439.013 108.097 447.229 112.576V93.5797C440.248 90.5835 423.337 87.4329 414.148 87.4329C395.769 87.4329 376 97.4871 376 119.557C376 134.832 388.85 142.322 399.63 145.921C403.259 147.125 407.012 148.083 410.626 149.025L410.703 149.04C422.58 152.083 432.835 154.708 432.835 164.361C432.835 171.049 426.21 178.153 413.916 178.153C405.931 178.153 389.267 174.817 378.564 167.651V187.234C388.803 192.099 405.313 195.373 414.364 195.373C432.974 195.358 452.743 184.331 452.743 163.913Z" fill="currentColor"/>
150
+ <path d="M982.051 107.541H985.017C993.604 107.572 1001.79 111.449 1006.89 117.951C1010.18 122.013 1013.22 127.789 1013.22 142.507V194.462H1033.54V143.619C1033.54 126.739 1030.5 115.681 1023.38 106.661C1014.24 95.0006 1000.46 88.3286 985.604 88.3286H981.465C961.402 88.3286 946.329 102.259 943.502 105.055L943.209 105.348L942.916 105.055C940.089 102.259 925.015 88.3286 904.953 88.3286H900.814C885.941 88.3286 872.165 95.0161 863.037 106.661C855.917 115.681 852.875 126.739 852.875 143.619V194.462H873.2V142.507C873.2 127.789 876.242 122.013 879.532 117.951C884.628 111.464 892.799 107.572 901.401 107.541H904.366C920.537 107.588 931.996 122.492 932.491 123.125L932.568 123.233V123.372V194.447H953.85V123.372C953.85 123.217 965.727 107.588 982.051 107.541Z" fill="currentColor"/>
151
+ <path d="M1165.52 193.35L1165.48 140.299C1165.21 125.58 1159.49 112.097 1149.36 102.352C1139.21 92.5911 1125.31 87.2165 1110.21 87.2165C1078.69 87.2165 1054.92 110.507 1054.92 141.395C1054.92 172.284 1078.69 195.574 1110.21 195.574C1123.44 195.574 1137.56 187.62 1143.75 176.67L1144.54 175.265V193.35H1165.52ZM1110.22 176.361C1090.64 176.361 1075.86 161.334 1075.86 141.395C1075.86 121.457 1090.63 106.429 1110.22 106.429C1129.64 106.429 1144.08 120.731 1144.56 140.438V142.353C1144.08 162.06 1129.64 176.361 1110.22 176.361Z" fill="currentColor"/>
152
+ <g clip-path="url(#wm_clip1)">
153
+ <g filter="url(#wm_filter0)">
154
+ <path d="M252.952 147.36C252.952 166.967 225.717 139.051 190.258 139.051C154.799 139.051 124.544 166.967 124.544 147.36C124.544 127.753 133.608 72.5811 190.258 72.5811C246.909 72.5811 252.952 127.753 252.952 147.36Z" fill="url(#wm_grad)"/>
155
+ </g>
156
+ <path d="M129.856 156.851C124.708 142.435 124.945 126.645 130.523 112.39C136.102 98.1359 146.645 86.3786 160.21 79.2861C173.775 72.1935 189.446 70.244 204.335 73.7968C219.224 77.3496 232.327 86.1653 241.228 98.6185C250.129 111.072 254.228 126.323 252.769 141.56C251.31 156.798 244.391 170.994 233.289 181.532C222.187 192.07 207.649 198.239 192.356 198.902C177.064 199.565 162.047 194.677 150.074 185.139" stroke="currentColor" stroke-width="18.1282"/>
157
+ <path d="M85.7543 185.564C99.3784 171.94 115.553 161.133 133.353 153.76C151.154 146.386 170.233 142.591 189.5 142.591C208.768 142.591 227.847 146.386 245.647 153.76C263.448 161.133 279.622 171.94 293.247 185.564" stroke="currentColor" stroke-width="19.5626"/>
158
+ </g>
159
+ </g>
160
+ <defs>
161
+ <filter id="wm_filter0" x="66.928" y="24.9334" width="243.639" height="196.992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
162
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
163
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
164
+ <feOffset dy="9.96812"/>
165
+ <feGaussianBlur stdDeviation="28.8079"/>
166
+ <feComposite in2="hardAlpha" operator="out"/>
167
+ <feColorMatrix type="matrix" values="0 0 0 0 0.856738 0 0 0 0 0.462638 0 0 0 0 0 0 0 0 0.8 0"/>
168
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1"/>
169
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1" result="shape"/>
170
+ </filter>
171
+ <linearGradient id="wm_grad" x1="154.002" y1="124.7" x2="241.622" y2="158.69" gradientUnits="userSpaceOnUse">
172
+ <stop stop-color="#FF6B00"/>
173
+ <stop offset="1" stop-color="#FFB800"/>
174
+ </linearGradient>
175
+ <clipPath id="wm_clip0"><rect width="1270" height="280" fill="white"/></clipPath>
176
+ <clipPath id="wm_clip1"><rect width="300" height="300" fill="white" transform="translate(40 -14)"/></clipPath>
177
+ </defs>
178
+ </svg>`;
179
+ // Topographic contour SVG paths (from TopographicalBackground component)
180
+ const TOPO_SVG = `<svg class="topo-bg" viewBox="0 0 2048 1365" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
181
+ <defs>
182
+ <filter id="orange-glow" x="-50%" y="-50%" width="200%" height="200%">
183
+ <feGaussianBlur stdDeviation="3" result="coloredBlur"/>
184
+ <feMerge><feMergeNode in="coloredBlur"/><feMergeNode in="SourceGraphic"/></feMerge>
185
+ </filter>
186
+ </defs>
187
+ <path transform="translate(300,-150) scale(-1,1)" d="m0 0h43l27 3 38 7 64 15 36 8 36 6 21 2 45 3 20 3 19 5 17 7 19 10v374l-14-2-13-1h-14l-24 3-18 5-18 8-21 11-16 9-14 6-14 4-6 1h-19l-20-4-21-7-23-10-13-7-9-8-5-8-5-17-4-14-7-13-7-9-11-11-13-9-16-8-16-6-16-4-16-3-13-1h-40l-26 1h-39l-21-2-19-4-17-6-16-8-11-7-14-11-13-13-10-13-10-17-8-19-5-21-2-20 1-20 3-18 8-24 8-16 9-13 9-11 14-14 13-10 24-16 21-12 27-14 24-11 23-9 24-8 28-7 26-4z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="0.9"/>
188
+ <path transform="translate(0)" d="m0 0h885l-4 3-16 8-13 9-8 9-8 16-7 25-6 11-9 9-14 11-13 11-33 27-12 11-7 7-7 11-4 10-1 4v18l4 10 7 8 14 7 14 3 30 4 12 4 11 7 10 9 14 14 7 8 7 7 14 10 2 1 1 22 4 12 4 6 8 5 3 1h15l15-5 15-6 12-3h15l13 4 8 6 6 8 3 7v12l-9 20-1 4v12l4 8 8 10 2 6v16l-5 24v18l5 10 8 6 13 5 14 3 33 4 16 4 14 7 10 9 7 10 4 13 1 7v10l-3 17-6 16-9 16-9 10-14 7-31 8-12 5-9 6-7 8-10 19-7 8-13 9-19 11-12 9-7 7-9 14-12 25-9 19-7 11-11 12-15 12-17 12-11 9-12 12-7 11-5 12-1 4v18l5 25v16l-4 26v16l3 13 5 8 8 5 16 7 10 8 11 14 16 24 11 12 9 6 15 5 25 5 9 5 5 6 3 9v8l-4 13-7 9-9 9-15 11-25 16-25 15-29 16-34 17-32 14-36 14-36 12h-9l-5-5-8-18-8-9-14-7-10-2h-19l-32 6-8 1h-14l-20-4-15-6-15-8-12-8-13-10-11-9-15-13-10-9-14-11-11-9-20-14-26-15-22-11-23-9-36-12-6-4-5-6-2-6-1-32-3-12-6-11-9-10-9-7-11-5-9-2-38-2-19-3-43-10-19-3h-28l-15 4-15 8-17 13-7 3-10 1-17-5-33-14-14-6z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="1.0"/>
189
+ <path transform="translate(1006)" d="m0 0h550l-8 16-12 21-8 13-10 18-9 21-5 17-2 10v28l3 11 7 17 11 18 16 24 8 15 5 15 2 12v17l-2 14-6 18-10 18-12 13-10 9-14 8-14 5-13 3-17 2h-26l-39-2h-24l-18 2-21 5-21 8-20 10-22 13-23 15-16 10-16 9-17 7-18 5-14 2h-29l-19-3-18-6-11-7-7-7-6-10-6-20-4-33-3-19-5-15-9-15-5-6-2-1v-2h-2v-2l-4-2-14-9-18-7-41-10-16-5-16-8-10-9-6-7-12-23-9-10-11-7-14-6-24-9-12-7-9-8-6-12v-11l4-8 7-7 15-10 24-14 11-9 7-8 11-21 6-13 6-11 11-12 8-7 15-9 20-8z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="0.8"/>
190
+ <path transform="translate(1663,693)" d="m0 0h43l27 3 38 7 64 15 36 8 36 6 21 2 45 3 20 3 19 5 17 7 19 10v374l-14-2-13-1h-14l-24 3-18 5-18 8-21 11-16 9-14 6-14 4-6 1h-19l-20-4-21-7-23-10-13-7-9-8-5-8-5-17-4-14-7-13-7-9-11-11-13-9-16-8-16-6-16-4-16-3-13-1h-40l-26 1h-39l-21-2-19-4-17-6-16-8-11-7-14-11-13-13-10-13-10-17-8-19-5-21-2-20 1-20 3-18 8-24 8-16 9-13 9-11 14-14 13-10 24-16 21-12 27-14 24-11 23-9 24-8 28-7 26-4z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="0.9"/>
191
+ <path transform="translate(149,1032)" d="m0 0h38l15 3 15 5 13 7 10 8 14 14 9 12 12 17 12 16 12 13 12 9 17 10 28 12 16 6 15 7 17 9 17 12 11 9 14 12 12 11 8 7 13 11 18 13 14 8 15 6 13 3h27l17-2h22l14 3 16 6 19 9 16 8 14 6 18 5 12 2 11 1h20l20-2 25-5 20-6 22-8 22-10 42-23 28-17 29-17 18-10 25-13 26-11 25-8 23-5 23-3h29l21 3 21 6 18 8 11 7 12 9 18 18 12 17 9 16 8 16 11 27 22 66h-1285v-327l12 3 16 3 16 1 24-1 29-4 36-6z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="0.8"/>
192
+ <path transform="translate(2e3 256)" d="m0 0h11l12 3 17 9 11 9v376l-33-11-29-6-15-2-14-1-65-2-22-2-25-5-40-12-28-6-33-4-18-1h-55l-53 2-29 2-29 4-23 5-29 9-32 13-35 17-33 17-19 10-16 8-7 3-10 1-8-3-6-4-8-8-7-8-7-6-9-4h-22l-7-3-7-6-9-14-6-16-2-11v-23l3-16 6-17 6-11 8-12 9-10 7-8 10-9 18-13 13-8 18-10 22-10 27-10 34-9 30-5 42-5 25-5 28-8 18-4 24-2 24 1 33 4 42 6 21 2h42l29-3 23-4 26-7 26-9 15-8 10-9 6-11 2-8 1-10 1-31 2-10 7-14 8-8 10-6 10-3 17-2 6-5 6-11 7-6 8-4z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="1.0"/>
193
+ <path transform="translate(1135,686)" d="m0 0h17l16 5 9 6v2l4 2 8 10 13 25 6 13 7 13 7 9 1 3h2v2l4 2 11 6 9 2h33l9 3 7 8 4 8 5 5 11 8 9 7 6 9 3 9 1 6v22l-2 21v13l3 19 8 26 10 30 3 12 2 15v12l-3 17-6 16-11 19-10 13-9 11-12 12-13 10-15 8-13 4-5 1h-27l-26-5-34-9-14-3-8-1-61-1-15-3-12-5-9-6-9-9-9-15-9-17-9-12-11-10-15-10-28-15-21-11-16-11-10-9-9-10-8-14-6-13-5-16-2-12 1-14 4-11 7-11 10-10 16-12 17-12 14-12 10-10 9-11 11-14 14-19 12-16 9-11 11-12 11-11 16-12 15-9 16-8 14-6 19-5z" fill="none" stroke="rgb(220,110,20)" stroke-width="2.5" opacity="1.0"/>
194
+ </svg>`;
195
+ function pageShell(content) {
196
+ const faviconUri = `data:image/svg+xml,${encodeURIComponent(FAVICON_SVG)}`;
197
+ return `<!DOCTYPE html>
198
+ <html lang="en">
199
+ <head>
200
+ <meta charset="UTF-8">
201
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
202
+ <title>Sonoma</title>
203
+ <link rel="icon" type="image/svg+xml" href="${faviconUri}">
204
+ <style>
205
+ :root {
206
+ --bg: #0a0a0a;
207
+ --fg: #f5f5f5;
208
+ --card-bg: #171717;
209
+ --card-border: rgba(255,255,255,0.1);
210
+ --muted: #a3a3a3;
211
+ --footer-color: #525252;
212
+ --footer-hover: #a3a3a3;
213
+ --stroke-color: #f5f5f5;
214
+ --topo-opacity: 0.15;
215
+ }
216
+ @media (prefers-color-scheme: light) {
217
+ :root {
218
+ --bg: #ffffff;
219
+ --fg: #111111;
220
+ --card-bg: #f5f5f5;
221
+ --card-border: rgba(0,0,0,0.08);
222
+ --muted: #666666;
223
+ --footer-color: #999999;
224
+ --footer-hover: #555555;
225
+ --stroke-color: #111111;
226
+ --topo-opacity: 0.08;
227
+ }
228
+ }
229
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
230
+ * { cursor: default !important; user-select: none; -webkit-user-select: none; }
231
+ body {
232
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
233
+ background: var(--bg);
234
+ min-height: 100vh;
235
+ display: flex;
236
+ flex-direction: column;
237
+ align-items: center;
238
+ color: var(--fg);
239
+ position: relative;
240
+ overflow: hidden;
241
+ }
242
+ .topo-bg {
243
+ position: absolute;
244
+ inset: 0;
245
+ width: 100%;
246
+ height: 100%;
247
+ pointer-events: none;
248
+ opacity: var(--topo-opacity);
249
+ }
250
+ .content {
251
+ flex: 1;
252
+ position: relative;
253
+ z-index: 10;
254
+ display: flex;
255
+ flex-direction: column;
256
+ align-items: center;
257
+ justify-content: center;
258
+ width: 100%;
259
+ max-width: 480px;
260
+ padding: 0 24px;
261
+ }
262
+ .card {
263
+ background: var(--card-bg);
264
+ border: 1px solid var(--card-border);
265
+ border-radius: 16px;
266
+ width: 100%;
267
+ text-align: center;
268
+ overflow: hidden;
269
+ }
270
+ .card-header {
271
+ padding: 48px 32px 24px;
272
+ }
273
+ .logo-container {
274
+ display: flex;
275
+ justify-content: center;
276
+ margin-bottom: 32px;
277
+ }
278
+ .logo-box {
279
+ width: 96px;
280
+ height: 96px;
281
+ border-radius: 20px;
282
+ border: 2px solid var(--card-border);
283
+ background: var(--bg);
284
+ display: flex;
285
+ align-items: center;
286
+ justify-content: center;
287
+ padding: 16px;
288
+ color: var(--stroke-color);
289
+ }
290
+ .logo-box svg { width: 100%; height: 100%; }
291
+ .title {
292
+ font-size: 22px;
293
+ font-weight: 600;
294
+ margin-bottom: 10px;
295
+ color: var(--fg);
296
+ }
297
+ .description {
298
+ font-size: 14px;
299
+ color: var(--muted);
300
+ line-height: 1.6;
301
+ }
302
+ .description strong { color: var(--fg); font-weight: 500; }
303
+ .card-footer {
304
+ padding: 8px 32px 40px;
305
+ }
306
+ .btn {
307
+ display: inline-block;
308
+ padding: 10px 28px;
309
+ border-radius: 8px;
310
+ font-size: 14px;
311
+ font-weight: 500;
312
+ text-decoration: none;
313
+ border: none;
314
+ transition: background 0.15s, border-color 0.15s;
315
+ }
316
+ .btn-cta {
317
+ background: rgba(59, 130, 246, 0.1);
318
+ color: #60a5fa;
319
+ border: 1px solid rgba(59, 130, 246, 0.2);
320
+ font-weight: 500;
321
+ }
322
+ @media (prefers-color-scheme: light) {
323
+ .btn-cta { color: #2563eb; }
324
+ }
325
+ .btn-cta:hover {
326
+ background: rgba(59, 130, 246, 0.2);
327
+ border-color: rgba(59, 130, 246, 0.3);
328
+ }
329
+ .wordmark {
330
+ position: relative;
331
+ z-index: 10;
332
+ padding: 32px 0 16px;
333
+ display: flex;
334
+ justify-content: center;
335
+ color: var(--stroke-color);
336
+ }
337
+ .wordmark svg { color: inherit; }
338
+ .footer {
339
+ padding: 24px 0 32px;
340
+ font-size: 12px;
341
+ color: var(--footer-color);
342
+ position: relative;
343
+ z-index: 10;
344
+ display: flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+ gap: 24px;
348
+ flex-wrap: wrap;
349
+ }
350
+ .footer a {
351
+ color: var(--footer-color);
352
+ text-decoration: none;
353
+ transition: color 0.15s;
354
+ }
355
+ .footer a:hover {
356
+ color: var(--footer-hover);
357
+ }
358
+ .check-icon {
359
+ display: flex;
360
+ align-items: center;
361
+ justify-content: center;
362
+ margin-bottom: 20px;
363
+ }
364
+ .error-icon {
365
+ display: flex;
366
+ align-items: center;
367
+ justify-content: center;
368
+ margin-bottom: 20px;
369
+ }
370
+ </style>
371
+ </head>
372
+ <body>
373
+ ${TOPO_SVG}
374
+ <div class="wordmark">${SONOMA_WORDMARK}</div>
375
+ <div class="content">
376
+ ${content}
377
+ </div>
378
+ <footer class="footer">
379
+ <span>&copy; 2026 Sonoma Security, Inc.</span>
380
+ <a href="https://sonoma.dev/privacy-policy" target="_blank" rel="noopener noreferrer">Privacy Policy</a>
381
+ <a href="https://sonoma.dev/contact" target="_blank" rel="noopener noreferrer">Contact</a>
382
+ </footer>
383
+ </body>
384
+ </html>`;
385
+ }
386
+ function renderSuccessPage(serverName) {
387
+ const displayName = serverName ? capitalize(escapeHtml(serverName)) : null;
388
+ const connectedTo = displayName
389
+ ? `Connected to <strong>${displayName}</strong> via <strong>Sonoma MCP Gateway</strong>.`
390
+ : `<strong>Sonoma MCP Gateway</strong> has been connected to your account.`;
391
+ return pageShell(`
392
+ <div class="card">
393
+ <div class="card-header">
394
+ <div class="logo-container">
395
+ <div class="logo-box">${SONOMA_LOGO}</div>
396
+ </div>
397
+ <div class="check-icon">
398
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
399
+ <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
400
+ <polyline points="22 4 12 14.01 9 11.01"/>
401
+ </svg>
402
+ </div>
403
+ <div class="title">Authentication Successful</div>
404
+ <p class="description">${connectedTo}</p>
405
+ </div>
406
+ <div class="card-footer">
407
+ <button class="btn btn-cta" onclick="window.close()">You can safely close this tab</button>
408
+ </div>
409
+ </div>`);
410
+ }
411
+ function renderErrorPage(message) {
412
+ return pageShell(`
413
+ <div class="card">
414
+ <div class="card-header">
415
+ <div class="logo-container">
416
+ <div class="logo-box">${SONOMA_LOGO}</div>
417
+ </div>
418
+ <div class="error-icon">
419
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
420
+ <circle cx="12" cy="12" r="10"/>
421
+ <line x1="15" y1="9" x2="9" y2="15"/>
422
+ <line x1="9" y1="9" x2="15" y2="15"/>
423
+ </svg>
424
+ </div>
425
+ <div class="title">Authentication Failed</div>
426
+ <p class="description">${message}</p>
427
+ </div>
428
+ <div class="card-footer">
429
+ <button class="btn btn-cta" onclick="window.close()">Close this tab</button>
430
+ </div>
431
+ </div>`);
432
+ }
155
433
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/auth/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/auth/server.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/auth/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AAYzG,MAAM,WAAW,iBAAiB;IAEhC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAG/B,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgFD;;GAEG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAc1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAOpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,GAAG,SAAS,CAY/E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAYpG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,2BAA2B,GAAG,SAAS,CAUrG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,SAAQ,GAAG,OAAO,CAMlF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAEjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/auth/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AAKzG,MAAM,WAAW,iBAAiB;IAEhC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAG/B,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAc1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAOpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,GAAG,SAAS,CAY/E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAYpG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,2BAA2B,GAAG,SAAS,CAUrG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,SAAQ,GAAG,OAAO,CAMlF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAEjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
@@ -5,80 +5,10 @@
5
5
  * The encryption key is derived from a machine-specific identifier to prevent
6
6
  * tokens from being copied between machines.
7
7
  */
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
9
- import { homedir, hostname } from "node:os";
8
+ import { existsSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
10
9
  import { join } from "node:path";
11
- import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "node:crypto";
12
- const SONOMA_DIR = join(homedir(), ".sonoma");
10
+ import { SONOMA_DIR, ensureSonomaDir, getDeviceId, encrypt, decrypt } from "./crypto.js";
13
11
  const CREDENTIALS_PATH = join(SONOMA_DIR, "gateway-credentials.json");
14
- const DEVICE_ID_PATH = join(SONOMA_DIR, "device-id");
15
- // Encryption settings
16
- const ALGORITHM = "aes-256-gcm";
17
- const KEY_LENGTH = 32;
18
- const IV_LENGTH = 16;
19
- const SALT_LENGTH = 32;
20
- /**
21
- * Get or create a stable device ID for this machine
22
- */
23
- function getDeviceId() {
24
- ensureSonomaDir();
25
- if (existsSync(DEVICE_ID_PATH)) {
26
- return readFileSync(DEVICE_ID_PATH, "utf-8").trim();
27
- }
28
- // Generate new device ID: dev_{random_hex}
29
- const id = `dev_${randomBytes(16).toString("hex")}`;
30
- writeFileSync(DEVICE_ID_PATH, id, { mode: 0o600 });
31
- return id;
32
- }
33
- /**
34
- * Derive an encryption key from machine-specific data
35
- */
36
- function deriveKey(salt) {
37
- // Use device ID and hostname as key material
38
- const deviceId = getDeviceId();
39
- const keyMaterial = `${deviceId}:${hostname()}:sonoma-mcp-gateway`;
40
- return scryptSync(keyMaterial, salt, KEY_LENGTH);
41
- }
42
- /**
43
- * Encrypt data using AES-256-GCM
44
- */
45
- function encrypt(data) {
46
- const salt = randomBytes(SALT_LENGTH);
47
- const key = deriveKey(salt);
48
- const iv = randomBytes(IV_LENGTH);
49
- const cipher = createCipheriv(ALGORITHM, key, iv);
50
- let encrypted = cipher.update(data, "utf8", "hex");
51
- encrypted += cipher.final("hex");
52
- const authTag = cipher.getAuthTag();
53
- // Format: salt:iv:authTag:encrypted (all hex)
54
- return [salt.toString("hex"), iv.toString("hex"), authTag.toString("hex"), encrypted].join(":");
55
- }
56
- /**
57
- * Decrypt data using AES-256-GCM
58
- */
59
- function decrypt(encryptedData) {
60
- const [saltHex, ivHex, authTagHex, encrypted] = encryptedData.split(":");
61
- if (!saltHex || !ivHex || !authTagHex || !encrypted) {
62
- throw new Error("Invalid encrypted data format");
63
- }
64
- const salt = Buffer.from(saltHex, "hex");
65
- const iv = Buffer.from(ivHex, "hex");
66
- const authTag = Buffer.from(authTagHex, "hex");
67
- const key = deriveKey(salt);
68
- const decipher = createDecipheriv(ALGORITHM, key, iv);
69
- decipher.setAuthTag(authTag);
70
- let decrypted = decipher.update(encrypted, "hex", "utf8");
71
- decrypted += decipher.final("utf8");
72
- return decrypted;
73
- }
74
- /**
75
- * Ensure the ~/.sonoma directory exists
76
- */
77
- function ensureSonomaDir() {
78
- if (!existsSync(SONOMA_DIR)) {
79
- mkdirSync(SONOMA_DIR, { recursive: true, mode: 0o700 });
80
- }
81
- }
82
12
  /**
83
13
  * Load stored credentials from disk
84
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/auth/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/auth/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * OAuthClientProvider implementation for upstream MCP servers.
3
+ *
4
+ * Implements the MCP SDK's OAuthClientProvider interface so the SDK's
5
+ * `auth()` orchestrator can handle the full OAuth flow (discovery, DCR,
6
+ * PKCE, authorization, token exchange, refresh) for any upstream server.
7
+ *
8
+ * Design: `redirectToAuthorization()` captures the URL instead of opening
9
+ * the browser directly. The caller (gateway) controls when/how to open it,
10
+ * enabling serial auth flows across multiple servers.
11
+ */
12
+ import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
13
+ import type { OAuthClientMetadata, OAuthClientInformationMixed, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
14
+ import type { UpstreamTokenStore } from "./upstream-token-store.js";
15
+ export interface UpstreamOAuthProviderOptions {
16
+ serverUrl: string;
17
+ store: UpstreamTokenStore;
18
+ callbackPort: number;
19
+ debug?: boolean;
20
+ }
21
+ export declare class UpstreamOAuthProvider implements OAuthClientProvider {
22
+ private readonly serverUrl;
23
+ private readonly store;
24
+ private readonly callbackPort;
25
+ private readonly _debug;
26
+ /** Captured authorization URL after `redirectToAuthorization` is called */
27
+ pendingAuthorizationUrl: URL | undefined;
28
+ constructor(options: UpstreamOAuthProviderOptions);
29
+ get redirectUrl(): string;
30
+ get clientMetadata(): OAuthClientMetadata;
31
+ clientInformation(): Promise<OAuthClientInformationMixed | undefined>;
32
+ saveClientInformation(info: OAuthClientInformationMixed): Promise<void>;
33
+ tokens(): Promise<OAuthTokens | undefined>;
34
+ saveTokens(tokens: OAuthTokens): Promise<void>;
35
+ redirectToAuthorization(authorizationUrl: URL): Promise<void>;
36
+ saveCodeVerifier(verifier: string): Promise<void>;
37
+ codeVerifier(): Promise<string>;
38
+ invalidateCredentials(scope: "all" | "client" | "tokens" | "verifier"): Promise<void>;
39
+ private log;
40
+ }
41
+ //# sourceMappingURL=upstream-oauth-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream-oauth-provider.d.ts","sourceRoot":"","sources":["../../src/auth/upstream-oauth-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,WAAW,EACZ,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAIpE,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAEjC,2EAA2E;IAC3E,uBAAuB,EAAE,GAAG,GAAG,SAAS,CAAC;gBAE7B,OAAO,EAAE,4BAA4B;IAOjD,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,cAAc,IAAI,mBAAmB,CAQxC;IAEK,iBAAiB,IAAI,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAIrE,qBAAqB,CAAC,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,MAAM,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI1C,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,uBAAuB,CAAC,gBAAgB,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ/B,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3F,OAAO,CAAC,GAAG;CAMZ"}