@metorial/mcp-server 1.0.0-rc.3 → 1.0.0-rc.5

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/src/auth.ts CHANGED
@@ -1,28 +1,28 @@
1
1
  import z from 'zod';
2
2
 
3
- export type McpServerAuthUrlHandlerParams<AuthConfig extends {}> = {
4
- authConfig: AuthConfig;
3
+ export type McpServerOAuthUrlHandlerParams<OAuthConfig extends {}> = {
4
+ authConfig: OAuthConfig;
5
5
  clientId: string;
6
6
  clientSecret: string;
7
7
  state: string;
8
8
  redirectUri: string;
9
9
  };
10
10
 
11
- export type McpServerAuthUrlHandlerResult = {
11
+ export type McpServerOAuthUrlHandlerResult = {
12
12
  authorizationUrl: string;
13
13
  authState?: Record<string, string> | null;
14
14
  };
15
15
 
16
- export type McpServerAuthUrlHandlerInternal = <AuthConfig extends {}>(
17
- d: McpServerAuthUrlHandlerParams<AuthConfig>
18
- ) => Promise<McpServerAuthUrlHandlerResult>;
16
+ export type McpServerOAuthUrlHandlerInternal = <OAuthConfig extends {}>(
17
+ d: McpServerOAuthUrlHandlerParams<OAuthConfig>
18
+ ) => Promise<McpServerOAuthUrlHandlerResult>;
19
19
 
20
- export type McpServerAuthUrlHandler = <AuthConfig extends {}>(
21
- d: McpServerAuthUrlHandlerParams<AuthConfig>
22
- ) => Promise<string | McpServerAuthUrlHandlerResult>;
20
+ export type McpServerOAuthUrlHandler = <OAuthConfig extends {}>(
21
+ d: McpServerOAuthUrlHandlerParams<OAuthConfig>
22
+ ) => Promise<string | McpServerOAuthUrlHandlerResult>;
23
23
 
24
- export type McpServerAuthCallbackHandlerParams<AuthConfig extends {}> = {
25
- authConfig: AuthConfig;
24
+ export type McpServerOAuthCallbackHandlerParams<OAuthConfig extends {}> = {
25
+ authConfig: OAuthConfig;
26
26
  authState: Record<string, string>;
27
27
  clientId: string;
28
28
  clientSecret: string;
@@ -33,7 +33,7 @@ export type McpServerAuthCallbackHandlerParams<AuthConfig extends {}> = {
33
33
  authorizationUrl: string;
34
34
  };
35
35
 
36
- export type McpServerAuthCallbackHandlerResult = {
36
+ export type McpServerOAuthCallbackHandlerResult = {
37
37
  accessToken: string;
38
38
  refreshToken?: string;
39
39
  expiresIn?: number;
@@ -42,19 +42,19 @@ export type McpServerAuthCallbackHandlerResult = {
42
42
  [key: string]: any;
43
43
  };
44
44
 
45
- export type McpServerAuthCallbackHandler = <AuthConfig extends {}>(
46
- d: McpServerAuthCallbackHandlerParams<AuthConfig>
47
- ) => Promise<McpServerAuthCallbackHandlerResult>;
45
+ export type McpServerOAuthCallbackHandler = <OAuthConfig extends {}>(
46
+ d: McpServerOAuthCallbackHandlerParams<OAuthConfig>
47
+ ) => Promise<McpServerOAuthCallbackHandlerResult>;
48
48
 
49
- export type McpServerAuthTokenRefreshHandlerParams<AuthConfig extends {}> = {
50
- authConfig: AuthConfig;
49
+ export type McpServerOAuthTokenRefreshHandlerParams<OAuthConfig extends {}> = {
50
+ authConfig: OAuthConfig;
51
51
  authState: Record<string, string>;
52
52
  refreshToken: string;
53
53
  clientId: string;
54
54
  clientSecret: string;
55
55
  };
56
56
 
57
- export type McpServerAuthTokenRefreshHandlerResult = {
57
+ export type McpServerOAuthTokenRefreshHandlerResult = {
58
58
  accessToken: string;
59
59
  refreshToken?: string;
60
60
  expiresIn?: number;
@@ -63,11 +63,17 @@ export type McpServerAuthTokenRefreshHandlerResult = {
63
63
  [key: string]: any;
64
64
  };
65
65
 
66
- export type McpServerAuthTokenRefreshHandler = <AuthConfig extends {}>(
67
- d: McpServerAuthTokenRefreshHandlerParams<AuthConfig>
68
- ) => Promise<McpServerAuthTokenRefreshHandlerResult>;
66
+ export type McpServerOAuthTokenHandlers = {
67
+ getAuthorizationUrl: McpServerOAuthUrlHandler;
68
+ handleCallback: McpServerOAuthCallbackHandler;
69
+ refreshToken?: McpServerOAuthTokenRefreshHandler;
70
+ };
71
+
72
+ export type McpServerOAuthTokenRefreshHandler = <OAuthConfig extends {}>(
73
+ d: McpServerOAuthTokenRefreshHandlerParams<OAuthConfig>
74
+ ) => Promise<McpServerOAuthTokenRefreshHandlerResult>;
69
75
 
70
- export type McpServerAuthValue = {
76
+ export type McpServerOAuthValue = {
71
77
  accessToken: string;
72
78
  expiresIn?: number;
73
79
  scope?: string;
@@ -75,36 +81,63 @@ export type McpServerAuthValue = {
75
81
  [key: string]: any;
76
82
  };
77
83
 
78
- export class McpServerAuthConfig<AuthConfig extends {}> {
79
- #value: McpServerAuthValue | null = null;
84
+ export let authConfigs = new Set<McpServerOAuthConfig<any>>();
85
+
86
+ export class McpServerOAuthConfig<OAuthConfig extends {}> {
87
+ #value: McpServerOAuthValue | null = null;
88
+ #isRegistered = false;
89
+
90
+ #getAuthUrlHandler?: McpServerOAuthUrlHandlerInternal;
91
+ #callbackHandler?: McpServerOAuthCallbackHandler;
92
+ #tokenRefreshHandler?: McpServerOAuthTokenRefreshHandler;
93
+
94
+ private constructor(public readonly schema: z.ZodType<OAuthConfig>) {
95
+ authConfigs.add(this);
96
+ }
97
+
98
+ static create<OAuthConfig extends {}>(
99
+ ...args:
100
+ | [z.ZodType<OAuthConfig>, McpServerOAuthTokenHandlers]
101
+ | [McpServerOAuthTokenHandlers]
102
+ ) {
103
+ let schema = args.length == 2 ? args[0] : undefined;
104
+ let handlers = args.length == 2 ? args[1] : args[0];
80
105
 
81
- #getAuthUrlHandler?: McpServerAuthUrlHandlerInternal;
82
- #callbackHandler?: McpServerAuthCallbackHandler;
83
- #tokenRefreshHandler?: McpServerAuthTokenRefreshHandler;
106
+ let config = new McpServerOAuthConfig(schema ?? (z.object({}) as z.ZodType<OAuthConfig>));
84
107
 
85
- private constructor(public readonly schema: z.ZodType<AuthConfig>) {}
108
+ config.getAuthorizationUrl(handlers.getAuthorizationUrl);
109
+ config.handleCallback(handlers.handleCallback);
110
+ if (handlers.refreshToken) {
111
+ config.refreshToken(handlers.refreshToken);
112
+ }
86
113
 
87
- static create<AuthConfig extends {}>(schema?: z.ZodType<AuthConfig>) {
88
- return new McpServerAuthConfig(schema ?? (z.object({}) as z.ZodType<AuthConfig>));
114
+ return config.build();
89
115
  }
90
116
 
91
- static getImplementation(config: McpServerAuthConfig<any>) {
117
+ static getImplementation(config: McpServerOAuthConfig<any>) {
92
118
  if (!config.#getAuthUrlHandler || !config.#callbackHandler) {
93
119
  throw new Error('MCP Server auth config is missing required handlers');
94
120
  }
95
121
 
96
122
  return {
123
+ setValue: config.setValue.bind(config),
124
+ registered: config.registered.bind(config),
125
+
97
126
  getAuthUrlHandler: config.#getAuthUrlHandler,
98
127
  callbackHandler: config.#callbackHandler,
99
128
  tokenRefreshHandler: config.#tokenRefreshHandler
100
129
  };
101
130
  }
102
131
 
103
- setValue(value: McpServerAuthValue) {
104
- this.#value = value;
132
+ static assertRegistered(config: McpServerOAuthConfig<any>) {
133
+ if (!config.#isRegistered) {
134
+ throw new Error(
135
+ 'MCP Server auth config is not registered with `createMcpServer`. Please pass your OAuth config as `authConfig` when creating the server.'
136
+ );
137
+ }
105
138
  }
106
139
 
107
- getAuthorizationUrl(cb: McpServerAuthUrlHandler) {
140
+ getAuthorizationUrl(cb: McpServerOAuthUrlHandler) {
108
141
  this.#getAuthUrlHandler = async d => {
109
142
  let res = await cb(d);
110
143
  if (typeof res == 'string') {
@@ -115,17 +148,17 @@ export class McpServerAuthConfig<AuthConfig extends {}> {
115
148
  return this;
116
149
  }
117
150
 
118
- handleCallback(cb: McpServerAuthCallbackHandler) {
151
+ handleCallback(cb: McpServerOAuthCallbackHandler) {
119
152
  this.#callbackHandler = cb;
120
153
  return this;
121
154
  }
122
155
 
123
- refreshToken(cb: McpServerAuthTokenRefreshHandler) {
156
+ refreshToken(cb: McpServerOAuthTokenRefreshHandler) {
124
157
  this.#tokenRefreshHandler = cb;
125
158
  return this;
126
159
  }
127
160
 
128
- build(): AuthConfig {
161
+ build(): OAuthConfig {
129
162
  if (!this.#getAuthUrlHandler || !this.#callbackHandler) {
130
163
  throw new Error('MCP Server auth config is missing required handlers');
131
164
  }
@@ -142,38 +175,57 @@ export class McpServerAuthConfig<AuthConfig extends {}> {
142
175
  return self;
143
176
  }
144
177
 
145
- if (self.#value === null) {
146
- throw new Error('MCP Server auth config value not set');
178
+ if (self.#value === null || !self.#isRegistered) {
179
+ throw new Error(
180
+ 'MCP Server auth config is not registered with `createMcpServer`. Please pass your OAuth config as `authConfig` when creating the server.'
181
+ );
147
182
  }
148
183
 
149
184
  return (self.#value as any)[prop];
150
185
  }
151
186
  }
152
- ) as any as AuthConfig;
187
+ ) as any as OAuthConfig;
188
+ }
189
+
190
+ private setValue(value: McpServerOAuthValue) {
191
+ this.#value = value;
192
+ }
193
+
194
+ private registered() {
195
+ this.#isRegistered = true;
153
196
  }
154
197
  }
155
198
 
156
- export let createAuth = <Config extends {}>(schema?: z.ZodType<Config>) => {
157
- return McpServerAuthConfig.create(schema);
158
- };
199
+ export let createOAuth = <Config extends {}>(
200
+ ...args: [z.ZodType<Config>, McpServerOAuthTokenHandlers] | [McpServerOAuthTokenHandlers]
201
+ ) => McpServerOAuthConfig.create(...args);
159
202
 
160
- export let auth = <Config extends {}>(schema?: z.ZodType<Config>) => createAuth(schema);
203
+ export let oAuth = createOAuth;
161
204
 
162
- export let getAuthConfigImplementation = <Config extends {}>(configValue: any) => {
163
- let self = configValue['__config__'] as McpServerAuthConfig<Config>;
164
- return McpServerAuthConfig.getImplementation(self);
205
+ export let getOAuthConfigImplementation = <Config extends {}>(configValue: any) => {
206
+ let self = configValue['__config__'] as McpServerOAuthConfig<Config>;
207
+ return McpServerOAuthConfig.getImplementation(self);
165
208
  };
166
209
 
167
- export let setAuthConfigValue = <Config extends {}>(
210
+ export let setOAuthConfigValue = <Config extends {}>(
168
211
  configValue: any,
169
- value: McpServerAuthValue
212
+ value: McpServerOAuthValue
170
213
  ) => {
171
- let self = configValue['__config__'] as McpServerAuthConfig<Config>;
172
- self.setValue(value);
214
+ let self = configValue['__config__'] as McpServerOAuthConfig<Config>;
215
+ let impl = McpServerOAuthConfig.getImplementation(self);
216
+
217
+ impl.setValue(value);
218
+ impl.registered();
219
+ };
220
+
221
+ export let registerOAuthConfig = <Config extends {}>(configValue: any) => {
222
+ let self = configValue['__config__'] as McpServerOAuthConfig<Config>;
223
+ let impl = McpServerOAuthConfig.getImplementation(self);
224
+ impl.registered();
173
225
  };
174
226
 
175
- export let getAuthConfigSchema = <Config extends {}>(configValue: any) => {
176
- let self = configValue['__config__'] as McpServerAuthConfig<Config>;
227
+ export let getOAuthConfigSchema = <Config extends {}>(configValue: any) => {
228
+ let self = configValue['__config__'] as McpServerOAuthConfig<Config>;
177
229
  return self.schema.toJSONSchema({
178
230
  unrepresentable: 'any',
179
231
  override: ctx => {
package/src/config.ts CHANGED
@@ -1,19 +1,36 @@
1
1
  import z from 'zod';
2
2
 
3
+ export let configs = new Set<McpServerConfig<any>>();
4
+
3
5
  export class McpServerConfig<Config extends {}> {
4
6
  #value: Config | null = null;
7
+ #isRegistered = false;
5
8
 
6
- private constructor(public readonly schema: z.ZodType<Config>) {}
9
+ private constructor(public readonly schema: z.ZodType<Config>) {
10
+ configs.add(this);
11
+ }
7
12
 
8
13
  static create<Config extends {}>(schema: z.ZodType<Config>) {
9
14
  return new McpServerConfig(schema);
10
15
  }
11
16
 
17
+ static assertRegistered(config: McpServerConfig<any>) {
18
+ if (!config.#isRegistered) {
19
+ throw new Error(
20
+ 'MCP Server config is not registered with `createMcpServer`. Please pass your config as `config` when creating the server.'
21
+ );
22
+ }
23
+ }
24
+
12
25
  setValue(value: unknown) {
13
26
  let parsed = this.schema.parse(value);
14
27
  this.#value = parsed;
15
28
  }
16
29
 
30
+ registered() {
31
+ this.#isRegistered = true;
32
+ }
33
+
17
34
  value(): Config {
18
35
  let self = this;
19
36
 
@@ -27,8 +44,10 @@ export class McpServerConfig<Config extends {}> {
27
44
  return self;
28
45
  }
29
46
 
30
- if (self.#value === null) {
31
- throw new Error('MCP Server config value not set');
47
+ if (self.#value === null || !self.#isRegistered) {
48
+ throw new Error(
49
+ 'MCP Server config is not registered with `createMcpServer`. Please pass your config as `config` when creating the server.'
50
+ );
32
51
  }
33
52
 
34
53
  return (self.#value as any)[prop];
@@ -47,6 +66,12 @@ export let config = <Config extends {}>(schema: z.ZodType<Config>) => createConf
47
66
  export let setConfigValue = <Config extends {}>(configValue: any, value: Config) => {
48
67
  let self = configValue['__config__'] as McpServerConfig<Config>;
49
68
  self.setValue(value);
69
+ self.registered();
70
+ };
71
+
72
+ export let registerConfig = <Config extends {}>(configValue: any) => {
73
+ let self = configValue['__config__'] as McpServerConfig<Config>;
74
+ self.registered();
50
75
  };
51
76
 
52
77
  export let getConfigSchema = <Config extends {}>(configValue: any) => {
package/src/index.ts CHANGED
@@ -13,20 +13,20 @@ export {
13
13
  } from './adapter';
14
14
 
15
15
  export {
16
- auth,
17
- createAuth,
18
- type McpServerAuthCallbackHandler,
19
- type McpServerAuthCallbackHandlerParams,
20
- type McpServerAuthCallbackHandlerResult,
21
- type McpServerAuthConfig,
22
- type McpServerAuthTokenRefreshHandler,
23
- type McpServerAuthTokenRefreshHandlerParams,
24
- type McpServerAuthTokenRefreshHandlerResult,
25
- type McpServerAuthUrlHandler,
26
- type McpServerAuthUrlHandlerInternal,
27
- type McpServerAuthUrlHandlerParams,
28
- type McpServerAuthUrlHandlerResult,
29
- type McpServerAuthValue
16
+ createOAuth,
17
+ oAuth,
18
+ type McpServerOAuthCallbackHandler,
19
+ type McpServerOAuthCallbackHandlerParams,
20
+ type McpServerOAuthCallbackHandlerResult,
21
+ type McpServerOAuthConfig,
22
+ type McpServerOAuthTokenRefreshHandler,
23
+ type McpServerOAuthTokenRefreshHandlerParams,
24
+ type McpServerOAuthTokenRefreshHandlerResult,
25
+ type McpServerOAuthUrlHandler,
26
+ type McpServerOAuthUrlHandlerInternal,
27
+ type McpServerOAuthUrlHandlerParams,
28
+ type McpServerOAuthUrlHandlerResult,
29
+ type McpServerOAuthValue
30
30
  } from './auth';
31
31
 
32
32
  export { config, createConfig, type McpServerConfig } from './config';
package/src/instance.ts CHANGED
@@ -5,15 +5,24 @@ import {
5
5
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
6
  import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
7
7
  import {
8
- getAuthConfigImplementation,
9
- getAuthConfigSchema,
10
- McpServerAuthCallbackHandlerParams,
11
- McpServerAuthTokenRefreshHandlerParams,
12
- McpServerAuthUrlHandlerParams,
13
- setAuthConfigValue
8
+ authConfigs,
9
+ getOAuthConfigImplementation,
10
+ getOAuthConfigSchema,
11
+ McpServerOAuthCallbackHandlerParams,
12
+ McpServerOAuthConfig,
13
+ McpServerOAuthTokenRefreshHandlerParams,
14
+ McpServerOAuthUrlHandlerParams,
15
+ registerOAuthConfig,
16
+ setOAuthConfigValue
14
17
  } from './auth';
15
18
  import { ClientOpts, handleMcpMessages } from './client';
16
- import { getConfigSchema, setConfigValue } from './config';
19
+ import {
20
+ configs,
21
+ getConfigSchema,
22
+ McpServerConfig,
23
+ registerConfig,
24
+ setConfigValue
25
+ } from './config';
17
26
 
18
27
  export type McpServerInstanceServer = CreateMcpServerOpts | { server: McpServer };
19
28
  let getServer = (instance: McpServerInstanceServer) => {
@@ -33,6 +42,12 @@ export class McpServerInstance {
33
42
  #server: McpServer;
34
43
 
35
44
  private constructor(private instance: McpServerInstanceOpts) {
45
+ if (instance.config) registerConfig(instance.config);
46
+ if (instance.authConfig) registerOAuthConfig(instance.authConfig);
47
+
48
+ for (let ac of authConfigs) McpServerOAuthConfig.assertRegistered(ac);
49
+ for (let co of configs) McpServerConfig.assertRegistered(co);
50
+
36
51
  this.#server = getServer(instance);
37
52
  }
38
53
 
@@ -46,8 +61,8 @@ export class McpServerInstance {
46
61
  oauth: this.instance.authConfig
47
62
  ? {
48
63
  status: 'enabled' as const,
49
- authConfig: getAuthConfigSchema(this.instance.authConfig),
50
- hasTokenRefresh: !!getAuthConfigImplementation(this.instance.authConfig)
64
+ authConfig: getOAuthConfigSchema(this.instance.authConfig),
65
+ hasTokenRefresh: !!getOAuthConfigImplementation(this.instance.authConfig)
51
66
  .tokenRefreshHandler
52
67
  }
53
68
  : {
@@ -66,29 +81,29 @@ export class McpServerInstance {
66
81
  setConfigValue(this.instance.config, opts.config);
67
82
  }
68
83
  if (opts.authConfig && this.instance.authConfig) {
69
- setAuthConfigValue(this.instance.authConfig, opts.authConfig);
84
+ setOAuthConfigValue(this.instance.authConfig, opts.authConfig);
70
85
  }
71
86
 
72
87
  return handleMcpMessages(this.#server, opts.client, opts.message);
73
88
  }
74
89
 
75
- getOauthAuthorizationUrl(d: McpServerAuthUrlHandlerParams<any>) {
90
+ getOauthAuthorizationUrl(d: McpServerOAuthUrlHandlerParams<any>) {
76
91
  if (!this.instance.authConfig) return null;
77
- let impl = getAuthConfigImplementation(this.instance.authConfig);
92
+ let impl = getOAuthConfigImplementation(this.instance.authConfig);
78
93
 
79
94
  return impl.getAuthUrlHandler(d);
80
95
  }
81
96
 
82
- handleOauthCallback(d: McpServerAuthCallbackHandlerParams<any>) {
97
+ handleOauthCallback(d: McpServerOAuthCallbackHandlerParams<any>) {
83
98
  if (!this.instance.authConfig) return null;
84
- let impl = getAuthConfigImplementation(this.instance.authConfig);
99
+ let impl = getOAuthConfigImplementation(this.instance.authConfig);
85
100
 
86
101
  return impl.callbackHandler(d);
87
102
  }
88
103
 
89
- handleOauthTokenRefresh(d: McpServerAuthTokenRefreshHandlerParams<any>) {
104
+ handleOauthTokenRefresh(d: McpServerOAuthTokenRefreshHandlerParams<any>) {
90
105
  if (!this.instance.authConfig) return null;
91
- let impl = getAuthConfigImplementation(this.instance.authConfig);
106
+ let impl = getOAuthConfigImplementation(this.instance.authConfig);
92
107
 
93
108
  if (!impl.tokenRefreshHandler) {
94
109
  return null;