Skip to content

Commit 11fa257

Browse files
authored
refactor(config): migrate mcp schemas to Effect Schema.Class (#23163)
1 parent 6af8ab0 commit 11fa257

3 files changed

Lines changed: 58 additions & 64 deletions

File tree

packages/opencode/src/config/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export const Info = z
178178
.record(
179179
z.string(),
180180
z.union([
181-
ConfigMCP.Info,
181+
ConfigMCP.Info.zod,
182182
z
183183
.object({
184184
enabled: z.boolean(),
Lines changed: 56 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,62 @@
1-
import z from "zod"
1+
import { Schema } from "effect"
2+
import { zod } from "@/util/effect-zod"
3+
import { withStatics } from "@/util/schema"
24

3-
export const Local = z
4-
.object({
5-
type: z.literal("local").describe("Type of MCP server connection"),
6-
command: z.string().array().describe("Command and arguments to run the MCP server"),
7-
environment: z
8-
.record(z.string(), z.string())
9-
.optional()
10-
.describe("Environment variables to set when running the MCP server"),
11-
enabled: z.boolean().optional().describe("Enable or disable the MCP server on startup"),
12-
timeout: z
13-
.number()
14-
.int()
15-
.positive()
16-
.optional()
17-
.describe("Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified."),
18-
})
19-
.strict()
20-
.meta({
21-
ref: "McpLocalConfig",
22-
})
5+
export class Local extends Schema.Class<Local>("McpLocalConfig")({
6+
type: Schema.Literal("local").annotate({ description: "Type of MCP server connection" }),
7+
command: Schema.mutable(Schema.Array(Schema.String)).annotate({
8+
description: "Command and arguments to run the MCP server",
9+
}),
10+
environment: Schema.optional(Schema.Record(Schema.String, Schema.String)).annotate({
11+
description: "Environment variables to set when running the MCP server",
12+
}),
13+
enabled: Schema.optional(Schema.Boolean).annotate({
14+
description: "Enable or disable the MCP server on startup",
15+
}),
16+
timeout: Schema.optional(Schema.Number).annotate({
17+
description: "Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified.",
18+
}),
19+
}) {
20+
static readonly zod = zod(this)
21+
}
2322

24-
export const OAuth = z
25-
.object({
26-
clientId: z
27-
.string()
28-
.optional()
29-
.describe("OAuth client ID. If not provided, dynamic client registration (RFC 7591) will be attempted."),
30-
clientSecret: z.string().optional().describe("OAuth client secret (if required by the authorization server)"),
31-
scope: z.string().optional().describe("OAuth scopes to request during authorization"),
32-
redirectUri: z
33-
.string()
34-
.optional()
35-
.describe("OAuth redirect URI (default: http://127.0.0.1:19876/mcp/oauth/callback)."),
36-
})
37-
.strict()
38-
.meta({
39-
ref: "McpOAuthConfig",
40-
})
41-
export type OAuth = z.infer<typeof OAuth>
23+
export class OAuth extends Schema.Class<OAuth>("McpOAuthConfig")({
24+
clientId: Schema.optional(Schema.String).annotate({
25+
description: "OAuth client ID. If not provided, dynamic client registration (RFC 7591) will be attempted.",
26+
}),
27+
clientSecret: Schema.optional(Schema.String).annotate({
28+
description: "OAuth client secret (if required by the authorization server)",
29+
}),
30+
scope: Schema.optional(Schema.String).annotate({ description: "OAuth scopes to request during authorization" }),
31+
redirectUri: Schema.optional(Schema.String).annotate({
32+
description: "OAuth redirect URI (default: http://127.0.0.1:19876/mcp/oauth/callback).",
33+
}),
34+
}) {
35+
static readonly zod = zod(this)
36+
}
4237

43-
export const Remote = z
44-
.object({
45-
type: z.literal("remote").describe("Type of MCP server connection"),
46-
url: z.string().describe("URL of the remote MCP server"),
47-
enabled: z.boolean().optional().describe("Enable or disable the MCP server on startup"),
48-
headers: z.record(z.string(), z.string()).optional().describe("Headers to send with the request"),
49-
oauth: z
50-
.union([OAuth, z.literal(false)])
51-
.optional()
52-
.describe("OAuth authentication configuration for the MCP server. Set to false to disable OAuth auto-detection."),
53-
timeout: z
54-
.number()
55-
.int()
56-
.positive()
57-
.optional()
58-
.describe("Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified."),
59-
})
60-
.strict()
61-
.meta({
62-
ref: "McpRemoteConfig",
63-
})
38+
export class Remote extends Schema.Class<Remote>("McpRemoteConfig")({
39+
type: Schema.Literal("remote").annotate({ description: "Type of MCP server connection" }),
40+
url: Schema.String.annotate({ description: "URL of the remote MCP server" }),
41+
enabled: Schema.optional(Schema.Boolean).annotate({
42+
description: "Enable or disable the MCP server on startup",
43+
}),
44+
headers: Schema.optional(Schema.Record(Schema.String, Schema.String)).annotate({
45+
description: "Headers to send with the request",
46+
}),
47+
oauth: Schema.optional(Schema.Union([OAuth, Schema.Literal(false)])).annotate({
48+
description: "OAuth authentication configuration for the MCP server. Set to false to disable OAuth auto-detection.",
49+
}),
50+
timeout: Schema.optional(Schema.Number).annotate({
51+
description: "Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified.",
52+
}),
53+
}) {
54+
static readonly zod = zod(this)
55+
}
6456

65-
export const Info = z.discriminatedUnion("type", [Local, Remote])
66-
export type Info = z.infer<typeof Info>
57+
export const Info = Schema.Union([Local, Remote])
58+
.annotate({ discriminator: "type" })
59+
.pipe(withStatics((s) => ({ zod: zod(s) })))
60+
export type Info = Schema.Schema.Type<typeof Info>
6761

6862
export * as ConfigMCP from "./mcp"

packages/opencode/src/server/routes/instance/mcp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const McpRoutes = lazy(() =>
5454
"json",
5555
z.object({
5656
name: z.string(),
57-
config: ConfigMCP.Info,
57+
config: ConfigMCP.Info.zod,
5858
}),
5959
),
6060
async (c) => {

0 commit comments

Comments
 (0)