@stigmer/react 3.1.6 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mcp-server/McpServerConnectDialog.d.ts.map +1 -1
- package/mcp-server/McpServerConnectDialog.js +7 -3
- package/mcp-server/McpServerConnectDialog.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +6 -3
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/McpServerPicker.d.ts.map +1 -1
- package/mcp-server/McpServerPicker.js +3 -1
- package/mcp-server/McpServerPicker.js.map +1 -1
- package/mcp-server/OAuthRequiredNotice.d.ts +29 -0
- package/mcp-server/OAuthRequiredNotice.d.ts.map +1 -0
- package/mcp-server/OAuthRequiredNotice.js +29 -0
- package/mcp-server/OAuthRequiredNotice.js.map +1 -0
- package/mcp-server/StdioSandboxNotice.d.ts +43 -0
- package/mcp-server/StdioSandboxNotice.d.ts.map +1 -0
- package/mcp-server/StdioSandboxNotice.js +45 -0
- package/mcp-server/StdioSandboxNotice.js.map +1 -0
- package/mcp-server/useMcpServerCredentials.d.ts +12 -0
- package/mcp-server/useMcpServerCredentials.d.ts.map +1 -1
- package/mcp-server/useMcpServerCredentials.js +12 -4
- package/mcp-server/useMcpServerCredentials.js.map +1 -1
- package/package.json +4 -4
- package/src/mcp-server/McpServerConnectDialog.tsx +23 -11
- package/src/mcp-server/McpServerDetailView.tsx +22 -9
- package/src/mcp-server/McpServerPicker.tsx +12 -9
- package/src/mcp-server/OAuthRequiredNotice.tsx +77 -0
- package/src/mcp-server/StdioSandboxNotice.tsx +98 -0
- package/src/mcp-server/__tests__/OAuthRequiredNotice.test.tsx +25 -0
- package/src/mcp-server/__tests__/StdioSandboxNotice.test.tsx +71 -0
- package/src/mcp-server/useMcpServerCredentials.ts +25 -4
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { render, screen, cleanup } from "@testing-library/react";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import type { McpServerSpec } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/spec_pb";
|
|
5
|
+
import { DeploymentModeContext } from "../../deployment-mode";
|
|
6
|
+
import { StdioSandboxNotice, isStdioInCloud } from "../StdioSandboxNotice";
|
|
7
|
+
|
|
8
|
+
type McpServerType = McpServerSpec["serverType"];
|
|
9
|
+
|
|
10
|
+
const STDIO = { case: "stdio" } as McpServerType;
|
|
11
|
+
const HTTP = { case: "http" } as McpServerType;
|
|
12
|
+
const UNSET = { case: undefined } as McpServerType;
|
|
13
|
+
|
|
14
|
+
afterEach(cleanup);
|
|
15
|
+
|
|
16
|
+
describe("isStdioInCloud", () => {
|
|
17
|
+
it("is true only for stdio transport in cloud mode", () => {
|
|
18
|
+
expect(isStdioInCloud("cloud", STDIO)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("is false for stdio transport in local mode", () => {
|
|
22
|
+
expect(isStdioInCloud("local", STDIO)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("is false for http transport in cloud mode", () => {
|
|
26
|
+
expect(isStdioInCloud("cloud", HTTP)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("is false when the transport oneof is unset", () => {
|
|
30
|
+
expect(isStdioInCloud("cloud", UNSET)).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("is false when serverType is undefined", () => {
|
|
34
|
+
expect(isStdioInCloud("cloud", undefined)).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function withMode(mode: "cloud" | "local", children: ReactNode) {
|
|
39
|
+
return (
|
|
40
|
+
<DeploymentModeContext.Provider value={mode}>
|
|
41
|
+
{children}
|
|
42
|
+
</DeploymentModeContext.Provider>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
describe("StdioSandboxNotice", () => {
|
|
47
|
+
it("renders the sandbox-isolation caveat for stdio in cloud", () => {
|
|
48
|
+
render(withMode("cloud", <StdioSandboxNotice serverType={STDIO} />));
|
|
49
|
+
expect(screen.getByRole("status")).toBeTruthy();
|
|
50
|
+
expect(screen.getByText(/isolated cloud sandbox/i)).toBeTruthy();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("does not suggest the CLI (avoids inaccurate guidance)", () => {
|
|
54
|
+
render(withMode("cloud", <StdioSandboxNotice serverType={STDIO} />));
|
|
55
|
+
expect(screen.queryByText(/stigmer connect/i)).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("renders nothing for http servers in cloud", () => {
|
|
59
|
+
const { container } = render(
|
|
60
|
+
withMode("cloud", <StdioSandboxNotice serverType={HTTP} />),
|
|
61
|
+
);
|
|
62
|
+
expect(container.firstChild).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("renders nothing for stdio servers in local mode", () => {
|
|
66
|
+
const { container } = render(
|
|
67
|
+
withMode("local", <StdioSandboxNotice serverType={STDIO} />),
|
|
68
|
+
);
|
|
69
|
+
expect(container.firstChild).toBeNull();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -153,6 +153,18 @@ export interface UseMcpServerCredentialsReturn {
|
|
|
153
153
|
* link (when vendor approval is granted).
|
|
154
154
|
*/
|
|
155
155
|
readonly canBringOwnApp: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* `true` when a manually-entered static token is a valid way to
|
|
158
|
+
* authenticate this server. `false` for `oauth_only` servers whose
|
|
159
|
+
* hosted endpoint rejects static tokens (`spec.auth.oauth_only`), where
|
|
160
|
+
* OAuth is the sole credential path.
|
|
161
|
+
*
|
|
162
|
+
* Connect surfaces use this to decide whether to offer the "enter token
|
|
163
|
+
* manually" affordance — offering it on an `oauth_only` server would send
|
|
164
|
+
* the user down a path that cannot succeed. Always `true` for manual-only
|
|
165
|
+
* and PAT-capable servers.
|
|
166
|
+
*/
|
|
167
|
+
readonly manualEntrySupported: boolean;
|
|
156
168
|
/**
|
|
157
169
|
* When `true`, the user has opted to bypass OAuth and enter the
|
|
158
170
|
* `target_env_var` token manually. In this state:
|
|
@@ -251,6 +263,14 @@ export function useMcpServerCredentials(
|
|
|
251
263
|
const oauthTargetEnvVar = auth?.targetEnvVar || null;
|
|
252
264
|
const tokenLifetimeHint = auth?.tokenLifetimeHint || null;
|
|
253
265
|
|
|
266
|
+
// A static token is a valid credential for every server except those whose
|
|
267
|
+
// endpoint declares it rejects them (`oauth_only`). This is the single source
|
|
268
|
+
// of truth the connect surfaces consult before offering manual entry.
|
|
269
|
+
const manualEntrySupported = !auth?.oauthOnly;
|
|
270
|
+
// Defensively force manual override off for oauth_only servers so no surface
|
|
271
|
+
// can enter a dead-end manual-entry state, even if a stale toggle is set.
|
|
272
|
+
const effectiveManualOverride = manualOverride && manualEntrySupported;
|
|
273
|
+
|
|
254
274
|
const oauthStatus = mcpServer?.status?.oauthStatus;
|
|
255
275
|
const isVendorApprovalPending =
|
|
256
276
|
authMode === "oauth" &&
|
|
@@ -298,15 +318,15 @@ export function useMcpServerCredentials(
|
|
|
298
318
|
);
|
|
299
319
|
|
|
300
320
|
const missingVariables = useMemo(() => {
|
|
301
|
-
if (!oauthTargetEnvVar ||
|
|
321
|
+
if (!oauthTargetEnvVar || effectiveManualOverride) return requiredMissing;
|
|
302
322
|
return requiredMissing.filter((v) => v.key !== oauthTargetEnvVar);
|
|
303
|
-
}, [requiredMissing, oauthTargetEnvVar,
|
|
323
|
+
}, [requiredMissing, oauthTargetEnvVar, effectiveManualOverride]);
|
|
304
324
|
|
|
305
325
|
const isReady =
|
|
306
326
|
!personalEnv.isLoading &&
|
|
307
327
|
!grantStatus.isLoading &&
|
|
308
328
|
missingVariables.length === 0 &&
|
|
309
|
-
(authMode === "manual" ||
|
|
329
|
+
(authMode === "manual" || effectiveManualOverride || isOAuthConnected);
|
|
310
330
|
|
|
311
331
|
const saveCredentials = useCallback(
|
|
312
332
|
async (values: Record<string, EnvVarInput>): Promise<void> => {
|
|
@@ -335,6 +355,7 @@ export function useMcpServerCredentials(
|
|
|
335
355
|
effectiveOAuthSource,
|
|
336
356
|
isOrgOAuthApp,
|
|
337
357
|
canBringOwnApp,
|
|
358
|
+
manualEntrySupported,
|
|
338
359
|
missingVariables,
|
|
339
360
|
isReady,
|
|
340
361
|
isLoading: personalEnv.isLoading || grantStatus.isLoading,
|
|
@@ -342,7 +363,7 @@ export function useMcpServerCredentials(
|
|
|
342
363
|
saveCredentials,
|
|
343
364
|
isSaving: personalEnv.isMutating,
|
|
344
365
|
refetch,
|
|
345
|
-
manualOverride,
|
|
366
|
+
manualOverride: effectiveManualOverride,
|
|
346
367
|
setManualOverride,
|
|
347
368
|
};
|
|
348
369
|
}
|