Repository navigation
Expand file tree
/
Copy pathrpc_mcp_config.e2e.test.ts
More file actions
137 lines (118 loc) · 5.2 KB
/
Copy pathrpc_mcp_config.e2e.test.ts
File metadata and controls
137 lines (118 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
import { describe, expect, it, onTestFinished } from "vitest";
import { CopilotClient } from "../../src/index.js";
function startEphemeralClient(): CopilotClient {
const client = new CopilotClient();
onTestFinished(async () => {
try {
await client.stop();
} catch {
// Ignore cleanup errors
}
});
return client;
}
function uniqueName(prefix: string): string {
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
}
type ServerEntry = Record<string, unknown>;
function getServerConfig(list: { servers: Record<string, unknown> }, name: string): ServerEntry {
expect(list.servers).toHaveProperty(name);
const entry = list.servers[name] as ServerEntry;
expect(entry).toBeDefined();
return entry;
}
describe("Server-scoped MCP config RPC", () => {
it("should call server mcp config rpcs", async () => {
const client = startEphemeralClient();
await client.start();
const serverName = uniqueName("sdk-test");
const config = {
type: "local" as const,
command: "node",
args: [] as string[],
};
const updatedConfig = {
type: "local" as const,
command: "node",
args: ["--version"],
};
const initial = await client.rpc.mcp.config.list();
expect(initial.servers[serverName]).toBeUndefined();
try {
await client.rpc.mcp.config.add({ name: serverName, config });
const afterAdd = await client.rpc.mcp.config.list();
expect(afterAdd.servers[serverName]).toBeDefined();
await client.rpc.mcp.config.update({ name: serverName, config: updatedConfig });
const afterUpdate = await client.rpc.mcp.config.list();
const updated = getServerConfig(afterUpdate, serverName) as {
command?: string;
args?: string[];
};
expect(updated.command).toBe("node");
expect(updated.args?.[0]).toBe("--version");
await client.rpc.mcp.config.disable({ names: [serverName] });
await client.rpc.mcp.config.enable({ names: [serverName] });
} finally {
await client.rpc.mcp.config.remove({ name: serverName });
}
const afterRemove = await client.rpc.mcp.config.list();
expect(afterRemove.servers[serverName]).toBeUndefined();
await client.stop();
});
it("should roundtrip http mcp oauth config rpc", async () => {
const client = startEphemeralClient();
await client.start();
const serverName = uniqueName("sdk-http-oauth");
const config = {
type: "http" as const,
url: "https://example.com/mcp",
headers: { Authorization: "Bearer token" } as Record<string, string>,
oauthClientId: "client-id",
oauthPublicClient: false,
oauthGrantType: "client_credentials" as const,
tools: ["*"],
timeout: 3000,
};
const updatedConfig = {
type: "http" as const,
url: "https://example.com/updated-mcp",
oauthClientId: "updated-client-id",
oauthPublicClient: true,
oauthGrantType: "authorization_code" as const,
tools: ["updated-tool"],
timeout: 4000,
};
try {
await client.rpc.mcp.config.add({ name: serverName, config });
const afterAdd = await client.rpc.mcp.config.list();
const added = getServerConfig(afterAdd, serverName) as Record<string, unknown> & {
headers?: Record<string, string>;
};
expect(added.type).toBe("http");
expect(added.url).toBe("https://example.com/mcp");
expect(added.headers?.Authorization).toBe("Bearer token");
expect(added.oauthClientId).toBe("client-id");
expect(added.oauthPublicClient).toBe(false);
expect(added.oauthGrantType).toBe("client_credentials");
await client.rpc.mcp.config.update({ name: serverName, config: updatedConfig });
const afterUpdate = await client.rpc.mcp.config.list();
const updated = getServerConfig(afterUpdate, serverName) as Record<string, unknown> & {
tools?: string[];
};
expect(updated.url).toBe("https://example.com/updated-mcp");
expect(updated.oauthClientId).toBe("updated-client-id");
expect(updated.oauthPublicClient).toBe(true);
expect(updated.oauthGrantType).toBe("authorization_code");
expect(updated.tools?.[0]).toBe("updated-tool");
expect(updated.timeout).toBe(4000);
} finally {
await client.rpc.mcp.config.remove({ name: serverName });
}
const afterRemove = await client.rpc.mcp.config.list();
expect(afterRemove.servers[serverName]).toBeUndefined();
await client.stop();
});
});