@smithery/sdk 3.0.1 → 4.0.1
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/README.md +4 -47
- package/dist/bundle/config.d.ts +16 -0
- package/dist/bundle/config.js +1 -0
- package/dist/bundle/deploy-payload.d.ts +120 -0
- package/dist/bundle/deploy-payload.js +22 -0
- package/dist/bundle/index.d.ts +7 -0
- package/dist/bundle/index.js +7 -0
- package/dist/bundle/limits.d.ts +7 -0
- package/dist/bundle/limits.js +7 -0
- package/dist/bundle/server-card.d.ts +108 -0
- package/dist/bundle/server-card.js +16 -0
- package/dist/index.d.ts +2 -8
- package/dist/index.js +4 -12
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.js +1 -0
- package/package.json +11 -19
- package/dist/server/auth/identity.d.ts +0 -18
- package/dist/server/auth/identity.js +0 -55
- package/dist/server/auth/oauth.d.ts +0 -21
- package/dist/server/auth/oauth.js +0 -155
- package/dist/server/index.d.ts +0 -5
- package/dist/server/index.js +0 -5
- package/dist/server/logger.d.ts +0 -19
- package/dist/server/logger.js +0 -76
- package/dist/server/session.d.ts +0 -17
- package/dist/server/session.js +0 -36
- package/dist/server/stateful.d.ts +0 -48
- package/dist/server/stateful.js +0 -170
- package/dist/server/stateless.d.ts +0 -46
- package/dist/server/stateless.js +0 -119
- package/dist/shared/config.d.ts +0 -37
- package/dist/shared/config.js +0 -134
- package/dist/shared/patch.d.ts +0 -12
- package/dist/shared/patch.js +0 -12
package/README.md
CHANGED
|
@@ -1,49 +1,6 @@
|
|
|
1
|
-
# Smithery
|
|
1
|
+
# Smithery TypeScript SDK
|
|
2
2
|
|
|
3
|
-
The SDK provides
|
|
3
|
+
The SDK provides the types and bundle manifest schemas for building and deploying MCP servers on Smithery.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @smithery/sdk @modelcontextprotocol/sdk
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
### Spawning a Server
|
|
14
|
-
|
|
15
|
-
Here's a minimal example of how to use the SDK to spawn an MCP server.
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { createStatelessServer } from '@smithery/sdk/server/stateless.js'
|
|
19
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
|
|
20
|
-
|
|
21
|
-
// Create your MCP server function
|
|
22
|
-
function createMcpServer({ config }) {
|
|
23
|
-
// Create and return a server instance
|
|
24
|
-
// https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#core-concepts
|
|
25
|
-
const mcpServer = new McpServer({
|
|
26
|
-
name: "My App",
|
|
27
|
-
version: "1.0.0"
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
// ...
|
|
31
|
-
|
|
32
|
-
return mcpServer.server
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Create the stateless server using your MCP server function.
|
|
36
|
-
createStatelessServer(createMcpServer)
|
|
37
|
-
.app
|
|
38
|
-
.listen(process.env.PORT || 3000)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This example:
|
|
42
|
-
1. Creates a stateless server that handles MCP requests
|
|
43
|
-
2. Defines a function to create MCP server instances for each session
|
|
44
|
-
3. Starts the Express server on the specified port. You must listen on the PORT env var if provided for the deployment to work on Smithery.
|
|
45
|
-
|
|
46
|
-
#### Stateful Server
|
|
47
|
-
Most API integrations are stateless.
|
|
48
|
-
|
|
49
|
-
However, if your MCP server needs to persist state between calls (i.e., remembering previous interactions in a single chat conversation), you can use the `createStatefulServer` function instead.
|
|
5
|
+
For getting started, see the official documentation:
|
|
6
|
+
[https://smithery.ai/docs/getting_started/quickstart_build_typescript](https://smithery.ai/docs/getting_started/quickstart_build_typescript)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config - loaded from smithery.config.ts
|
|
3
|
+
*/
|
|
4
|
+
export interface Config {
|
|
5
|
+
build?: {
|
|
6
|
+
/**
|
|
7
|
+
* Path to the server's entry point.
|
|
8
|
+
* Default: detected from package.json "module" or "main"
|
|
9
|
+
*/
|
|
10
|
+
entry?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Optional esbuild overrides for bundling
|
|
13
|
+
*/
|
|
14
|
+
esbuild?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const DeployPayloadSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
type: z.ZodLiteral<"hosted">;
|
|
4
|
+
stateful: z.ZodDefault<z.ZodBoolean>;
|
|
5
|
+
configSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
6
|
+
serverCard: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
serverInfo: z.ZodObject<{
|
|
8
|
+
version: z.ZodString;
|
|
9
|
+
websiteUrl: z.ZodOptional<z.ZodString>;
|
|
10
|
+
description: z.ZodOptional<z.ZodString>;
|
|
11
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
12
|
+
src: z.ZodString;
|
|
13
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
14
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
15
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
16
|
+
light: "light";
|
|
17
|
+
dark: "dark";
|
|
18
|
+
}>>;
|
|
19
|
+
}, z.core.$strip>>>;
|
|
20
|
+
name: z.ZodString;
|
|
21
|
+
title: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
authentication: z.ZodOptional<z.ZodObject<{
|
|
24
|
+
required: z.ZodBoolean;
|
|
25
|
+
schemes: z.ZodArray<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
28
|
+
description: z.ZodOptional<z.ZodString>;
|
|
29
|
+
inputSchema: z.ZodObject<{
|
|
30
|
+
type: z.ZodLiteral<"object">;
|
|
31
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>;
|
|
32
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
}, z.core.$catchall<z.ZodUnknown>>;
|
|
34
|
+
outputSchema: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
type: z.ZodLiteral<"object">;
|
|
36
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>;
|
|
37
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
38
|
+
}, z.core.$catchall<z.ZodUnknown>>>;
|
|
39
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
title: z.ZodOptional<z.ZodString>;
|
|
41
|
+
readOnlyHint: z.ZodOptional<z.ZodBoolean>;
|
|
42
|
+
destructiveHint: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
+
idempotentHint: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
+
openWorldHint: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
}, z.core.$strip>>;
|
|
46
|
+
execution: z.ZodOptional<z.ZodObject<{
|
|
47
|
+
taskSupport: z.ZodOptional<z.ZodEnum<{
|
|
48
|
+
optional: "optional";
|
|
49
|
+
required: "required";
|
|
50
|
+
forbidden: "forbidden";
|
|
51
|
+
}>>;
|
|
52
|
+
}, z.core.$strip>>;
|
|
53
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
54
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
55
|
+
src: z.ZodString;
|
|
56
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
57
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
59
|
+
light: "light";
|
|
60
|
+
dark: "dark";
|
|
61
|
+
}>>;
|
|
62
|
+
}, z.core.$strip>>>;
|
|
63
|
+
name: z.ZodString;
|
|
64
|
+
title: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, z.core.$strip>>>;
|
|
66
|
+
resources: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
67
|
+
uri: z.ZodString;
|
|
68
|
+
description: z.ZodOptional<z.ZodString>;
|
|
69
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
70
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
71
|
+
audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
72
|
+
user: "user";
|
|
73
|
+
assistant: "assistant";
|
|
74
|
+
}>>>;
|
|
75
|
+
priority: z.ZodOptional<z.ZodNumber>;
|
|
76
|
+
lastModified: z.ZodOptional<z.ZodISODateTime>;
|
|
77
|
+
}, z.core.$strip>>;
|
|
78
|
+
_meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
79
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
80
|
+
src: z.ZodString;
|
|
81
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
82
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
83
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
84
|
+
light: "light";
|
|
85
|
+
dark: "dark";
|
|
86
|
+
}>>;
|
|
87
|
+
}, z.core.$strip>>>;
|
|
88
|
+
name: z.ZodString;
|
|
89
|
+
title: z.ZodOptional<z.ZodString>;
|
|
90
|
+
}, z.core.$strip>>>;
|
|
91
|
+
prompts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
92
|
+
description: z.ZodOptional<z.ZodString>;
|
|
93
|
+
arguments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
name: z.ZodString;
|
|
95
|
+
description: z.ZodOptional<z.ZodString>;
|
|
96
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
97
|
+
}, z.core.$strip>>>;
|
|
98
|
+
_meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
99
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
100
|
+
src: z.ZodString;
|
|
101
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
102
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
103
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
104
|
+
light: "light";
|
|
105
|
+
dark: "dark";
|
|
106
|
+
}>>;
|
|
107
|
+
}, z.core.$strip>>>;
|
|
108
|
+
name: z.ZodString;
|
|
109
|
+
title: z.ZodOptional<z.ZodString>;
|
|
110
|
+
}, z.core.$strip>>>;
|
|
111
|
+
}, z.core.$loose>>;
|
|
112
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
114
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, z.core.$strip>>;
|
|
116
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
117
|
+
type: z.ZodLiteral<"external">;
|
|
118
|
+
upstreamUrl: z.ZodString;
|
|
119
|
+
}, z.core.$strip>], "type">;
|
|
120
|
+
export type DeployPayload = z.infer<typeof DeployPayloadSchema>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ServerCardSchema } from "./server-card.js";
|
|
3
|
+
const HostedDeployPayloadSchema = z.object({
|
|
4
|
+
type: z.literal("hosted"),
|
|
5
|
+
stateful: z.boolean().default(false),
|
|
6
|
+
configSchema: z.record(z.string(), z.unknown()).optional(),
|
|
7
|
+
serverCard: ServerCardSchema.optional(),
|
|
8
|
+
source: z
|
|
9
|
+
.object({
|
|
10
|
+
commit: z.string().optional(),
|
|
11
|
+
branch: z.string().optional(),
|
|
12
|
+
})
|
|
13
|
+
.optional(),
|
|
14
|
+
});
|
|
15
|
+
const ExternalDeployPayloadSchema = z.object({
|
|
16
|
+
type: z.literal("external"),
|
|
17
|
+
upstreamUrl: z.string().url(),
|
|
18
|
+
});
|
|
19
|
+
export const DeployPayloadSchema = z.discriminatedUnion("type", [
|
|
20
|
+
HostedDeployPayloadSchema,
|
|
21
|
+
ExternalDeployPayloadSchema,
|
|
22
|
+
]);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ServerCardSchema: z.ZodObject<{
|
|
3
|
+
serverInfo: z.ZodObject<{
|
|
4
|
+
version: z.ZodString;
|
|
5
|
+
websiteUrl: z.ZodOptional<z.ZodString>;
|
|
6
|
+
description: z.ZodOptional<z.ZodString>;
|
|
7
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
8
|
+
src: z.ZodString;
|
|
9
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
10
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
11
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
12
|
+
light: "light";
|
|
13
|
+
dark: "dark";
|
|
14
|
+
}>>;
|
|
15
|
+
}, z.core.$strip>>>;
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
title: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
authentication: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
required: z.ZodBoolean;
|
|
21
|
+
schemes: z.ZodArray<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
24
|
+
description: z.ZodOptional<z.ZodString>;
|
|
25
|
+
inputSchema: z.ZodObject<{
|
|
26
|
+
type: z.ZodLiteral<"object">;
|
|
27
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>;
|
|
28
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
29
|
+
}, z.core.$catchall<z.ZodUnknown>>;
|
|
30
|
+
outputSchema: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
type: z.ZodLiteral<"object">;
|
|
32
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>;
|
|
33
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
}, z.core.$catchall<z.ZodUnknown>>>;
|
|
35
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
title: z.ZodOptional<z.ZodString>;
|
|
37
|
+
readOnlyHint: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
destructiveHint: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
idempotentHint: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
openWorldHint: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
execution: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
taskSupport: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
optional: "optional";
|
|
45
|
+
required: "required";
|
|
46
|
+
forbidden: "forbidden";
|
|
47
|
+
}>>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
50
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
51
|
+
src: z.ZodString;
|
|
52
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
53
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
54
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
55
|
+
light: "light";
|
|
56
|
+
dark: "dark";
|
|
57
|
+
}>>;
|
|
58
|
+
}, z.core.$strip>>>;
|
|
59
|
+
name: z.ZodString;
|
|
60
|
+
title: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>>>;
|
|
62
|
+
resources: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
63
|
+
uri: z.ZodString;
|
|
64
|
+
description: z.ZodOptional<z.ZodString>;
|
|
65
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
66
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
67
|
+
audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
68
|
+
user: "user";
|
|
69
|
+
assistant: "assistant";
|
|
70
|
+
}>>>;
|
|
71
|
+
priority: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
lastModified: z.ZodOptional<z.ZodISODateTime>;
|
|
73
|
+
}, z.core.$strip>>;
|
|
74
|
+
_meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
75
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
|
+
src: z.ZodString;
|
|
77
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
78
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
79
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
80
|
+
light: "light";
|
|
81
|
+
dark: "dark";
|
|
82
|
+
}>>;
|
|
83
|
+
}, z.core.$strip>>>;
|
|
84
|
+
name: z.ZodString;
|
|
85
|
+
title: z.ZodOptional<z.ZodString>;
|
|
86
|
+
}, z.core.$strip>>>;
|
|
87
|
+
prompts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
88
|
+
description: z.ZodOptional<z.ZodString>;
|
|
89
|
+
arguments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
90
|
+
name: z.ZodString;
|
|
91
|
+
description: z.ZodOptional<z.ZodString>;
|
|
92
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
}, z.core.$strip>>>;
|
|
94
|
+
_meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
95
|
+
icons: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
96
|
+
src: z.ZodString;
|
|
97
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
98
|
+
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
99
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
100
|
+
light: "light";
|
|
101
|
+
dark: "dark";
|
|
102
|
+
}>>;
|
|
103
|
+
}, z.core.$strip>>>;
|
|
104
|
+
name: z.ZodString;
|
|
105
|
+
title: z.ZodOptional<z.ZodString>;
|
|
106
|
+
}, z.core.$strip>>>;
|
|
107
|
+
}, z.core.$loose>;
|
|
108
|
+
export type ServerCard = z.infer<typeof ServerCardSchema>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ImplementationSchema, PromptSchema, ResourceSchema, ToolSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export const ServerCardSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
serverInfo: ImplementationSchema,
|
|
6
|
+
authentication: z
|
|
7
|
+
.object({
|
|
8
|
+
required: z.boolean(),
|
|
9
|
+
schemes: z.array(z.string()),
|
|
10
|
+
})
|
|
11
|
+
.optional(),
|
|
12
|
+
tools: z.array(ToolSchema).optional(),
|
|
13
|
+
resources: z.array(ResourceSchema).optional(),
|
|
14
|
+
prompts: z.array(PromptSchema).optional(),
|
|
15
|
+
})
|
|
16
|
+
.passthrough();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export { createStatefulServer, type CreateServerFn, type StatefulServerOptions, } from "./server/stateful.js";
|
|
4
|
-
export { createStatelessServer, type CreateStatelessServerFn, type StatelessServerOptions, } from "./server/stateless.js";
|
|
5
|
-
export * from "./server/logger.js";
|
|
6
|
-
export * from "./server/session.js";
|
|
7
|
-
export * from "./server/auth/identity.js";
|
|
8
|
-
export * from "./server/auth/oauth.js";
|
|
1
|
+
export * from "./types/index.js";
|
|
2
|
+
export * from "./bundle/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
// Smithery SDK – Main exports
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export * from "./
|
|
6
|
-
// === Server Primitives ===
|
|
7
|
-
// Stateful/stateless server patterns, session management, auth
|
|
8
|
-
export { createStatefulServer, } from "./server/stateful.js";
|
|
9
|
-
export { createStatelessServer, } from "./server/stateless.js";
|
|
10
|
-
export * from "./server/logger.js";
|
|
11
|
-
export * from "./server/session.js";
|
|
12
|
-
export * from "./server/auth/identity.js";
|
|
13
|
-
export * from "./server/auth/oauth.js";
|
|
2
|
+
// Types for MCP server authors
|
|
3
|
+
export * from "./types/index.js";
|
|
4
|
+
// Bundle manifest schema (for CLI/registry)
|
|
5
|
+
export * from "./bundle/index.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import type { z } from "zod";
|
|
3
|
+
export type Session = {
|
|
4
|
+
id: string;
|
|
5
|
+
get: <T = unknown>(key: string) => Promise<T | undefined>;
|
|
6
|
+
set: (key: string, value: unknown) => Promise<void>;
|
|
7
|
+
delete: (key: string) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
export type StatelessServerContext<TConfig = unknown> = {
|
|
10
|
+
config: TConfig;
|
|
11
|
+
env: Record<string, string | undefined>;
|
|
12
|
+
};
|
|
13
|
+
export type StatefulServerContext<TConfig = unknown> = {
|
|
14
|
+
config: TConfig;
|
|
15
|
+
session: Session;
|
|
16
|
+
env: Record<string, string | undefined>;
|
|
17
|
+
};
|
|
18
|
+
export type ServerContext<TConfig = unknown> = StatelessServerContext<TConfig> | StatefulServerContext<TConfig>;
|
|
19
|
+
export type SandboxServerContext = {
|
|
20
|
+
session: Session;
|
|
21
|
+
};
|
|
22
|
+
export type CreateServerFn<TConfig = unknown> = (context: ServerContext<TConfig>) => Server | Promise<Server>;
|
|
23
|
+
export type CreateSandboxServerFn = (context: SandboxServerContext) => Server | Promise<Server>;
|
|
24
|
+
/**
|
|
25
|
+
* ServerModule - expected exports from an MCP server entry point
|
|
26
|
+
*/
|
|
27
|
+
export interface ServerModule<TConfig = unknown> {
|
|
28
|
+
default: CreateServerFn<TConfig>;
|
|
29
|
+
configSchema?: z.ZodSchema<TConfig>;
|
|
30
|
+
createSandboxServer?: CreateSandboxServerFn;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the server is stateful.
|
|
33
|
+
* Stateful servers maintain state between calls within a session.
|
|
34
|
+
* Stateless servers are fresh for each request.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
stateful?: boolean;
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithery/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "SDK to develop with Smithery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -10,40 +10,32 @@
|
|
|
10
10
|
"main": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
|
-
".":
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./bundle": {
|
|
18
|
+
"types": "./dist/bundle/index.d.ts",
|
|
19
|
+
"default": "./dist/bundle/index.js"
|
|
20
|
+
}
|
|
14
21
|
},
|
|
15
22
|
"files": [
|
|
16
23
|
"dist"
|
|
17
24
|
],
|
|
18
25
|
"scripts": {
|
|
19
|
-
"build": "tsc",
|
|
20
|
-
"build:all": "pnpm -r --filter './*' build",
|
|
21
|
-
"watch": "tsc --watch",
|
|
26
|
+
"build": "rm -rf dist && tsc",
|
|
22
27
|
"check": "pnpm exec biome check --write --unsafe",
|
|
23
28
|
"prepare": "pnpm run build"
|
|
24
29
|
},
|
|
25
30
|
"packageManager": "pnpm@9.0.0",
|
|
26
31
|
"license": "MIT",
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
29
|
-
"chalk": "^5.6.2",
|
|
30
|
-
"express": "^5.1.0",
|
|
31
|
-
"jose": "^6.1.0",
|
|
32
|
-
"lodash": "^4.17.21",
|
|
33
|
-
"okay-error": "^1.0.3"
|
|
34
|
-
},
|
|
35
32
|
"peerDependencies": {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
36
34
|
"zod": "^4"
|
|
37
35
|
},
|
|
38
36
|
"devDependencies": {
|
|
39
37
|
"@biomejs/biome": "2.2.6",
|
|
40
|
-
"@types/express": "^5.0.1",
|
|
41
|
-
"@types/json-schema": "^7.0.15",
|
|
42
|
-
"@types/lodash": "^4.17.17",
|
|
43
38
|
"@types/node": "^20.0.0",
|
|
44
|
-
"@types/uuid": "^9.0.7",
|
|
45
|
-
"dotenv": "^16.4.7",
|
|
46
|
-
"tsx": "^4.19.2",
|
|
47
39
|
"typescript": "^5.0.0",
|
|
48
40
|
"zod": "^4"
|
|
49
41
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Application, Request, Router } from "express";
|
|
2
|
-
import { type JWTPayload } from "jose";
|
|
3
|
-
import type { OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
4
|
-
export type IdentityJwtClaims = JWTPayload & Record<string, unknown>;
|
|
5
|
-
export interface IdentityHandler {
|
|
6
|
-
/** Base path to mount metadata and token endpoints. Default: "/" */
|
|
7
|
-
basePath?: string;
|
|
8
|
-
/** Expected JWT issuer. Default: "https://server.smithery.ai" */
|
|
9
|
-
issuer?: string;
|
|
10
|
-
/** JWKS URL for issuer. Default: "https://server.smithery.ai/.well-known/jwks.json" */
|
|
11
|
-
jwksUrl?: string;
|
|
12
|
-
/** Optional explicit token path. Overrides basePath+"token". */
|
|
13
|
-
tokenPath?: string;
|
|
14
|
-
/** Handle a JWT grant provided by an external identity provider (i.e., Smithery) and mint access tokens */
|
|
15
|
-
handleJwtGrant: (claims: IdentityJwtClaims, req: Request) => Promise<OAuthTokens | null>;
|
|
16
|
-
}
|
|
17
|
-
export declare function createIdentityTokenRouter(options: IdentityHandler): Router;
|
|
18
|
-
export declare function mountIdentity(app: Application, options: IdentityHandler): void;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3
|
-
function normalizeBasePath(basePath) {
|
|
4
|
-
const value = basePath ?? "/";
|
|
5
|
-
return value.endsWith("/") ? value : `${value}/`;
|
|
6
|
-
}
|
|
7
|
-
export function createIdentityTokenRouter(options) {
|
|
8
|
-
const basePath = normalizeBasePath(options.basePath);
|
|
9
|
-
const issuer = options.issuer ?? "https://server.smithery.ai";
|
|
10
|
-
const jwksUrl = new URL(options.jwksUrl ?? "https://server.smithery.ai/.well-known/jwks.json");
|
|
11
|
-
const tokenPath = typeof options.tokenPath === "string" && options.tokenPath.length > 0
|
|
12
|
-
? options.tokenPath
|
|
13
|
-
: `${basePath}token`;
|
|
14
|
-
// Create JWKS resolver once; jose caches keys internally
|
|
15
|
-
const JWKS = createRemoteJWKSet(jwksUrl);
|
|
16
|
-
const tokenRouter = express.Router();
|
|
17
|
-
// urlencoded parser required for OAuth token requests
|
|
18
|
-
tokenRouter.use(express.urlencoded({ extended: false }));
|
|
19
|
-
tokenRouter.post(tokenPath, async (req, res, next) => {
|
|
20
|
-
try {
|
|
21
|
-
const grantType = typeof req.body?.grant_type === "string"
|
|
22
|
-
? req.body.grant_type
|
|
23
|
-
: undefined;
|
|
24
|
-
if (grantType !== "urn:ietf:params:oauth:grant-type:jwt-bearer")
|
|
25
|
-
return next();
|
|
26
|
-
const assertion = typeof req.body?.assertion === "string" ? req.body.assertion : undefined;
|
|
27
|
-
if (!assertion) {
|
|
28
|
-
res.status(400).json({
|
|
29
|
-
error: "invalid_request",
|
|
30
|
-
error_description: "Missing assertion",
|
|
31
|
-
});
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const host = req.get("host") ?? "localhost";
|
|
35
|
-
const audience = `https://${host}${tokenPath}`;
|
|
36
|
-
const { payload } = await jwtVerify(assertion, JWKS, {
|
|
37
|
-
issuer,
|
|
38
|
-
audience,
|
|
39
|
-
algorithms: ["RS256"],
|
|
40
|
-
});
|
|
41
|
-
const result = await options.handleJwtGrant(payload, req);
|
|
42
|
-
if (!result)
|
|
43
|
-
return next();
|
|
44
|
-
res.json(result);
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
console.error(error);
|
|
48
|
-
res.status(400).json({ error: "invalid_grant" });
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
return tokenRouter;
|
|
52
|
-
}
|
|
53
|
-
export function mountIdentity(app, options) {
|
|
54
|
-
app.use(createIdentityTokenRouter(options));
|
|
55
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { OAuthServerProvider, OAuthTokenVerifier } from "@modelcontextprotocol/sdk/server/auth/provider.js";
|
|
2
|
-
import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
|
|
3
|
-
import type { Application, Response } from "express";
|
|
4
|
-
import { type IdentityHandler } from "./identity.js";
|
|
5
|
-
export interface TokenVerifier extends OAuthTokenVerifier {
|
|
6
|
-
verifyAccessToken: (token: string) => Promise<AuthInfo>;
|
|
7
|
-
requiredScopes?: string[];
|
|
8
|
-
resourceMetadataUrl?: string;
|
|
9
|
-
}
|
|
10
|
-
type ProviderVerifier = OAuthServerProvider & TokenVerifier;
|
|
11
|
-
export interface OAuthProvider extends ProviderVerifier {
|
|
12
|
-
basePath?: string;
|
|
13
|
-
callbackPath?: string;
|
|
14
|
-
handleOAuthCallback?: (code: string, state: string | undefined, res: Response) => Promise<URL>;
|
|
15
|
-
}
|
|
16
|
-
export interface OAuthMountOptions {
|
|
17
|
-
provider?: OAuthProvider | TokenVerifier;
|
|
18
|
-
identity?: IdentityHandler;
|
|
19
|
-
}
|
|
20
|
-
export declare function mountOAuth(app: Application, opts: OAuthMountOptions): void;
|
|
21
|
-
export {};
|