@burdenoff/mcp-libs 2026.511.1

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 (174) hide show
  1. package/README.md +76 -0
  2. package/dist/chunk-4GBVJ4OY.js +847 -0
  3. package/dist/chunk-4GBVJ4OY.js.map +1 -0
  4. package/dist/chunk-H2OYWLOA.js +919 -0
  5. package/dist/chunk-H2OYWLOA.js.map +1 -0
  6. package/dist/chunk-JFEQYSWM.js +174 -0
  7. package/dist/chunk-JFEQYSWM.js.map +1 -0
  8. package/dist/chunk-WWFVD7BO.js +273 -0
  9. package/dist/chunk-WWFVD7BO.js.map +1 -0
  10. package/dist/context-1jV4NsLv.d.cts +138 -0
  11. package/dist/context-1jV4NsLv.d.ts +138 -0
  12. package/dist/core/index.cjs +953 -0
  13. package/dist/core/index.cjs.map +1 -0
  14. package/dist/core/index.d.cts +59 -0
  15. package/dist/core/index.d.ts +59 -0
  16. package/dist/core/index.js +3 -0
  17. package/dist/core/index.js.map +1 -0
  18. package/dist/http-BP4c721D.d.cts +22 -0
  19. package/dist/http-DXTeCD5r.d.ts +22 -0
  20. package/dist/index.cjs +1013 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +7 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.js +4 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/module-DBcfA-i3.d.ts +67 -0
  27. package/dist/module-DFQBZNK6.d.cts +67 -0
  28. package/dist/modules/auth/index.cjs +533 -0
  29. package/dist/modules/auth/index.cjs.map +1 -0
  30. package/dist/modules/auth/index.d.cts +51 -0
  31. package/dist/modules/auth/index.d.ts +51 -0
  32. package/dist/modules/auth/index.js +159 -0
  33. package/dist/modules/auth/index.js.map +1 -0
  34. package/dist/modules/billing/index.cjs +655 -0
  35. package/dist/modules/billing/index.cjs.map +1 -0
  36. package/dist/modules/billing/index.d.cts +8 -0
  37. package/dist/modules/billing/index.d.ts +8 -0
  38. package/dist/modules/billing/index.js +606 -0
  39. package/dist/modules/billing/index.js.map +1 -0
  40. package/dist/modules/channels/index.cjs +443 -0
  41. package/dist/modules/channels/index.cjs.map +1 -0
  42. package/dist/modules/channels/index.d.cts +8 -0
  43. package/dist/modules/channels/index.d.ts +8 -0
  44. package/dist/modules/channels/index.js +394 -0
  45. package/dist/modules/channels/index.js.map +1 -0
  46. package/dist/modules/conversations/index.cjs +288 -0
  47. package/dist/modules/conversations/index.cjs.map +1 -0
  48. package/dist/modules/conversations/index.d.cts +8 -0
  49. package/dist/modules/conversations/index.d.ts +8 -0
  50. package/dist/modules/conversations/index.js +239 -0
  51. package/dist/modules/conversations/index.js.map +1 -0
  52. package/dist/modules/devportal/index.cjs +796 -0
  53. package/dist/modules/devportal/index.cjs.map +1 -0
  54. package/dist/modules/devportal/index.d.cts +8 -0
  55. package/dist/modules/devportal/index.d.ts +8 -0
  56. package/dist/modules/devportal/index.js +747 -0
  57. package/dist/modules/devportal/index.js.map +1 -0
  58. package/dist/modules/export/index.cjs +333 -0
  59. package/dist/modules/export/index.cjs.map +1 -0
  60. package/dist/modules/export/index.d.cts +8 -0
  61. package/dist/modules/export/index.d.ts +8 -0
  62. package/dist/modules/export/index.js +284 -0
  63. package/dist/modules/export/index.js.map +1 -0
  64. package/dist/modules/files/index.cjs +278 -0
  65. package/dist/modules/files/index.cjs.map +1 -0
  66. package/dist/modules/files/index.d.cts +8 -0
  67. package/dist/modules/files/index.d.ts +8 -0
  68. package/dist/modules/files/index.js +229 -0
  69. package/dist/modules/files/index.js.map +1 -0
  70. package/dist/modules/groups/index.cjs +451 -0
  71. package/dist/modules/groups/index.cjs.map +1 -0
  72. package/dist/modules/groups/index.d.cts +8 -0
  73. package/dist/modules/groups/index.d.ts +8 -0
  74. package/dist/modules/groups/index.js +402 -0
  75. package/dist/modules/groups/index.js.map +1 -0
  76. package/dist/modules/health/index.cjs +159 -0
  77. package/dist/modules/health/index.cjs.map +1 -0
  78. package/dist/modules/health/index.d.cts +8 -0
  79. package/dist/modules/health/index.d.ts +8 -0
  80. package/dist/modules/health/index.js +36 -0
  81. package/dist/modules/health/index.js.map +1 -0
  82. package/dist/modules/integrations/index.cjs +316 -0
  83. package/dist/modules/integrations/index.cjs.map +1 -0
  84. package/dist/modules/integrations/index.d.cts +8 -0
  85. package/dist/modules/integrations/index.d.ts +8 -0
  86. package/dist/modules/integrations/index.js +267 -0
  87. package/dist/modules/integrations/index.js.map +1 -0
  88. package/dist/modules/notifications/index.cjs +222 -0
  89. package/dist/modules/notifications/index.cjs.map +1 -0
  90. package/dist/modules/notifications/index.d.cts +8 -0
  91. package/dist/modules/notifications/index.d.ts +8 -0
  92. package/dist/modules/notifications/index.js +173 -0
  93. package/dist/modules/notifications/index.js.map +1 -0
  94. package/dist/modules/organizations/index.cjs +267 -0
  95. package/dist/modules/organizations/index.cjs.map +1 -0
  96. package/dist/modules/organizations/index.d.cts +8 -0
  97. package/dist/modules/organizations/index.d.ts +8 -0
  98. package/dist/modules/organizations/index.js +218 -0
  99. package/dist/modules/organizations/index.js.map +1 -0
  100. package/dist/modules/products/index.cjs +736 -0
  101. package/dist/modules/products/index.cjs.map +1 -0
  102. package/dist/modules/products/index.d.cts +8 -0
  103. package/dist/modules/products/index.d.ts +8 -0
  104. package/dist/modules/products/index.js +687 -0
  105. package/dist/modules/products/index.js.map +1 -0
  106. package/dist/modules/rbac/index.cjs +378 -0
  107. package/dist/modules/rbac/index.cjs.map +1 -0
  108. package/dist/modules/rbac/index.d.cts +8 -0
  109. package/dist/modules/rbac/index.d.ts +8 -0
  110. package/dist/modules/rbac/index.js +329 -0
  111. package/dist/modules/rbac/index.js.map +1 -0
  112. package/dist/modules/sandbox/index.cjs +318 -0
  113. package/dist/modules/sandbox/index.cjs.map +1 -0
  114. package/dist/modules/sandbox/index.d.cts +8 -0
  115. package/dist/modules/sandbox/index.d.ts +8 -0
  116. package/dist/modules/sandbox/index.js +225 -0
  117. package/dist/modules/sandbox/index.js.map +1 -0
  118. package/dist/modules/scheduler/index.cjs +267 -0
  119. package/dist/modules/scheduler/index.cjs.map +1 -0
  120. package/dist/modules/scheduler/index.d.cts +8 -0
  121. package/dist/modules/scheduler/index.d.ts +8 -0
  122. package/dist/modules/scheduler/index.js +218 -0
  123. package/dist/modules/scheduler/index.js.map +1 -0
  124. package/dist/modules/security/index.cjs +529 -0
  125. package/dist/modules/security/index.cjs.map +1 -0
  126. package/dist/modules/security/index.d.cts +8 -0
  127. package/dist/modules/security/index.d.ts +8 -0
  128. package/dist/modules/security/index.js +480 -0
  129. package/dist/modules/security/index.js.map +1 -0
  130. package/dist/modules/store/index.cjs +450 -0
  131. package/dist/modules/store/index.cjs.map +1 -0
  132. package/dist/modules/store/index.d.cts +8 -0
  133. package/dist/modules/store/index.d.ts +8 -0
  134. package/dist/modules/store/index.js +401 -0
  135. package/dist/modules/store/index.js.map +1 -0
  136. package/dist/modules/support/index.cjs +285 -0
  137. package/dist/modules/support/index.cjs.map +1 -0
  138. package/dist/modules/support/index.d.cts +8 -0
  139. package/dist/modules/support/index.d.ts +8 -0
  140. package/dist/modules/support/index.js +236 -0
  141. package/dist/modules/support/index.js.map +1 -0
  142. package/dist/modules/tags/index.cjs +421 -0
  143. package/dist/modules/tags/index.cjs.map +1 -0
  144. package/dist/modules/tags/index.d.cts +8 -0
  145. package/dist/modules/tags/index.d.ts +8 -0
  146. package/dist/modules/tags/index.js +372 -0
  147. package/dist/modules/tags/index.js.map +1 -0
  148. package/dist/modules/tours/index.cjs +225 -0
  149. package/dist/modules/tours/index.cjs.map +1 -0
  150. package/dist/modules/tours/index.d.cts +8 -0
  151. package/dist/modules/tours/index.d.ts +8 -0
  152. package/dist/modules/tours/index.js +176 -0
  153. package/dist/modules/tours/index.js.map +1 -0
  154. package/dist/modules/vibecontrols/index.cjs +5551 -0
  155. package/dist/modules/vibecontrols/index.cjs.map +1 -0
  156. package/dist/modules/vibecontrols/index.d.cts +8 -0
  157. package/dist/modules/vibecontrols/index.d.ts +8 -0
  158. package/dist/modules/vibecontrols/index.js +4380 -0
  159. package/dist/modules/vibecontrols/index.js.map +1 -0
  160. package/dist/modules/workspaces/index.cjs +552 -0
  161. package/dist/modules/workspaces/index.cjs.map +1 -0
  162. package/dist/modules/workspaces/index.d.cts +8 -0
  163. package/dist/modules/workspaces/index.d.ts +8 -0
  164. package/dist/modules/workspaces/index.js +503 -0
  165. package/dist/modules/workspaces/index.js.map +1 -0
  166. package/dist/tool-name-CQf_IqAj.d.cts +47 -0
  167. package/dist/tool-name-DlnrBsZ6.d.ts +47 -0
  168. package/dist/transports/index.cjs +183 -0
  169. package/dist/transports/index.cjs.map +1 -0
  170. package/dist/transports/index.d.cts +13 -0
  171. package/dist/transports/index.d.ts +13 -0
  172. package/dist/transports/index.js +3 -0
  173. package/dist/transports/index.js.map +1 -0
  174. package/package.json +125 -0
