@iflow-mcp/kamranbiglari-mcp-server-chart 1.0.0

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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +264 -0
  3. package/biome.json +49 -0
  4. package/dist/charts/bar.js +43 -0
  5. package/dist/charts/bubble.js +71 -0
  6. package/dist/charts/doughnut.js +104 -0
  7. package/dist/charts/gauge.js +84 -0
  8. package/dist/charts/index.js +15 -0
  9. package/dist/charts/line.js +74 -0
  10. package/dist/charts/ohlc.js +455 -0
  11. package/dist/charts/pie.js +50 -0
  12. package/dist/charts/polarArea.js +50 -0
  13. package/dist/charts/progressBar.js +50 -0
  14. package/dist/charts/radar.js +59 -0
  15. package/dist/charts/radialGauge.js +43 -0
  16. package/dist/charts/sankey.js +64 -0
  17. package/dist/charts/scatter.js +70 -0
  18. package/dist/charts/sparkline.js +43 -0
  19. package/dist/charts/violin.js +67 -0
  20. package/dist/index.js +236 -0
  21. package/dist/stdio-server.js +58 -0
  22. package/dist/utils/index.js +1 -0
  23. package/dist/utils/schema.js +9 -0
  24. package/image.png +0 -0
  25. package/language.json +1 -0
  26. package/package.json +1 -0
  27. package/package_name +1 -0
  28. package/push_info.json +5 -0
  29. package/screenshot/image.png +0 -0
  30. package/src/charts/bar.ts +48 -0
  31. package/src/charts/bubble.ts +78 -0
  32. package/src/charts/doughnut.ts +117 -0
  33. package/src/charts/gauge.ts +92 -0
  34. package/src/charts/index.ts +15 -0
  35. package/src/charts/line.ts +80 -0
  36. package/src/charts/ohlc.ts +474 -0
  37. package/src/charts/pie.ts +56 -0
  38. package/src/charts/polarArea.ts +56 -0
  39. package/src/charts/progressBar.ts +56 -0
  40. package/src/charts/radar.ts +65 -0
  41. package/src/charts/radialGauge.ts +49 -0
  42. package/src/charts/sankey.ts +71 -0
  43. package/src/charts/scatter.ts +77 -0
  44. package/src/charts/sparkline.ts +49 -0
  45. package/src/charts/violin.ts +73 -0
  46. package/src/index.ts +279 -0
  47. package/src/stdio-server.ts +77 -0
  48. package/src/utils/index.ts +1 -0
  49. package/src/utils/schema.ts +10 -0
  50. package/tsconfig.json +1 -0
  51. package/worker-configuration.d.ts +5709 -0
  52. package/wrangler.jsonc +28 -0
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the radar chart
5
+ // {
6
+ // type: 'radar',
7
+ // data: {
8
+ // labels: ['January', 'February', 'March', 'April', 'May'],
9
+ // datasets: [
10
+ // { label: 'Dogs', data: [50, 60, 70, 180, 190] },
11
+ // { label: 'Cats', data: [100, 200, 300, 400, 500] },
12
+ // ],
13
+ // },
14
+ // }
15
+
16
+ const schema = {
17
+ type: z.literal("radar").default("radar"),
18
+ data: z.object({
19
+ labels: z.array(z.string()).describe("Labels for the radar chart axes"),
20
+ datasets: z.array(
21
+ z.object({
22
+ label: z.string().describe("Label for the dataset"),
23
+ data: z.array(z.number()).describe("Data points for each axis"),
24
+ backgroundColor: z.string().optional().describe("Fill color of the radar area"),
25
+ borderColor: z.string().optional().describe("Color of the radar border line"),
26
+ borderWidth: z.number().optional().describe("Width of the border line"),
27
+ pointBackgroundColor: z.string().optional().describe("Background color of the data points"),
28
+ pointBorderColor: z.string().optional().describe("Border color of the data points"),
29
+ pointRadius: z.number().optional().describe("Radius of the data points"),
30
+ fill: z.boolean().optional().describe("Whether to fill the area"),
31
+ })
32
+ ),
33
+ }),
34
+ };
35
+
36
+ const tool = {
37
+ name: "radar",
38
+ description: `Generates a radar chart with the provided data.
39
+ example input:
40
+ \`\`\`json
41
+ {
42
+ "type": "radar",
43
+ "data": {
44
+ "labels": ["January", "February", "March", "April", "May"],
45
+ "datasets": [
46
+ {
47
+ "label": "Dogs",
48
+ "data": [50, 60, 70, 180, 190]
49
+ },
50
+ {
51
+ "label": "Cats",
52
+ "data": [100, 200, 300, 400, 500]
53
+ }
54
+ ]
55
+ }
56
+ }
57
+ \`\`\`
58
+ `,
59
+ inputSchema: zodToJsonSchema(schema),
60
+ };
61
+
62
+ export const radar = {
63
+ schema,
64
+ tool,
65
+ };
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the radial gauge chart
5
+ // {
6
+ // type: 'radialGauge',
7
+ // data: { datasets: [{ data: [70], backgroundColor: 'green' }] },
8
+ // }
9
+
10
+ const schema = {
11
+ type: z.literal("radialGauge").default("radialGauge"),
12
+ data: z.object({
13
+ datasets: z.array(
14
+ z.object({
15
+ data: z.array(z.number()).describe("Single value array representing the gauge value"),
16
+ backgroundColor: z.string().optional().describe("Background color of the gauge"),
17
+ borderColor: z.string().optional().describe("Border color of the gauge"),
18
+ borderWidth: z.number().optional().describe("Width of the gauge border"),
19
+ label: z.string().optional().describe("Label for the dataset"),
20
+ })
21
+ ),
22
+ }),
23
+ };
24
+
25
+ const tool = {
26
+ name: "radialGauge",
27
+ description: `Generates a radial gauge chart with the provided value.
28
+ example input:
29
+ \`\`\`json
30
+ {
31
+ "type": "radialGauge",
32
+ "data": {
33
+ "datasets": [
34
+ {
35
+ "data": [70],
36
+ "backgroundColor": "green"
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ \`\`\`
42
+ `,
43
+ inputSchema: zodToJsonSchema(schema),
44
+ };
45
+
46
+ export const radialGauge = {
47
+ schema,
48
+ tool,
49
+ };
@@ -0,0 +1,71 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the sankey chart
5
+ // {
6
+ // type: 'sankey',
7
+ // data: {
8
+ // datasets: [
9
+ // {
10
+ // data: [
11
+ // { from: 'Step A', to: 'Step B', flow: 10 },
12
+ // { from: 'Step A', to: 'Step C', flow: 5 },
13
+ // { from: 'Step B', to: 'Step C', flow: 10 },
14
+ // { from: 'Step D', to: 'Step C', flow: 7 },
15
+ // ]
16
+ // },
17
+ // ],
18
+ // },
19
+ // }
20
+
21
+ const sankeyDataPointSchema = z.object({
22
+ from: z.string().describe("Source node"),
23
+ to: z.string().describe("Target node"),
24
+ flow: z.number().describe("Flow value between nodes"),
25
+ });
26
+
27
+ const schema = {
28
+ type: z.literal("sankey").default("sankey"),
29
+ data: z.object({
30
+ datasets: z.array(
31
+ z.object({
32
+ data: z.array(sankeyDataPointSchema).describe("Array of flow connections between nodes"),
33
+ label: z.string().optional().describe("Label for the dataset"),
34
+ colorFrom: z.string().optional().describe("Color scheme for source nodes"),
35
+ colorTo: z.string().optional().describe("Color scheme for target nodes"),
36
+ colorMode: z.string().optional().describe("Color mode for the flows"),
37
+ borderWidth: z.number().optional().describe("Width of the flow borders"),
38
+ })
39
+ ),
40
+ }),
41
+ };
42
+
43
+ const tool = {
44
+ name: "sankey",
45
+ description: `Generates a sankey diagram with the provided flow data.
46
+ example input:
47
+ \`\`\`json
48
+ {
49
+ "type": "sankey",
50
+ "data": {
51
+ "datasets": [
52
+ {
53
+ "data": [
54
+ {"from": "Step A", "to": "Step B", "flow": 10},
55
+ {"from": "Step A", "to": "Step C", "flow": 5},
56
+ {"from": "Step B", "to": "Step C", "flow": 10},
57
+ {"from": "Step D", "to": "Step C", "flow": 7}
58
+ ]
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ \`\`\`
64
+ `,
65
+ inputSchema: zodToJsonSchema(schema),
66
+ };
67
+
68
+ export const sankey = {
69
+ schema,
70
+ tool,
71
+ };
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the scatter chart
5
+ // {
6
+ // type: 'scatter',
7
+ // data: {
8
+ // datasets: [
9
+ // {
10
+ // label: 'Data 1',
11
+ // data: [
12
+ // { x: 2, y: 4 },
13
+ // { x: 3, y: 3 },
14
+ // { x: -10, y: 0 },
15
+ // { x: 0, y: 10 },
16
+ // { x: 10, y: 5 },
17
+ // ],
18
+ // },
19
+ // ],
20
+ // },
21
+ // }
22
+
23
+ const scatterDataPointSchema = z.object({
24
+ x: z.number(),
25
+ y: z.number(),
26
+ });
27
+
28
+ const schema = {
29
+ type: z.literal("scatter").default("scatter"),
30
+ data: z.object({
31
+ datasets: z.array(
32
+ z.object({
33
+ label: z.string().describe("Label for the dataset"),
34
+ data: z.array(scatterDataPointSchema).describe("Array of {x, y} coordinate points"),
35
+ backgroundColor: z.string().optional().describe("Background color of the points"),
36
+ borderColor: z.string().optional().describe("Border color of the points"),
37
+ borderWidth: z.number().optional().describe("Width of the point borders"),
38
+ pointRadius: z.number().optional().describe("Radius of the data points"),
39
+ pointBackgroundColor: z.string().optional().describe("Background color of the data points"),
40
+ pointBorderColor: z.string().optional().describe("Border color of the data points"),
41
+ showLine: z.boolean().optional().describe("Whether to show lines connecting the points"),
42
+ })
43
+ ),
44
+ }),
45
+ };
46
+
47
+ const tool = {
48
+ name: "scatter",
49
+ description: `Generates a scatter chart with the provided data points.
50
+ example input:
51
+ \`\`\`json
52
+ {
53
+ "type": "scatter",
54
+ "data": {
55
+ "datasets": [
56
+ {
57
+ "label": "Data 1",
58
+ "data": [
59
+ {"x": 2, "y": 4},
60
+ {"x": 3, "y": 3},
61
+ {"x": -10, "y": 0},
62
+ {"x": 0, "y": 10},
63
+ {"x": 10, "y": 5}
64
+ ]
65
+ }
66
+ ]
67
+ }
68
+ }
69
+ \`\`\`
70
+ `,
71
+ inputSchema: zodToJsonSchema(schema),
72
+ };
73
+
74
+ export const scatter = {
75
+ schema,
76
+ tool,
77
+ };
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the sparkline chart
5
+ // {
6
+ // type: 'sparkline',
7
+ // data: { datasets: [{ data: [140, 60, 274, 370, 199] }] },
8
+ // }
9
+
10
+ const schema = {
11
+ type: z.literal("sparkline").default("sparkline"),
12
+ data: z.object({
13
+ datasets: z.array(
14
+ z.object({
15
+ data: z.array(z.number()).describe("Data values for the sparkline"),
16
+ backgroundColor: z.string().optional().describe("Background color of the sparkline"),
17
+ borderColor: z.string().optional().describe("Border color of the sparkline"),
18
+ borderWidth: z.number().optional().describe("Width of the sparkline border"),
19
+ fill: z.boolean().optional().describe("Whether to fill the area under the line"),
20
+ label: z.string().optional().describe("Label for the dataset"),
21
+ })
22
+ ),
23
+ }),
24
+ };
25
+
26
+ const tool = {
27
+ name: "sparkline",
28
+ description: `Generates a sparkline chart with the provided data.
29
+ example input:
30
+ \`\`\`json
31
+ {
32
+ "type": "sparkline",
33
+ "data": {
34
+ "datasets": [
35
+ {
36
+ "data": [140, 60, 274, 370, 199]
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ \`\`\`
42
+ `,
43
+ inputSchema: zodToJsonSchema(schema),
44
+ };
45
+
46
+ export const sparkline = {
47
+ schema,
48
+ tool,
49
+ };
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "../utils/index.js";
3
+
4
+ // Define the schema for the violin chart
5
+ // {
6
+ // type: 'violin',
7
+ // data: {
8
+ // labels: [2012, 2013, 2014, 2015],
9
+ // datasets: [
10
+ // {
11
+ // label: 'Data',
12
+ // data: [
13
+ // [12, 6, 3, 4],
14
+ // [1, 8, 8, 15],
15
+ // [1, 1, 1, 2, 3, 5, 9, 8],
16
+ // [19, -3, 18, 8, 5, 9, 9],
17
+ // ],
18
+ // backgroundColor: 'rgba(56,123,45,0.2)',
19
+ // borderColor: 'rgba(56,123,45,1.9)',
20
+ // },
21
+ // ],
22
+ // },
23
+ // }
24
+
25
+ const schema = {
26
+ type: z.literal("violin").default("violin"),
27
+ data: z.object({
28
+ labels: z.array(z.union([z.string(), z.number()])).describe("Labels for each violin"),
29
+ datasets: z.array(
30
+ z.object({
31
+ label: z.string().describe("Label for the dataset"),
32
+ data: z.array(z.array(z.number())).describe("Array of data arrays for each violin"),
33
+ backgroundColor: z.string().optional().describe("Background color of the violins"),
34
+ borderColor: z.string().optional().describe("Border color of the violins"),
35
+ borderWidth: z.number().optional().describe("Width of the violin borders"),
36
+ })
37
+ ),
38
+ }),
39
+ };
40
+
41
+ const tool = {
42
+ name: "violin",
43
+ description: `Generates a violin chart with the provided distribution data.
44
+ example input:
45
+ \`\`\`json
46
+ {
47
+ "type": "violin",
48
+ "data": {
49
+ "labels": [2012, 2013, 2014, 2015],
50
+ "datasets": [
51
+ {
52
+ "label": "Data",
53
+ "data": [
54
+ [12, 6, 3, 4],
55
+ [1, 8, 8, 15],
56
+ [1, 1, 1, 2, 3, 5, 9, 8],
57
+ [19, -3, 18, 8, 5, 9, 9]
58
+ ],
59
+ "backgroundColor": "rgba(56,123,45,0.2)",
60
+ "borderColor": "rgba(56,123,45,1.9)"
61
+ }
62
+ ]
63
+ }
64
+ }
65
+ \`\`\`
66
+ `,
67
+ inputSchema: zodToJsonSchema(schema),
68
+ };
69
+
70
+ export const violin = {
71
+ schema,
72
+ tool,
73
+ };
package/src/index.ts ADDED
@@ -0,0 +1,279 @@
1
+ import { McpAgent } from "agents/mcp";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { z } from "zod";
4
+ import * as Charts from './charts';
5
+
6
+ // Define our MCP agent with tools
7
+ export class MyMCP extends McpAgent {
8
+ server = new McpServer({
9
+ name: "mcp-server-chart",
10
+ version: "1.0.0",
11
+ description: "MCP Server for generating charts using QuickChart",
12
+ baseUrl: "https://chart.mcp.cloudcertainty.com",
13
+ author: "Kamran Biglari",
14
+ authorUrl: "https://github.com/KamranBiglari"
15
+ });
16
+
17
+ async init() {
18
+
19
+ // Register all chart tools
20
+ for (const chart of Object.values(Charts)) {
21
+ // @ts-ignore
22
+ this.server.tool(chart.tool.name, chart.tool.description, chart.schema, async (input) => {
23
+
24
+ console.log(`Received input for ${chart.tool.name}:`, input);
25
+ return fetch(`http://quickchart.io/chart?v=3&c=${encodeURIComponent(JSON.stringify(input))}`)
26
+ .then(response => response.arrayBuffer())
27
+ .then(data => {
28
+ const base64Image = Buffer.from(data).toString('base64');
29
+ return {
30
+ content: [
31
+ {
32
+ type: "image",
33
+ data: base64Image,
34
+ mimeType: "image/png",
35
+ },
36
+ ],
37
+ };
38
+ })
39
+ .catch(error => {
40
+ console.error(`Error generating ${chart.tool.name} chart:`, error);
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: `Error generating ${chart.tool.name} chart: ${error.message}`,
46
+ },
47
+ ],
48
+ };
49
+ });
50
+
51
+ });
52
+ }
53
+
54
+ }
55
+ }
56
+
57
+ // Helper function to get the base URL from the request
58
+ function getBaseUrl(request: Request): string {
59
+ const url = new URL(request.url);
60
+ return `${url.protocol}//${url.host}`;
61
+ }
62
+
63
+ // OAuth Authorization Server Discovery Response
64
+ function createOAuthAuthorizationServerResponse(baseUrl: string) {
65
+ return {
66
+ "issuer": baseUrl,
67
+ "authorization_endpoint": `${baseUrl}/oauth/authorize`,
68
+ "token_endpoint": `${baseUrl}/oauth/token`,
69
+ "token_endpoint_auth_methods_supported": ["none", "client_secret_basic", "client_secret_post"],
70
+ "response_types_supported": ["code", "token"],
71
+ "grant_types_supported": ["authorization_code", "client_credentials", "implicit"],
72
+ "code_challenge_methods_supported": ["plain", "S256"],
73
+ "scopes_supported": ["read", "write", "openid"],
74
+ "subject_types_supported": ["public"],
75
+ "id_token_signing_alg_values_supported": ["RS256"],
76
+ // Dynamic Client Registration support
77
+ "registration_endpoint": `${baseUrl}/oauth/register`,
78
+ "registration_endpoint_auth_methods_supported": ["none"],
79
+ // Indicate this is an authless server
80
+ "authless": true,
81
+ "require_authentication": false
82
+ };
83
+ }
84
+
85
+ // OAuth Protected Resource Discovery Response
86
+ function createOAuthProtectedResourceResponse(baseUrl: string) {
87
+ return {
88
+ "resource": baseUrl,
89
+ "authorization_servers": [baseUrl],
90
+ "scopes_supported": ["read", "write"],
91
+ "bearer_methods_supported": ["header", "query"],
92
+ // Indicate no authentication required
93
+ "authless": true,
94
+ "require_authentication": false,
95
+ "token_validation": "none"
96
+ };
97
+ }
98
+
99
+ // Mock OAuth Token Response
100
+ function createMockTokenResponse() {
101
+ return {
102
+ "access_token": "authless-token",
103
+ "token_type": "Bearer",
104
+ "expires_in": 3600,
105
+ "scope": "read write"
106
+ };
107
+ }
108
+
109
+ // Mock Client Registration Response
110
+ function createClientRegistrationResponse() {
111
+ return {
112
+ "client_id": "authless-client",
113
+ "client_secret": "authless-secret",
114
+ "client_id_issued_at": Math.floor(Date.now() / 1000),
115
+ "client_secret_expires_at": 0, // Never expires
116
+ "redirect_uris": [],
117
+ "token_endpoint_auth_method": "none",
118
+ "grant_types": ["authorization_code", "client_credentials"],
119
+ "response_types": ["code"],
120
+ "scope": "read write"
121
+ };
122
+ }
123
+
124
+ export default {
125
+ fetch(request: Request, env: Env, ctx: ExecutionContext) {
126
+ const url = new URL(request.url);
127
+ const baseUrl = getBaseUrl(request);
128
+
129
+ // OAuth Authorization Server Discovery Endpoint
130
+ if (url.pathname === "/.well-known/oauth-authorization-server") {
131
+ return new Response(
132
+ JSON.stringify(createOAuthAuthorizationServerResponse(baseUrl), null, 2),
133
+ {
134
+ headers: {
135
+ "Content-Type": "application/json",
136
+ "Access-Control-Allow-Origin": "*",
137
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
138
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
139
+ },
140
+ }
141
+ );
142
+ }
143
+
144
+ // OAuth Protected Resource Discovery Endpoint
145
+ if (url.pathname === "/.well-known/oauth-protected-resource") {
146
+ return new Response(
147
+ JSON.stringify(createOAuthProtectedResourceResponse(baseUrl), null, 2),
148
+ {
149
+ headers: {
150
+ "Content-Type": "application/json",
151
+ "Access-Control-Allow-Origin": "*",
152
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
153
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
154
+ },
155
+ }
156
+ );
157
+ }
158
+
159
+ // Mock OAuth Authorization Endpoint
160
+ if (url.pathname === "/oauth/authorize") {
161
+
162
+ // redirect to the redirect_uri if provided
163
+ const redirectUri = url.searchParams.get("redirect_uri");
164
+ if (redirectUri) {
165
+ return Response.redirect(redirectUri);
166
+ }
167
+ return new Response(
168
+ JSON.stringify(createMockTokenResponse(), null, 2),
169
+ {
170
+ headers: {
171
+ "Content-Type": "application/json",
172
+ "Access-Control-Allow-Origin": "*",
173
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
174
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
175
+ },
176
+ }
177
+ );
178
+ }
179
+
180
+ // Mock OAuth Token Endpoint
181
+ if (url.pathname === "/oauth/token") {
182
+ return new Response(
183
+ JSON.stringify(createMockTokenResponse(), null, 2),
184
+ {
185
+ headers: {
186
+ "Content-Type": "application/json",
187
+ "Access-Control-Allow-Origin": "*",
188
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
189
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
190
+ },
191
+ }
192
+ );
193
+ }
194
+
195
+ // Mock OAuth Client Registration Endpoint
196
+ if (url.pathname === "/oauth/register") {
197
+ // Handle both GET and POST for client registration
198
+ if (request.method === "POST" || request.method === "GET") {
199
+ return new Response(
200
+ JSON.stringify(createClientRegistrationResponse(), null, 2),
201
+ {
202
+ headers: {
203
+ "Content-Type": "application/json",
204
+ "Access-Control-Allow-Origin": "*",
205
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
206
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
207
+ },
208
+ }
209
+ );
210
+ }
211
+ }
212
+
213
+ // Health check endpoint
214
+ if (url.pathname === "/health") {
215
+ return new Response(
216
+ JSON.stringify({
217
+ status: "ok",
218
+ authless: true,
219
+ timestamp: new Date().toISOString(),
220
+ server: "mcp-server-chart"
221
+ }, null, 2),
222
+ {
223
+ headers: {
224
+ "Content-Type": "application/json",
225
+ "Access-Control-Allow-Origin": "*",
226
+ },
227
+ }
228
+ );
229
+ }
230
+
231
+ // Root endpoint with server info
232
+ if (url.pathname === "/") {
233
+ return new Response(
234
+ JSON.stringify({
235
+ name: "mcp-server-chart",
236
+ version: "1.0.0",
237
+ authless: true,
238
+ endpoints: {
239
+ mcp: "/mcp",
240
+ sse: "/sse",
241
+ health: "/health",
242
+ oauth_authorization_server: "/.well-known/oauth-authorization-server",
243
+ oauth_protected_resource: "/.well-known/oauth-protected-resource",
244
+ oauth_authorize: "/oauth/authorize",
245
+ oauth_token: "/oauth/token"
246
+ }
247
+ }, null, 2),
248
+ {
249
+ headers: {
250
+ "Content-Type": "application/json",
251
+ "Access-Control-Allow-Origin": "*",
252
+ },
253
+ }
254
+ );
255
+ }
256
+
257
+ // Handle CORS preflight requests
258
+ if (request.method === "OPTIONS") {
259
+ return new Response(null, {
260
+ headers: {
261
+ "Access-Control-Allow-Origin": "*",
262
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
263
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
264
+ },
265
+ });
266
+ }
267
+
268
+ // Existing MCP endpoints
269
+ if (url.pathname === "/sse" || url.pathname === "/sse/message") {
270
+ return MyMCP.serveSSE("/sse").fetch(request, env, ctx);
271
+ }
272
+
273
+ if (url.pathname === "/mcp") {
274
+ return MyMCP.serve("/mcp").fetch(request, env, ctx);
275
+ }
276
+
277
+ return new Response("Not found", { status: 404 });
278
+ },
279
+ };