@stigmer/react 0.0.80 → 0.0.82

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 (49) hide show
  1. package/environment/index.d.ts +1 -1
  2. package/environment/index.d.ts.map +1 -1
  3. package/environment/index.js +1 -1
  4. package/environment/index.js.map +1 -1
  5. package/environment/systemEnvVars.d.ts +16 -0
  6. package/environment/systemEnvVars.d.ts.map +1 -1
  7. package/environment/systemEnvVars.js +32 -0
  8. package/environment/systemEnvVars.js.map +1 -1
  9. package/index.d.ts +1 -1
  10. package/index.d.ts.map +1 -1
  11. package/index.js +1 -1
  12. package/index.js.map +1 -1
  13. package/mcp-server/McpServerConfigPanel.d.ts +23 -1
  14. package/mcp-server/McpServerConfigPanel.d.ts.map +1 -1
  15. package/mcp-server/McpServerConfigPanel.js +14 -5
  16. package/mcp-server/McpServerConfigPanel.js.map +1 -1
  17. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  18. package/mcp-server/McpServerDetailView.js +36 -14
  19. package/mcp-server/McpServerDetailView.js.map +1 -1
  20. package/mcp-server/McpServerPicker.d.ts.map +1 -1
  21. package/mcp-server/McpServerPicker.js +27 -3
  22. package/mcp-server/McpServerPicker.js.map +1 -1
  23. package/mcp-server/OAuthCallbackHandler.d.ts.map +1 -1
  24. package/mcp-server/OAuthCallbackHandler.js +33 -9
  25. package/mcp-server/OAuthCallbackHandler.js.map +1 -1
  26. package/mcp-server/useMcpServerConnect.d.ts +22 -12
  27. package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
  28. package/mcp-server/useMcpServerConnect.js +17 -10
  29. package/mcp-server/useMcpServerConnect.js.map +1 -1
  30. package/mcp-server/useMcpServerCredentials.d.ts +53 -2
  31. package/mcp-server/useMcpServerCredentials.d.ts.map +1 -1
  32. package/mcp-server/useMcpServerCredentials.js +37 -6
  33. package/mcp-server/useMcpServerCredentials.js.map +1 -1
  34. package/mcp-server/useMcpServerOAuthConnect.d.ts +10 -1
  35. package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
  36. package/mcp-server/useMcpServerOAuthConnect.js +60 -11
  37. package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
  38. package/package.json +4 -4
  39. package/src/environment/index.ts +1 -0
  40. package/src/environment/systemEnvVars.ts +39 -0
  41. package/src/index.ts +1 -0
  42. package/src/mcp-server/McpServerConfigPanel.tsx +82 -4
  43. package/src/mcp-server/McpServerDetailView.tsx +104 -16
  44. package/src/mcp-server/McpServerPicker.tsx +56 -18
  45. package/src/mcp-server/OAuthCallbackHandler.tsx +39 -12
  46. package/src/mcp-server/useMcpServerConnect.ts +33 -14
  47. package/src/mcp-server/useMcpServerCredentials.ts +68 -6
  48. package/src/mcp-server/useMcpServerOAuthConnect.ts +63 -15
  49. package/styles.css +1 -1
@@ -1,5 +1,6 @@
1
1
  "use client";
2
- import { useCallback, useMemo } from "react";
2
+ import { useCallback, useMemo, useState } from "react";
3
+ import { VendorApprovalStatus } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
3
4
  import { usePersonalEnvironment } from "../environment/usePersonalEnvironment";
4
5
  import { diffEnv } from "../environment/diffEnv";
5
6
  import { SYSTEM_ENV_VAR_KEYS } from "../environment/systemEnvVars";