@@ -0,0 +1,273 @@
1
+ import { fetchWorkspaces, issueWorkspaceToken } from './chunk-H2OYWLOA.js';
2
+
3
+ // src/modules/auth/legacy-auth.ts
4
+ var helpers = /* @__PURE__ */ new WeakMap();
5
+ function getAuth(ctx) {
6
+ const cached = helpers.get(ctx);
7
+ if (cached) return cached;
8
+ const helper = createAuthHelper(ctx);
9
+ helpers.set(ctx, helper);
10
+ return helper;
11
+ }
12
+ function createAuthHelper(ctx) {
13
+ let pending = null;
14
+ let onTokensChanged = null;
15
+ let refreshInProgress = null;
16
+ function notify() {
17
+ onTokensChanged?.();
18
+ }
19
+ async function startLogin() {
20
+ const { oidcIssuer, clientId } = ctx.config.resolveOIDC();
21
+ const deviceCodeUrl = `${oidcIssuer}/oidc/device/code`;
22
+ const tokenUrl = `${oidcIssuer}/oauth/device/token`;
23
+ const response = await fetch(deviceCodeUrl, {
24
+ method: "POST",
25
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
26
+ body: new URLSearchParams({
27
+ client_id: clientId,
28
+ scope: "openid profile email offline_access"
29
+ }).toString()
30
+ });
31
+ if (!response.ok) {
32
+ const text = await response.text().catch(() => "Unknown error");
33
+ throw new Error(`Device code request failed (${response.status}): ${text}`);
34
+ }
35
+ const data = await response.json();
36
+ const deviceCode = data["device_code"];
37
+ const userCode = data["user_code"];
38
+ const verificationUri = data["verification_uri"];
39
+ const verificationUriComplete = data["verification_uri_complete"] ?? null;
40
+ const expiresIn = data["expires_in"] ?? 900;
41
+ const interval = data["interval"] ?? 5;
42
+ pending = {
43
+ deviceCode,
44
+ userCode,
45
+ verificationUri,
46
+ verificationUriComplete,
47
+ expiresAt: Date.now() + expiresIn * 1e3,
48
+ interval,
49
+ clientId,
50
+ tokenUrl
51
+ };
52
+ return {
53
+ status: "device_code_issued",
54
+ verificationUri,
55
+ verificationUriComplete,
56
+ userCode,
57
+ expiresIn,
58
+ message: `Open ${verificationUriComplete ?? verificationUri} in a browser and enter code: ${userCode}. Then call ${ctx.productName}_auth_complete to finish authentication.`
59
+ };
60
+ }
61
+ async function completeLogin() {
62
+ if (!pending) {
63
+ throw new Error(
64
+ `No pending login flow. Call ${ctx.productName}_auth_login first to start the device code flow.`
65
+ );
66
+ }
67
+ const p = pending;
68
+ if (Date.now() >= p.expiresAt) {
69
+ pending = null;
70
+ return {
71
+ status: "expired",
72
+ message: `Device code has expired. Call ${ctx.productName}_auth_login again to get a new code.`
73
+ };
74
+ }
75
+ const response = await fetch(p.tokenUrl, {
76
+ method: "POST",
77
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
78
+ body: new URLSearchParams({
79
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
80
+ device_code: p.deviceCode,
81
+ client_id: p.clientId
82
+ }).toString()
83
+ });
84
+ const data = await response.json();
85
+ if (response.ok && data["access_token"]) {
86
+ pending = null;
87
+ const expiresIn = data["expires_in"] ?? 3600;
88
+ const auth = ctx.auth.read() ?? { accessToken: "", refreshToken: "" };
89
+ ctx.auth.write({
90
+ ...auth,
91
+ accessToken: data["access_token"],
92
+ refreshToken: data["refresh_token"] ?? "",
93
+ expiresAt: Date.now() + expiresIn * 1e3,
94
+ authMethod: "device_code"
95
+ });
96
+ ctx.gql.reset();
97
+ return await handlePostLogin();
98
+ }
99
+ const errorCode = data["error"];
100
+ if (errorCode === "authorization_pending") {
101
+ return {
102
+ status: "pending",
103
+ message: `Still waiting for user to authorize. Open ${p.verificationUriComplete ?? p.verificationUri} and enter code: ${p.userCode}. Then call ${ctx.productName}_auth_complete again.`
104
+ };
105
+ } else if (errorCode === "slow_down") {
106
+ p.interval += 5;
107
+ return {
108
+ status: "pending",
109
+ message: `Authorization server asked to slow down. Wait a moment, then call ${ctx.productName}_auth_complete again.`
110
+ };
111
+ } else if (errorCode === "expired_token") {
112
+ pending = null;
113
+ return {
114
+ status: "expired",
115
+ message: `Device code has expired. Call ${ctx.productName}_auth_login again.`
116
+ };
117
+ } else if (errorCode === "access_denied") {
118
+ pending = null;
119
+ throw new Error("Authorization was denied by the user.");
120
+ } else {
121
+ pending = null;
122
+ throw new Error(
123
+ `Device code error: ${data["error_description"] ?? errorCode ?? "Unknown"}`
124
+ );
125
+ }
126
+ }
127
+ async function handlePostLogin() {
128
+ try {
129
+ const workspaces = await listWorkspaces();
130
+ if (workspaces.length === 0) {
131
+ notify();
132
+ ctx.logger.info("Device code login successful (no workspaces found)");
133
+ return {
134
+ status: "authenticated",
135
+ message: `Authentication successful. No workspaces found \u2014 use ${ctx.productName}_auth_select_workspace when one is available.`
136
+ };
137
+ }
138
+ if (workspaces.length === 1) {
139
+ const ws = workspaces[0];
140
+ if (!ws)
141
+ throw new Error("Unexpected: workspaces.length === 1 but workspaces[0] is undefined");
142
+ await issueAndStoreWorkspaceToken(ws.id, ws.organizationId);
143
+ ctx.logger.info("Device code login successful", {
144
+ workspaceId: ws.id,
145
+ workspaceName: ws.name
146
+ });
147
+ return {
148
+ status: "authenticated",
149
+ message: `Authentication successful. Workspace "${ws.name}" selected automatically.`
150
+ };
151
+ }
152
+ notify();
153
+ ctx.logger.info("Device code login successful, workspace selection needed");
154
+ return {
155
+ status: "workspace_selection_required",
156
+ message: `Authentication successful. ${workspaces.length} workspaces available \u2014 call ${ctx.productName}_auth_select_workspace to choose one.`,
157
+ workspaces
158
+ };
159
+ } catch (wsError) {
160
+ notify();
161
+ ctx.logger.warn("Workspace discovery failed after login", {
162
+ error: wsError instanceof Error ? wsError.message : String(wsError)
163
+ });
164
+ return {
165
+ status: "authenticated",
166
+ message: `Authentication successful. Workspace discovery failed: ${wsError instanceof Error ? wsError.message : String(wsError)}`
167
+ };
168
+ }
169
+ }
170
+ async function listWorkspaces() {
171
+ const auth = ctx.auth.read();
172
+ if (!auth?.accessToken) throw new Error("Not authenticated. Please login first.");
173
+ return fetchWorkspaces(ctx.config.read().globalEndpoint, auth.accessToken);
174
+ }
175
+ async function issueAndStoreWorkspaceToken(workspaceId, organizationId) {
176
+ const auth = ctx.auth.read();
177
+ if (!auth?.accessToken) throw new Error("Not authenticated.");
178
+ const result = await issueWorkspaceToken(
179
+ ctx.config.read().workspaceEndpoint,
180
+ auth.accessToken,
181
+ workspaceId,
182
+ organizationId
183
+ );
184
+ ctx.auth.write({
185
+ ...auth,
186
+ workspaceToken: result.token,
187
+ workspaceTokenExpiresAt: new Date(result.expiresAt).getTime(),
188
+ workspaceId,
189
+ organizationId
190
+ });
191
+ ctx.gql.reset();
192
+ notify();
193
+ }
194
+ async function selectWorkspace(workspaceId, organizationId) {
195
+ const auth = ctx.auth.read();
196
+ if (!auth?.accessToken) throw new Error("Not authenticated. Please login first.");
197
+ await issueAndStoreWorkspaceToken(workspaceId, organizationId);
198
+ ctx.logger.info("Workspace selected", { workspaceId });
199
+ }
200
+ async function ensureAuthenticated() {
201
+ if (refreshInProgress) {
202
+ await refreshInProgress;
203
+ return;
204
+ }
205
+ const doEnsure = async () => {
206
+ const auth = ctx.auth.read();
207
+ if (auth?.apiKey) return;
208
+ if (!auth?.accessToken) {
209
+ throw new Error(
210
+ `Not authenticated. Call ${ctx.productName}_auth_login to start the login flow, then ${ctx.productName}_auth_complete after authorizing in the browser.`
211
+ );
212
+ }
213
+ };
214
+ refreshInProgress = doEnsure().finally(() => {
215
+ refreshInProgress = null;
216
+ });
217
+ await refreshInProgress;
218
+ }
219
+ function getStatus() {
220
+ const auth = ctx.auth.read();
221
+ return Promise.resolve({
222
+ authenticated: !!(auth?.accessToken || auth?.apiKey),
223
+ method: auth?.apiKey ? "api_key" : auth?.accessToken ? "oauth_token" : "none",
224
+ expiresAt: auth?.expiresAt ? new Date(auth.expiresAt).toISOString() : null,
225
+ workspaceId: auth?.workspaceId ?? null,
226
+ organizationId: auth?.organizationId ?? null,
227
+ workspaceTokenExpiresAt: auth?.workspaceTokenExpiresAt ? new Date(auth.workspaceTokenExpiresAt).toISOString() : null,
228
+ hasWorkspaceToken: !!auth?.workspaceToken,
229
+ hasPendingLogin: !!pending
230
+ });
231
+ }
232
+ async function logout() {
233
+ pending = null;
234
+ ctx.auth.clear();
235
+ ctx.gql.reset();
236
+ notify();
237
+ ctx.logger.info("Logged out and cleared stored tokens");
238
+ }
239
+ function getHeaders() {
240
+ const auth = ctx.auth.read();
241
+ const headers = {};
242
+ if (auth?.apiKey) headers["X-API-Key"] = auth.apiKey;
243
+ if (auth?.accessToken) headers["Authorization"] = `Bearer ${auth.accessToken}`;
244
+ if (auth?.workspaceToken)
245
+ headers["X-Workspace-Authorization"] = `Bearer ${auth.workspaceToken}`;
246
+ if (auth?.organizationId) headers["x-org-id"] = auth.organizationId;
247
+ if (auth?.workspaceId) headers["x-workspace-id"] = auth.workspaceId;
248
+ return headers;
249
+ }
250
+ function isLoggedIn() {
251
+ const auth = ctx.auth.read();
252
+ return !!(auth?.accessToken || auth?.apiKey);
253
+ }
254
+ function setOnTokensChanged(cb) {
255
+ onTokensChanged = cb;
256
+ }
257
+ return {
258
+ startLogin,
259
+ completeLogin,
260
+ selectWorkspace,
261
+ listWorkspaces,
262
+ ensureAuthenticated,
263
+ getStatus,
264
+ logout,
265
+ getHeaders,
266
+ isLoggedIn,
267
+ setOnTokensChanged
268
+ };
269
+ }
270
+
271
+ export { getAuth };
272
+ //# sourceMappingURL=chunk-WWFVD7BO.js.map
273
+ //# sourceMappingURL=chunk-WWFVD7BO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/modules/auth/legacy-auth.ts"],"names":[],"mappings":"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","file":"chunk-WWFVD7BO.js","sourcesContent":["/**\n * Auth helper for the auth module — ports VibeControlsMCPAuth from\n * vibecontrols-mcp/src/auth/index.ts to a ctx-aware factory.\n *\n * Differences from the legacy class:\n * - Per-ctx instance (no module-level singleton; each product MCP gets its own)\n * - Token persistence delegated to ctx.auth (StoredAuth file)\n * - Endpoints + clientId resolved via ctx.config.resolveOIDC + ctx.config.read\n * - pendingDeviceCode kept in closure scope (alive for the MCP server process,\n * suitable for stdio's lifetime; HTTP's per-session servers each get their own\n * pending state)\n *\n * Public surface mirrors the legacy class so the lifted auth/tools.ts works\n * without modification: startLogin / completeLogin / selectWorkspace /\n * listWorkspaces / getStatus / logout / ensureAuthenticated / getHeaders /\n * isLoggedIn / setOnTokensChanged.\n */\n\nimport type { McpContext } from '../../core/index.js';\nimport { fetchWorkspaces, issueWorkspaceToken } from '../../core/auth/device-code.js';\n\ninterface PendingDeviceCode {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string | null;\n expiresAt: number;\n interval: number;\n clientId: string;\n tokenUrl: string;\n}\n\nexport interface WorkspaceInfo {\n id: string;\n name: string;\n slug: string;\n tenantId: string;\n organizationId: string;\n}\n\nexport interface LoginStartResult {\n status: 'device_code_issued';\n verificationUri: string;\n verificationUriComplete: string | null;\n userCode: string;\n expiresIn: number;\n message: string;\n}\n\nexport interface LoginCompleteResult {\n status: 'authenticated' | 'workspace_selection_required' | 'pending' | 'expired';\n message: string;\n workspaces?: WorkspaceInfo[];\n}\n\nexport interface AuthHelper {\n startLogin(): Promise<LoginStartResult>;\n completeLogin(): Promise<LoginCompleteResult>;\n selectWorkspace(workspaceId: string, organizationId: string): Promise<void>;\n listWorkspaces(): Promise<WorkspaceInfo[]>;\n ensureAuthenticated(): Promise<void>;\n getStatus(): Promise<{\n authenticated: boolean;\n method: string;\n expiresAt: string | null;\n workspaceId: string | null;\n organizationId: string | null;\n workspaceTokenExpiresAt: string | null;\n hasWorkspaceToken: boolean;\n hasPendingLogin: boolean;\n }>;\n logout(): Promise<void>;\n getHeaders(): Record<string, string>;\n isLoggedIn(): boolean;\n setOnTokensChanged(cb: () => void): void;\n}\n\nconst helpers = new WeakMap<McpContext, AuthHelper>();\n\nexport function getAuth(ctx: McpContext): AuthHelper {\n const cached = helpers.get(ctx);\n if (cached) return cached;\n const helper = createAuthHelper(ctx);\n helpers.set(ctx, helper);\n return helper;\n}\n\nfunction createAuthHelper(ctx: McpContext): AuthHelper {\n let pending: PendingDeviceCode | null = null;\n let onTokensChanged: (() => void) | null = null;\n let refreshInProgress: Promise<void> | null = null;\n\n function notify(): void {\n onTokensChanged?.();\n }\n\n async function startLogin(): Promise<LoginStartResult> {\n const { oidcIssuer, clientId } = ctx.config.resolveOIDC();\n const deviceCodeUrl = `${oidcIssuer}/oidc/device/code`;\n const tokenUrl = `${oidcIssuer}/oauth/device/token`;\n\n const response = await fetch(deviceCodeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n client_id: clientId,\n scope: 'openid profile email offline_access',\n }).toString(),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => 'Unknown error');\n throw new Error(`Device code request failed (${response.status}): ${text}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const deviceCode = data['device_code'] as string;\n const userCode = data['user_code'] as string;\n const verificationUri = data['verification_uri'] as string;\n const verificationUriComplete = (data['verification_uri_complete'] as string) ?? null;\n const expiresIn = (data['expires_in'] as number) ?? 900;\n const interval = (data['interval'] as number) ?? 5;\n\n pending = {\n deviceCode,\n userCode,\n verificationUri,\n verificationUriComplete,\n expiresAt: Date.now() + expiresIn * 1000,\n interval,\n clientId,\n tokenUrl,\n };\n\n return {\n status: 'device_code_issued',\n verificationUri,\n verificationUriComplete,\n userCode,\n expiresIn,\n message: `Open ${verificationUriComplete ?? verificationUri} in a browser and enter code: ${userCode}. Then call ${ctx.productName}_auth_complete to finish authentication.`,\n };\n }\n\n async function completeLogin(): Promise<LoginCompleteResult> {\n if (!pending) {\n throw new Error(\n `No pending login flow. Call ${ctx.productName}_auth_login first to start the device code flow.`,\n );\n }\n\n const p = pending;\n if (Date.now() >= p.expiresAt) {\n pending = null;\n return {\n status: 'expired',\n message: `Device code has expired. Call ${ctx.productName}_auth_login again to get a new code.`,\n };\n }\n\n const response = await fetch(p.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: p.deviceCode,\n client_id: p.clientId,\n }).toString(),\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n\n if (response.ok && data['access_token']) {\n pending = null;\n const expiresIn = (data['expires_in'] as number) ?? 3600;\n const auth = ctx.auth.read() ?? { accessToken: '', refreshToken: '' };\n ctx.auth.write({\n ...auth,\n accessToken: data['access_token'] as string,\n refreshToken: (data['refresh_token'] as string) ?? '',\n expiresAt: Date.now() + expiresIn * 1000,\n authMethod: 'device_code',\n });\n ctx.gql.reset();\n return await handlePostLogin();\n }\n\n const errorCode = data['error'] as string | undefined;\n if (errorCode === 'authorization_pending') {\n return {\n status: 'pending',\n message: `Still waiting for user to authorize. Open ${p.verificationUriComplete ?? p.verificationUri} and enter code: ${p.userCode}. Then call ${ctx.productName}_auth_complete again.`,\n };\n } else if (errorCode === 'slow_down') {\n p.interval += 5;\n return {\n status: 'pending',\n message: `Authorization server asked to slow down. Wait a moment, then call ${ctx.productName}_auth_complete again.`,\n };\n } else if (errorCode === 'expired_token') {\n pending = null;\n return {\n status: 'expired',\n message: `Device code has expired. Call ${ctx.productName}_auth_login again.`,\n };\n } else if (errorCode === 'access_denied') {\n pending = null;\n throw new Error('Authorization was denied by the user.');\n } else {\n pending = null;\n throw new Error(\n `Device code error: ${(data['error_description'] as string) ?? errorCode ?? 'Unknown'}`,\n );\n }\n }\n\n async function handlePostLogin(): Promise<LoginCompleteResult> {\n try {\n const workspaces = await listWorkspaces();\n if (workspaces.length === 0) {\n notify();\n ctx.logger.info('Device code login successful (no workspaces found)');\n return {\n status: 'authenticated',\n message: `Authentication successful. No workspaces found — use ${ctx.productName}_auth_select_workspace when one is available.`,\n };\n }\n if (workspaces.length === 1) {\n const ws = workspaces[0];\n if (!ws)\n throw new Error('Unexpected: workspaces.length === 1 but workspaces[0] is undefined');\n await issueAndStoreWorkspaceToken(ws.id, ws.organizationId);\n ctx.logger.info('Device code login successful', {\n workspaceId: ws.id,\n workspaceName: ws.name,\n });\n return {\n status: 'authenticated',\n message: `Authentication successful. Workspace \"${ws.name}\" selected automatically.`,\n };\n }\n notify();\n ctx.logger.info('Device code login successful, workspace selection needed');\n return {\n status: 'workspace_selection_required',\n message: `Authentication successful. ${workspaces.length} workspaces available — call ${ctx.productName}_auth_select_workspace to choose one.`,\n workspaces,\n };\n } catch (wsError) {\n notify();\n ctx.logger.warn('Workspace discovery failed after login', {\n error: wsError instanceof Error ? wsError.message : String(wsError),\n });\n return {\n status: 'authenticated',\n message: `Authentication successful. Workspace discovery failed: ${wsError instanceof Error ? wsError.message : String(wsError)}`,\n };\n }\n }\n\n async function listWorkspaces(): Promise<WorkspaceInfo[]> {\n const auth = ctx.auth.read();\n if (!auth?.accessToken) throw new Error('Not authenticated. Please login first.');\n return fetchWorkspaces(ctx.config.read().globalEndpoint, auth.accessToken);\n }\n\n async function issueAndStoreWorkspaceToken(\n workspaceId: string,\n organizationId: string,\n ): Promise<void> {\n const auth = ctx.auth.read();\n if (!auth?.accessToken) throw new Error('Not authenticated.');\n const result = await issueWorkspaceToken(\n ctx.config.read().workspaceEndpoint,\n auth.accessToken,\n workspaceId,\n organizationId,\n );\n ctx.auth.write({\n ...auth,\n workspaceToken: result.token,\n workspaceTokenExpiresAt: new Date(result.expiresAt).getTime(),\n workspaceId,\n organizationId,\n });\n ctx.gql.reset();\n notify();\n }\n\n async function selectWorkspace(workspaceId: string, organizationId: string): Promise<void> {\n const auth = ctx.auth.read();\n if (!auth?.accessToken) throw new Error('Not authenticated. Please login first.');\n await issueAndStoreWorkspaceToken(workspaceId, organizationId);\n ctx.logger.info('Workspace selected', { workspaceId });\n }\n\n async function ensureAuthenticated(): Promise<void> {\n if (refreshInProgress) {\n await refreshInProgress;\n return;\n }\n const doEnsure = async (): Promise<void> => {\n const auth = ctx.auth.read();\n if (auth?.apiKey) return;\n if (!auth?.accessToken) {\n throw new Error(\n `Not authenticated. Call ${ctx.productName}_auth_login to start the login flow, then ${ctx.productName}_auth_complete after authorizing in the browser.`,\n );\n }\n // The shared gql client handles refresh via isTokenExpiringSoon + isWorkspaceTokenExpiringSoon —\n // trigger by issuing a no-op request that goes through the workspace client's refresh path.\n // We simulate a no-op via a cheap query if needed; today the gql wrapper does it lazily,\n // so we just delegate to it on the next request. Nothing to do here.\n };\n refreshInProgress = doEnsure().finally(() => {\n refreshInProgress = null;\n });\n await refreshInProgress;\n }\n\n function getStatus(): Promise<{\n authenticated: boolean;\n method: string;\n expiresAt: string | null;\n workspaceId: string | null;\n organizationId: string | null;\n workspaceTokenExpiresAt: string | null;\n hasWorkspaceToken: boolean;\n hasPendingLogin: boolean;\n }> {\n const auth = ctx.auth.read();\n return Promise.resolve({\n authenticated: !!(auth?.accessToken || auth?.apiKey),\n method: auth?.apiKey ? 'api_key' : auth?.accessToken ? 'oauth_token' : 'none',\n expiresAt: auth?.expiresAt ? new Date(auth.expiresAt).toISOString() : null,\n workspaceId: auth?.workspaceId ?? null,\n organizationId: auth?.organizationId ?? null,\n workspaceTokenExpiresAt: auth?.workspaceTokenExpiresAt\n ? new Date(auth.workspaceTokenExpiresAt).toISOString()\n : null,\n hasWorkspaceToken: !!auth?.workspaceToken,\n hasPendingLogin: !!pending,\n });\n }\n\n async function logout(): Promise<void> {\n pending = null;\n ctx.auth.clear();\n ctx.gql.reset();\n notify();\n ctx.logger.info('Logged out and cleared stored tokens');\n }\n\n function getHeaders(): Record<string, string> {\n const auth = ctx.auth.read();\n const headers: Record<string, string> = {};\n if (auth?.apiKey) headers['X-API-Key'] = auth.apiKey;\n if (auth?.accessToken) headers['Authorization'] = `Bearer ${auth.accessToken}`;\n if (auth?.workspaceToken)\n headers['X-Workspace-Authorization'] = `Bearer ${auth.workspaceToken}`;\n if (auth?.organizationId) headers['x-org-id'] = auth.organizationId;\n if (auth?.workspaceId) headers['x-workspace-id'] = auth.workspaceId;\n return headers;\n }\n\n function isLoggedIn(): boolean {\n const auth = ctx.auth.read();\n return !!(auth?.accessToken || auth?.apiKey);\n }\n\n function setOnTokensChanged(cb: () => void): void {\n onTokensChanged = cb;\n }\n\n return {\n startLogin,\n completeLogin,\n selectWorkspace,\n listWorkspaces,\n ensureAuthenticated,\n getStatus,\n logout,\n getHeaders,\n isLoggedIn,\n setOnTokensChanged,\n };\n}\n"]}
@@ -0,0 +1,138 @@
1
+ import * as _modelcontextprotocol_sdk_server_mcp_js from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { RequestDocument, Variables } from 'graphql-request';
4
+
5
+ type AuthMethod = 'device_code' | 'client_credentials' | 'api_key';
6
+ interface StoredAuth {
7
+ accessToken: string;
8
+ refreshToken: string;
9
+ expiresAt?: number;
10
+ workspaceToken?: string;
11
+ workspaceTokenExpiresAt?: number;
12
+ workspaceId?: string;
13
+ organizationId?: string;
14
+ authMethod?: AuthMethod;
15
+ clientId?: string;
16
+ clientSecret?: string;
17
+ apiKey?: string;
18
+ }
19
+ interface AuthStore {
20
+ read(): StoredAuth | null;
21
+ write(auth: StoredAuth): void;
22
+ clear(): void;
23
+ isTokenExpired(): boolean;
24
+ isTokenExpiringSoon(): boolean;
25
+ isWorkspaceTokenExpired(): boolean;
26
+ isWorkspaceTokenExpiringSoon(): boolean;
27
+ isAuthenticated(): boolean;
28
+ }
29
+ declare function createAuthStore(configDir: string, authFileName?: string): AuthStore;
30
+
31
+ interface McpConfig {
32
+ workspaceEndpoint: string;
33
+ globalEndpoint: string;
34
+ oidcIssuer?: string;
35
+ clientId?: string;
36
+ accessToken?: string;
37
+ refreshToken?: string;
38
+ workspaceToken?: string;
39
+ apiKey?: string;
40
+ workspaceId?: string;
41
+ organizationId?: string;
42
+ host: string;
43
+ httpPort: number;
44
+ corsOrigins: string;
45
+ allowedHosts: string;
46
+ logLevel: 'error' | 'warn' | 'info' | 'debug';
47
+ logFormat: 'json' | 'text';
48
+ }
49
+ interface ProductDefaults {
50
+ configDirName: string;
51
+ oidcClientId: string;
52
+ oidcIssuerProd?: string;
53
+ workspaceEndpointDefault: string;
54
+ globalEndpointDefault: string;
55
+ httpPortDefault?: number;
56
+ hostDefault?: string;
57
+ envPrefix?: string;
58
+ }
59
+ interface ConfigStore {
60
+ read(): McpConfig;
61
+ write(config: Partial<McpConfig>): void;
62
+ path(): string;
63
+ dir(): string;
64
+ resolveOIDC(): {
65
+ oidcIssuer: string;
66
+ clientId: string;
67
+ };
68
+ }
69
+ declare function createConfigStore(defaults: ProductDefaults): ConfigStore;
70
+
71
+ interface GqlClient {
72
+ request<T>(document: RequestDocument, variables?: Variables): Promise<T>;
73
+ }
74
+ interface GqlClients {
75
+ workspace: GqlClient;
76
+ global: GqlClient;
77
+ workspaceAuthOnly: GqlClient;
78
+ reset(): void;
79
+ }
80
+ declare function extractGqlErrorMessage(error: unknown): string;
81
+ declare function createGqlClients(config: ConfigStore, authStore: AuthStore): GqlClients;
82
+
83
+ type LogLevel = 'error' | 'warn' | 'info' | 'debug';
84
+ type LogFormat = 'json' | 'text';
85
+ interface LogContext {
86
+ [key: string]: unknown;
87
+ }
88
+ interface Logger {
89
+ error(message: string, context?: LogContext): void;
90
+ warn(message: string, context?: LogContext): void;
91
+ info(message: string, context?: LogContext): void;
92
+ debug(message: string, context?: LogContext): void;
93
+ setLevel(level: LogLevel): void;
94
+ getLevel(): LogLevel;
95
+ }
96
+ interface LoggerOptions {
97
+ level?: LogLevel;
98
+ format?: LogFormat;
99
+ }
100
+ declare function createLogger(opts?: LoggerOptions): Logger;
101
+
102
+ type ProgressFn = (token: string | number | undefined, current: number, total?: number, message?: string) => void;
103
+ declare function createProgress(serverRef: {
104
+ current: McpServer | null;
105
+ }): ProgressFn;
106
+
107
+ type Environment = 'prod' | 'alpha' | 'dev' | 'local';
108
+ interface McpContext {
109
+ productName: string;
110
+ productVersion: string;
111
+ serverName: string;
112
+ serverVersion: string;
113
+ defaults: ProductDefaults;
114
+ config: ConfigStore;
115
+ auth: AuthStore;
116
+ gql: GqlClients;
117
+ logger: Logger;
118
+ progress: ProgressFn;
119
+ env: Environment;
120
+ _internal: {
121
+ serverRef: {
122
+ current: _modelcontextprotocol_sdk_server_mcp_js.McpServer | null;
123
+ };
124
+ };
125
+ }
126
+ interface BuildContextOptions {
127
+ productName: string;
128
+ productVersion: string;
129
+ serverName: string;
130
+ serverVersion: string;
131
+ defaults: ProductDefaults;
132
+ logger?: LoggerOptions | Logger;
133
+ env?: Environment;
134
+ tokenStorePath?: string;
135
+ }
136
+ declare function buildContext(opts: BuildContextOptions): McpContext;
137
+
138
+ export { type AuthMethod as A, type BuildContextOptions as B, type ConfigStore as C, type Environment as E, type GqlClient as G, type Logger as L, type McpContext as M, type ProductDefaults as P, type StoredAuth as S, type AuthStore as a, buildContext as b, type GqlClients as c, type LogContext as d, type LogFormat as e, type LogLevel as f, type LoggerOptions as g, type McpConfig as h, type ProgressFn as i, createAuthStore as j, createConfigStore as k, createGqlClients as l, createLogger as m, createProgress as n, extractGqlErrorMessage as o };
@@ -0,0 +1,138 @@
1
+ import * as _modelcontextprotocol_sdk_server_mcp_js from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { RequestDocument, Variables } from 'graphql-request';
4
+
5
+ type AuthMethod = 'device_code' | 'client_credentials' | 'api_key';
6
+ interface StoredAuth {
7
+ accessToken: string;
8
+ refreshToken: string;
9
+ expiresAt?: number;
10
+ workspaceToken?: string;
11
+ workspaceTokenExpiresAt?: number;
12
+ workspaceId?: string;
13
+ organizationId?: string;
14
+ authMethod?: AuthMethod;
15
+ clientId?: string;
16
+ clientSecret?: string;
17
+ apiKey?: string;
18
+ }
19
+ interface AuthStore {
20
+ read(): StoredAuth | null;
21
+ write(auth: StoredAuth): void;
22
+ clear(): void;
23
+ isTokenExpired(): boolean;
24
+ isTokenExpiringSoon(): boolean;
25
+ isWorkspaceTokenExpired(): boolean;
26
+ isWorkspaceTokenExpiringSoon(): boolean;
27
+ isAuthenticated(): boolean;
28
+ }
29
+ declare function createAuthStore(configDir: string, authFileName?: string): AuthStore;
30
+
31
+ interface McpConfig {
32
+ workspaceEndpoint: string;
33
+ globalEndpoint: string;
34
+ oidcIssuer?: string;
35
+ clientId?: string;
36
+ accessToken?: string;
37
+ refreshToken?: string;
38
+ workspaceToken?: string;
39
+ apiKey?: string;
40
+ workspaceId?: string;
41
+ organizationId?: string;
42
+ host: string;
43
+ httpPort: number;
44
+ corsOrigins: string;
45
+ allowedHosts: string;
46
+ logLevel: 'error' | 'warn' | 'info' | 'debug';
47
+ logFormat: 'json' | 'text';
48
+ }
49
+ interface ProductDefaults {
50
+ configDirName: string;
51
+ oidcClientId: string;
52
+ oidcIssuerProd?: string;
53
+ workspaceEndpointDefault: string;
54
+ globalEndpointDefault: string;
55
+ httpPortDefault?: number;
56
+ hostDefault?: string;
57
+ envPrefix?: string;
58
+ }
59
+ interface ConfigStore {
60
+ read(): McpConfig;
61
+ write(config: Partial<McpConfig>): void;
62
+ path(): string;
63
+ dir(): string;
64
+ resolveOIDC(): {
65
+ oidcIssuer: string;
66
+ clientId: string;
67
+ };
68
+ }
69
+ declare function createConfigStore(defaults: ProductDefaults): ConfigStore;
70
+
71
+ interface GqlClient {
72
+ request<T>(document: RequestDocument, variables?: Variables): Promise<T>;
73
+ }
74
+ interface GqlClients {
75
+ workspace: GqlClient;
76
+ global: GqlClient;
77
+ workspaceAuthOnly: GqlClient;
78
+ reset(): void;
79
+ }
80
+ declare function extractGqlErrorMessage(error: unknown): string;
81
+ declare function createGqlClients(config: ConfigStore, authStore: AuthStore): GqlClients;
82
+
83
+ type LogLevel = 'error' | 'warn' | 'info' | 'debug';
84
+ type LogFormat = 'json' | 'text';
85
+ interface LogContext {
86
+ [key: string]: unknown;
87
+ }
88
+ interface Logger {
89
+ error(message: string, context?: LogContext): void;
90
+ warn(message: string, context?: LogContext): void;
91
+ info(message: string, context?: LogContext): void;
92
+ debug(message: string, context?: LogContext): void;
93
+ setLevel(level: LogLevel): void;
94
+ getLevel(): LogLevel;
95
+ }
96
+ interface LoggerOptions {
97
+ level?: LogLevel;
98
+ format?: LogFormat;
99
+ }
100
+ declare function createLogger(opts?: LoggerOptions): Logger;
101
+
102
+ type ProgressFn = (token: string | number | undefined, current: number, total?: number, message?: string) => void;
103
+ declare function createProgress(serverRef: {
104
+ current: McpServer | null;
105
+ }): ProgressFn;
106
+
107
+ type Environment = 'prod' | 'alpha' | 'dev' | 'local';
108
+ interface McpContext {
109
+ productName: string;
110
+ productVersion: string;
111
+ serverName: string;
112
+ serverVersion: string;
113
+ defaults: ProductDefaults;
114
+ config: ConfigStore;
115
+ auth: AuthStore;
116
+ gql: GqlClients;
117
+ logger: Logger;
118
+ progress: ProgressFn;
119
+ env: Environment;
120
+ _internal: {
121
+ serverRef: {
122
+ current: _modelcontextprotocol_sdk_server_mcp_js.McpServer | null;
123
+ };
124
+ };
125
+ }
126
+ interface BuildContextOptions {
127
+ productName: string;
128
+ productVersion: string;
129
+ serverName: string;
130
+ serverVersion: string;
131
+ defaults: ProductDefaults;
132
+ logger?: LoggerOptions | Logger;
133
+ env?: Environment;
134
+ tokenStorePath?: string;
135
+ }
136
+ declare function buildContext(opts: BuildContextOptions): McpContext;
137
+
138
+ export { type AuthMethod as A, type BuildContextOptions as B, type ConfigStore as C, type Environment as E, type GqlClient as G, type Logger as L, type McpContext as M, type ProductDefaults as P, type StoredAuth as S, type AuthStore as a, buildContext as b, type GqlClients as c, type LogContext as d, type LogFormat as e, type LogLevel as f, type LoggerOptions as g, type McpConfig as h, type ProgressFn as i, createAuthStore as j, createConfigStore as k, createGqlClients as l, createLogger as m, createProgress as n, extractGqlErrorMessage as o };