@@ -32,9 +33,31 @@ import { useOAuthGrantStatus } from "./useOAuthGrantStatus";
32
33
  * ```tsx
33
34
  * const creds = useMcpServerCredentials("acme", mcpServer);
34
35
  *
35
- * // OAuth server — sign-in button + optional manual form
36
+ * // OAuth server — sign-in button + manual override escape hatch
36
37
  * if (creds.authMode === "oauth" && !creds.isOAuthConnected) {
37
- * return <button onClick={startOAuth}>Sign in</button>;
38
+ * if (creds.manualOverride) {
39
+ * // User opted to enter the token manually
40
+ * return (
41
+ * <>
42
+ * <EnvVarForm
43
+ * variables={creds.missingVariables}
44
+ * onSubmit={(values) => creds.saveCredentials(values)}
45
+ * isSubmitting={creds.isSaving}
46
+ * />
47
+ * <button onClick={() => creds.setManualOverride(false)}>
48
+ * Sign in with OAuth instead
49
+ * </button>
50
+ * </>
51
+ * );
52
+ * }
53
+ * return (
54
+ * <>
55
+ * <button onClick={startOAuth}>Sign in</button>
56
+ * <button onClick={() => creds.setManualOverride(true)}>
57
+ * Enter token manually
58
+ * </button>
59
+ * </>
60
+ * );
38
61
  * }
39
62
  *
40
63
  * // Manual vars still needed (mixed mode or manual-only)
@@ -52,10 +75,14 @@ import { useOAuthGrantStatus } from "./useOAuthGrantStatus";
52
75
  */
53
76
  export function useMcpServerCredentials(org, mcpServer) {
54
77
  const personalEnv = usePersonalEnvironment(org);
78
+ const [manualOverride, setManualOverride] = useState(false);
55
79
  const auth = mcpServer?.spec?.auth;
56
80
  const authMode = auth ? "oauth" : "manual";
57
81
  const oauthTargetEnvVar = auth?.targetEnvVar || null;
58
82
  const tokenLifetimeHint = auth?.tokenLifetimeHint || null;
83
+ const isVendorApprovalPending = authMode === "oauth" &&
84
+ auth?.vendorApprovalStatus === VendorApprovalStatus.PENDING;
85
+ const vendorApprovalDocsUrl = auth?.vendorApprovalDocsUrl || null;
59
86
  const grantStatus = useOAuthGrantStatus(authMode === "oauth" ? (mcpServer?.metadata?.id ?? null) : null, authMode === "oauth" ? org : null);
60
87
  const isOAuthConnected = authMode === "oauth" && grantStatus.connected;
61
88
  const existingKeys = useMemo(() => new Set(Object.keys(personalEnv.environment?.spec?.data ?? {})), [personalEnv.environment]);
@@ -69,14 +96,14 @@ export function useMcpServerCredentials(org, mcpServer) {
69
96
  }, [mcpServer, existingKeys]);
70
97
  const requiredMissing = useMemo(() => allMissingVariables.filter((v) => !v.optional), [allMissingVariables]);
71
98
  const missingVariables = useMemo(() => {
72
- if (!oauthTargetEnvVar)
99
+ if (!oauthTargetEnvVar || manualOverride)
73
100
  return requiredMissing;
74
101
  return requiredMissing.filter((v) => v.key !== oauthTargetEnvVar);
75
- }, [requiredMissing, oauthTargetEnvVar]);
102
+ }, [requiredMissing, oauthTargetEnvVar, manualOverride]);
76
103
  const isReady = !personalEnv.isLoading &&
77
104
  !grantStatus.isLoading &&
78
105
  missingVariables.length === 0 &&
79
- (authMode === "manual" || isOAuthConnected);
106
+ (authMode === "manual" || manualOverride || isOAuthConnected);
80
107
  const saveCredentials = useCallback(async (values) => {
81
108
  await personalEnv.getOrCreate();
82
109
  await personalEnv.addVariables(values);
@@ -91,6 +118,8 @@ export function useMcpServerCredentials(org, mcpServer) {
91
118
  isOAuthConnected,
92
119
  accessTokenExpiresAt: grantStatus.accessTokenExpiresAt,
93
120
  tokenLifetimeHint,
121
+ isVendorApprovalPending,
122
+ vendorApprovalDocsUrl,
94
123
  missingVariables,
95
124
  isReady,
96
125
  isLoading: personalEnv.isLoading || grantStatus.isLoading,
@@ -98,6 +127,8 @@ export function useMcpServerCredentials(org, mcpServer) {
98
127
  saveCredentials,
99
128
  isSaving: personalEnv.isMutating,
100
129
  refetch,
130
+ manualOverride,
131
+ setManualOverride,
101
132
  };
102
133
  }
103
134
  //# sourceMappingURL=useMcpServerCredentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMcpServerCredentials.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerCredentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useMcpServerCredentials.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerCredentials.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,13 @@ import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/
5
5
  * @internal
6
6
  */
7
7
  export declare const OAUTH_CALLBACK_MESSAGE_TYPE = "stigmer:oauth:callback";
8
+ /**
9
+ * BroadcastChannel name used as a fallback when `window.opener` is severed
10
+ * by `Cross-Origin-Opener-Policy` headers on the OAuth provider.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare const OAUTH_BROADCAST_CHANNEL = "stigmer:oauth:broadcast";
8
15
  /**
9
16
  * Shape of the `postMessage` payload sent from the OAuth callback popup.
10
17
  *
@@ -33,9 +40,11 @@ export interface UseMcpServerOAuthConnectReturn {
33
40
  *
34
41
  * @param mcpServerId - System-generated ID (metadata.id) of the MCP server.
35
42
  * @param org - Organization context for token storage (caller's active org).
43
+ * @param declaredEnvKeys - Keys from the server's `spec.env` declaration.
44
+ * System vars are only injected when declared here.
36
45
  * @returns The updated McpServer after tool discovery completes.
37
46
  */
38
- readonly startOAuth: (mcpServerId: string, org: string) => Promise<McpServer>;
47
+ readonly startOAuth: (mcpServerId: string, org: string, declaredEnvKeys?: readonly string[]) => Promise<McpServer>;
39
48
  /** `true` while any phase of the OAuth flow is in progress. */
40
49
  readonly isInProgress: boolean;
41
50
  /** Current phase of the OAuth flow. */
@@ -1 +1 @@
1
- {"version":3,"file":"useMcpServerOAuthConnect.d.ts","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerOAuthConnect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wDAAwD,CAAC;AAUxF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,2BAA2B,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,iDAAiD;AACjD,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,YAAY,GACZ,mBAAmB,GACnB,YAAY,GACZ,YAAY,GACZ,MAAM,CAAC;AAEX,wDAAwD;AACxD,MAAM,WAAW,8BAA8B;IAC7C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9E,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CACjC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,wBAAwB,IAAI,8BAA8B,CAiHzE"}
1
+ {"version":3,"file":"useMcpServerOAuthConnect.d.ts","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerOAuthConnect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wDAAwD,CAAC;AAUxF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,2BAA2B,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,iDAAiD;AACjD,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,YAAY,GACZ,mBAAmB,GACnB,YAAY,GACZ,YAAY,GACZ,MAAM,CAAC;AAEX,wDAAwD;AACxD,MAAM,WAAW,8BAA8B;IAC7C;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACnH,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CACjC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,wBAAwB,IAAI,8BAA8B,CAsHzE"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { create } from "@bufbuild/protobuf";
4
4
  import { InitiateOAuthConnectInputSchema, CompleteOAuthConnectInputSchema, ConnectInputSchema, } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
5
5
  import { useStigmer } from "../hooks";
6
- import { resolveSystemEnvVarValues } from "../environment/systemEnvVars";
6
+ import { resolveDeclaredSystemEnvVars } from "../environment/systemEnvVars";
7
7
  import { toError } from "../internal/toError";
8
8
  /**
9
9
  * Message type posted by {@link OAuthCallbackHandler} to the opener window.
@@ -11,6 +11,13 @@ import { toError } from "../internal/toError";
11
11
  * @internal
12
12
  */
13
13
  export const OAUTH_CALLBACK_MESSAGE_TYPE = "stigmer:oauth:callback";
14
+ /**
15
+ * BroadcastChannel name used as a fallback when `window.opener` is severed
16
+ * by `Cross-Origin-Opener-Policy` headers on the OAuth provider.
17
+ *
18
+ * @internal
19
+ */
20
+ export const OAUTH_BROADCAST_CHANNEL = "stigmer:oauth:broadcast";
14
21
  const POPUP_WIDTH = 600;
15
22
  const POPUP_HEIGHT = 700;
16
23
  const POPUP_CALLBACK_TIMEOUT_MS = 120_000;
@@ -62,7 +69,7 @@ export function useMcpServerOAuthConnect() {
62
69
  setPhase("idle");
63
70
  setError(null);
64
71
  }, []);
65
- const startOAuth = useCallback(async (mcpServerId, org) => {
72
+ const startOAuth = useCallback(async (mcpServerId, org, declaredEnvKeys) => {
66
73
  setPhase("initiating");
67
74
  setError(null);
68
75
  cleanupRef.current?.();
@@ -91,7 +98,9 @@ export function useMcpServerOAuthConnect() {
91
98
  state,
92
99
  }));
93
100
  setPhase("connecting");
94
- const systemEnv = await resolveSystemEnvVarValues(stigmer);
101
+ const systemEnv = declaredEnvKeys
102
+ ? await resolveDeclaredSystemEnvVars(stigmer, declaredEnvKeys)
103
+ : {};
95
104
  const runtimeEnvMap = {};
96
105
  for (const [key, envInput] of Object.entries(systemEnv)) {
97
106
  runtimeEnvMap[key] = {
@@ -99,10 +108,14 @@ export function useMcpServerOAuthConnect() {
99
108
  isSecret: envInput.isSecret ?? false,
100
109
  };
101
110
  }
102
- const server = await stigmer.mcpServer.connect(create(ConnectInputSchema, {
111
+ const input = create(ConnectInputSchema, {
103
112
  mcpServerId,
104
- runtimeEnv: runtimeEnvMap,
105
- }));
113
+ org,
114
+ ...(Object.keys(runtimeEnvMap).length > 0
115
+ ? { runtimeEnv: runtimeEnvMap }
116
+ : {}),
117
+ });
118
+ const server = await stigmer.mcpServer.connect(input);
106
119
  setPhase("done");
107
120
  return server;
108
121
  }
@@ -129,17 +142,29 @@ export function useMcpServerOAuthConnect() {
129
142
  // ---------------------------------------------------------------------------
130
143
  // Popup callback listener
131
144
  // ---------------------------------------------------------------------------
145
+ /**
146
+ * Grace period (ms) after `popup.closed` is first detected before treating
147
+ * it as a user-initiated close. COOP providers sever the opener reference
148
+ * immediately, making `popup.closed` appear `true` while the popup is still
149
+ * active. The grace period lets the BroadcastChannel callback arrive.
150
+ */
151
+ const POPUP_CLOSED_GRACE_MS = 5_000;
132
152
  function waitForOAuthCallback(popup, expectedState, onDispose) {
133
153
  return new Promise((resolve, reject) => {
134
154
  let settled = false;
135
155
  let timeoutId;
136
156
  let pollId;
157
+ let bc = null;
137
158
  function cleanup() {
138
159
  if (timeoutId)
139
160
  clearTimeout(timeoutId);
140
161
  if (pollId)
141
162
  clearInterval(pollId);
142
163
  window.removeEventListener("message", onMessage);
164
+ try {
165
+ bc?.close();
166
+ }
167
+ catch { /* ignore */ }
143
168
  }
144
169
  function settle(outcome) {
145
170
  if (settled)
@@ -157,10 +182,7 @@ function waitForOAuthCallback(popup, expectedState, onDispose) {
157
182
  settle(new Error("OAuth flow was cancelled."));
158
183
  closePopup(popup);
159
184
  });
160
- function onMessage(event) {
161
- if (event.origin !== window.location.origin)
162
- return;
163
- const data = event.data;
185
+ function validateAndSettle(data) {
164
186
  if (data?.type !== OAUTH_CALLBACK_MESSAGE_TYPE)
165
187
  return;
166
188
  if (data.state !== expectedState) {
@@ -174,16 +196,43 @@ function waitForOAuthCallback(popup, expectedState, onDispose) {
174
196
  }
175
197
  settle({ code: data.code, state: data.state });
176
198
  }
199
+ function onMessage(event) {
200
+ if (event.origin !== window.location.origin)
201
+ return;
202
+ validateAndSettle(event.data);
203
+ }
177
204
  window.addEventListener("message", onMessage);
205
+ // BroadcastChannel — works even when COOP severs window.opener.
206
+ try {
207
+ bc = new BroadcastChannel(OAUTH_BROADCAST_CHANNEL);
208
+ bc.onmessage = (event) => {
209
+ validateAndSettle(event.data);
210
+ };
211
+ }
212
+ catch {
213
+ // BroadcastChannel unsupported — rely on postMessage only.
214
+ }
178
215
  timeoutId = setTimeout(() => {
179
216
  settle(new Error("OAuth authentication timed out. Ensure your callback page " +
180
217
  "renders <OAuthCallbackHandler /> from @stigmer/react at " +
181
218
  "the URL configured as your OAuth redirect URI."));
182
219
  closePopup(popup);
183
220
  }, POPUP_CALLBACK_TIMEOUT_MS);
221
+ // COOP providers make popup.closed appear true immediately after
222
+ // cross-origin navigation. Wait a grace period before treating it
223
+ // as a real user-initiated close.
224
+ let popupClosedAt = null;
184
225
  pollId = setInterval(() => {
185
226
  if (popup.closed) {
186
- settle(new Error("The authentication window was closed before completing sign-in."));
227
+ if (popupClosedAt === null) {
228
+ popupClosedAt = Date.now();
229
+ }
230
+ else if (Date.now() - popupClosedAt > POPUP_CLOSED_GRACE_MS) {
231
+ settle(new Error("The authentication window was closed before completing sign-in."));
232
+ }
233
+ }
234
+ else {
235
+ popupClosedAt = null;
187
236
  }
188
237
  }, 500);
189
238
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useMcpServerOAuthConnect.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerOAuthConnect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useMcpServerOAuthConnect.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerOAuthConnect.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigmer/react",
3
- "version": "0.0.80",
3
+ "version": "0.0.82",
4
4
  "description": "React provider and client hook for the Stigmer platform SDK",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -35,7 +35,7 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@stigmer/theme": "0.0.80",
38
+ "@stigmer/theme": "0.0.82",
39
39
  "react-markdown": "^10.1.0",
40
40
  "remark-gfm": "^4.0.1",
41
41
  "yaml": "^2.8.2"
@@ -43,8 +43,8 @@
43
43
  "peerDependencies": {
44
44
  "@base-ui/react": "^1.0.0",
45
45
  "@bufbuild/protobuf": "^2.0.0",
46
- "@stigmer/protos": "0.0.80",
47
- "@stigmer/sdk": "0.0.80",
46
+ "@stigmer/protos": "0.0.82",
47
+ "@stigmer/sdk": "0.0.82",
48
48
  "react": "^19.0.0",
49
49
  "react-dom": "^19.0.0"
50
50
  }
@@ -46,4 +46,5 @@ export {
46
46
  toGrpcAddress,
47
47
  buildSystemEnvVars,
48
48
  resolveSystemEnvVarValues,
49
+ resolveDeclaredSystemEnvVars,
49
50
  } from "./systemEnvVars";
@@ -102,3 +102,42 @@ export async function resolveSystemEnvVarValues(
102
102
  const credential = await stigmer.getAuthCredential();
103
103
  return buildSystemEnvVars(stigmer.baseUrl, credential);
104
104
  }
105
+
106
+ /**
107
+ * Resolve only the system env vars that the target resource actually
108
+ * declares in its environment specification.
109
+ *
110
+ * System vars (`STIGMER_SERVER_ADDRESS`, `STIGMER_API_KEY`) should
111
+ * only be injected when the resource needs them — blindly injecting
112
+ * them causes `runtime_env` to be non-empty on the wire, which
113
+ * changes the backend's missing-credential tolerance semantics.
114
+ *
115
+ * @param stigmer - Live Stigmer client for credential resolution.
116
+ * @param declaredEnvKeys - The set of env var keys the target
117
+ * resource declares (e.g., `Object.keys(mcpServer.spec.env)`).
118
+ * Only system vars whose keys appear here are included.
119
+ * @returns Filtered system env vars (may be empty).
120
+ */
121
+ export async function resolveDeclaredSystemEnvVars(
122
+ stigmer: Stigmer,
123
+ declaredEnvKeys: ReadonlySet<string> | readonly string[],
124
+ ): Promise<Record<string, EnvVarInput>> {
125
+ const keys =
126
+ declaredEnvKeys instanceof Set
127
+ ? declaredEnvKeys
128
+ : new Set(declaredEnvKeys);
129
+
130
+ const hasDeclared = [...SYSTEM_ENV_VAR_KEYS].some((k) => keys.has(k));
131
+ if (!hasDeclared) {
132
+ return {};
133
+ }
134
+
135
+ const all = await resolveSystemEnvVarValues(stigmer);
136
+ const filtered: Record<string, EnvVarInput> = {};
137
+ for (const [key, value] of Object.entries(all)) {
138
+ if (keys.has(key)) {
139
+ filtered[key] = value;
140
+ }
141
+ }
142
+ return filtered;
143
+ }
package/src/index.ts CHANGED
@@ -355,6 +355,7 @@ export {
355
355
  toGrpcAddress,
356
356
  buildSystemEnvVars,
357
357
  resolveSystemEnvVarValues,
358
+ resolveDeclaredSystemEnvVars,
358
359
  } from "./environment";
359
360
  export type {
360
361
  UseEnvironmentReturn,
@@ -76,6 +76,16 @@ export interface McpServerOAuthSignInProps {
76
76
  readonly error: Error | null;
77
77
  /** Clear the OAuth error state. */
78
78
  readonly onClearError: () => void;
79
+ /**
80
+ * `true` when the platform's OAuth app is pending vendor approval.
81
+ * Disables the sign-in button and shows an informational message.
82
+ */
83
+ readonly isVendorApprovalPending?: boolean;
84
+ /**
85
+ * Documentation URL for bringing your own OAuth token.
86
+ * Shown as a help link when `isVendorApprovalPending` is `true`.
87
+ */
88
+ readonly vendorApprovalDocsUrl?: string | null;
79
89
  }
80
90
 
81
91
  // ---------------------------------------------------------------------------
@@ -113,6 +123,18 @@ export interface McpServerConfigPanelProps {
113
123
  readonly onEnabledToolsChange: (enabledTools: string[]) => void;
114
124
  /** Called when the user clicks "Back" to return to the picker list. */
115
125
  readonly onBack: () => void;
126
+ /**
127
+ * When provided, a "Enter token manually" link is shown below the
128
+ * OAuth sign-in section. Clicking it switches the panel to manual
129
+ * token entry mode — the caller is responsible for updating the
130
+ * `credentials` and `oauthSignIn` props accordingly.
131
+ */
132
+ readonly onSwitchToManual?: () => void;
133
+ /**
134
+ * When provided, a "Sign in with OAuth instead" link is shown near
135
+ * the credentials form. Clicking it reverts to the OAuth flow.
136
+ */
137
+ readonly onSwitchToOAuth?: () => void;
116
138
  /** Error to display inline (e.g., from credential submission failure). */
117
139
  readonly error?: Error | null;
118
140
  /** Disables all interaction. */
@@ -179,6 +201,8 @@ export function McpServerConfigPanel({
179
201
  enabledTools,
180
202
  onEnabledToolsChange,
181
203
  onBack,
204
+ onSwitchToManual,
205
+ onSwitchToOAuth,
182
206
  error,
183
207
  disabled,
184
208
  className,
@@ -257,9 +281,23 @@ export function McpServerConfigPanel({
257
281
  onSignIn={oauthSignIn.onSignIn}
258
282
  error={oauthSignIn.error}
259
283
  onClearError={oauthSignIn.onClearError}
284
+ isVendorApprovalPending={oauthSignIn.isVendorApprovalPending}
285
+ vendorApprovalDocsUrl={oauthSignIn.vendorApprovalDocsUrl}
286
+ onSwitchToManual={onSwitchToManual}
260
287
  />
261
288
  )}
262
289
 
290
+ {/* Switch back to OAuth — shown in manual override mode */}
291
+ {!oauthSignIn && onSwitchToOAuth && (
292
+ <button
293
+ type="button"
294
+ onClick={onSwitchToOAuth}
295
+ className="text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground"
296
+ >
297
+ Sign in with OAuth instead
298
+ </button>
299
+ )}
300
+
263
301
  {/* Credentials form — only when credentials prop is provided */}
264
302
  {credentials && (
265
303
  <EnvVarForm
@@ -308,6 +346,9 @@ function InlineOAuthSignIn({
308
346
  onSignIn,
309
347
  error,
310
348
  onClearError,
349
+ isVendorApprovalPending,
350
+ vendorApprovalDocsUrl,
351
+ onSwitchToManual,
311
352
  }: {
312
353
  readonly serverName: string;
313
354
  readonly isConnected: boolean;
@@ -315,6 +356,9 @@ function InlineOAuthSignIn({
315
356
  readonly onSignIn: () => void;
316
357
  readonly error: Error | null;
317
358
  readonly onClearError: () => void;
359
+ readonly isVendorApprovalPending?: boolean;
360
+ readonly vendorApprovalDocsUrl?: string | null;
361
+ readonly onSwitchToManual?: () => void;
318
362
  }) {
319
363
  const isBusy =
320
364
  phase === "initiating" ||
@@ -322,28 +366,38 @@ function InlineOAuthSignIn({
322
366
  phase === "completing" ||
323
367
  phase === "connecting";
324
368
 
369
+ const signInDisabled = isBusy || !!isVendorApprovalPending;
370
+
325
371
  return (
326
372
  <div className="space-y-1.5">
327
373
  <div className="flex items-center justify-between">
328
374
  <span
329
375
  className={cn(
330
376
  "inline-flex items-center gap-1 text-[0.65rem] font-medium",
331
- isConnected ? "text-success" : "text-muted-foreground",
377
+ isConnected
378
+ ? "text-success"
379
+ : isVendorApprovalPending
380
+ ? "text-amber-600 dark:text-amber-400"
381
+ : "text-muted-foreground",
332
382
  )}
333
383
  >
334
384
  <span
335
385
  className={cn(
336
386
  "size-1.5 rounded-full",
337
- isConnected ? "bg-success" : "bg-muted-foreground",
387
+ isConnected
388
+ ? "bg-success"
389
+ : isVendorApprovalPending
390
+ ? "bg-amber-500"
391
+ : "bg-muted-foreground",
338
392
  )}
339
393
  aria-hidden="true"
340
394
  />
341
- {isConnected ? "Signed in" : "Sign-in required"}
395
+ {isConnected ? "Signed in" : isVendorApprovalPending ? "Pending approval" : "Sign-in required"}
342
396
  </span>
343
397
  <button
344
398
  type="button"
345
399
  onClick={onSignIn}
346
- disabled={isBusy}
400
+ disabled={signInDisabled}
347
401
  className={cn(
348
402
  "inline-flex items-center gap-1 rounded px-2 py-0.5 text-[0.65rem] font-medium",
349
403
  isConnected
@@ -361,6 +415,21 @@ function InlineOAuthSignIn({
361
415
  )}
362
416
  </button>
363
417
  </div>
418
+ {isVendorApprovalPending && !isConnected && (
419
+ <div className="text-[0.65rem] text-amber-700 dark:text-amber-300">
420
+ <p>OAuth sign-in is pending vendor approval.</p>
421
+ {vendorApprovalDocsUrl && (
422
+ <a
423
+ href={vendorApprovalDocsUrl}
424
+ target="_blank"
425
+ rel="noopener noreferrer"
426
+ className="underline decoration-amber-600/40 underline-offset-2 hover:decoration-amber-600 dark:decoration-amber-400/40 dark:hover:decoration-amber-400"
427
+ >
428
+ Learn how to bring your own token
429
+ </a>
430
+ )}
431
+ </div>
432
+ )}
364
433
  {error && (
365
434
  <div className="flex items-start gap-1.5 text-[0.65rem] text-destructive">
366
435
  <span className="flex-1">{error.message}</span>
@@ -373,6 +442,15 @@ function InlineOAuthSignIn({
373
442
  </button>
374
443
  </div>
375
444
  )}
445
+ {onSwitchToManual && !isConnected && !isBusy && (
446
+ <button
447
+ type="button"
448
+ onClick={onSwitchToManual}
449
+ className="text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground"
450
+ >
451
+ Enter token manually
452
+ </button>
453
+ )}
376
454
  </div>
377
455
  );
378
456
  }