Refactor MCP server resources and creation logic
- Moved the static resource creation logic to a new file `staticResources.ts` for better organization and separation of concerns. - Introduced `createConfiguredAutumnOperationsMCPServer` in `createServer.ts` to encapsulate server creation logic and configuration. - Updated `createAutumnOperationsMCPServer` in `server.ts` to utilize the new server creation function, simplifying the server instantiation process. - Removed redundant code related to resource handling from `server.ts` to streamline the server setup.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build:worker-resources": "bun scripts/build-worker-resources.ts",
|
||||
"ts": "tsc --noEmit",
|
||||
"test": "bun test tests/unit",
|
||||
"test:eval": "ENV_FILE=.env infisical run --env=dev --recursive -- bun test tests/evals",
|
||||
|
||||
46
packages/mcp/scripts/build-worker-resources.ts
Normal file
46
packages/mcp/scripts/build-worker-resources.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { mkdirSync, writeFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import {
|
||||
autumnMcpResourceUris,
|
||||
autumnMcpResources,
|
||||
} from "../src/resources-v2/index.js";
|
||||
import { autumnMcpInstructions } from "../src/resources-v2/mcpInstructions.js";
|
||||
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const outputPath = resolve(
|
||||
scriptDir,
|
||||
"../src/resources-v2/generated/workerResources.ts",
|
||||
);
|
||||
|
||||
const resourceUris = autumnMcpResourceUris();
|
||||
const resourceDocs = await Promise.all(
|
||||
resourceUris.map(async (uri) => {
|
||||
const content = await autumnMcpResources.getResourceContent({ uri });
|
||||
const listed = (await autumnMcpResources.listResources()).find(
|
||||
(resource) => resource.uri === uri,
|
||||
);
|
||||
if (!listed) {
|
||||
throw new Error(`Generated resource list did not include ${uri}`);
|
||||
}
|
||||
return {
|
||||
name: listed.name,
|
||||
title: listed.title ?? listed.name,
|
||||
description: listed.description ?? "",
|
||||
priority: listed.annotations?.priority ?? 0.8,
|
||||
audience: listed.annotations?.audience ?? ["assistant"],
|
||||
uri,
|
||||
text: content.text,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
const source = `import type { AutumnMcpResourceDoc } from "../../resources/types.js";
|
||||
|
||||
export const workerAutumnMcpInstructions = ${JSON.stringify(autumnMcpInstructions)} as const;
|
||||
|
||||
export const workerAutumnMcpResourceDocs = ${JSON.stringify(resourceDocs, null, "\t")} satisfies AutumnMcpResourceDoc[];
|
||||
`;
|
||||
|
||||
mkdirSync(dirname(outputPath), { recursive: true });
|
||||
writeFileSync(outputPath, source);
|
||||
@@ -25,6 +25,10 @@ export {
|
||||
type OAuthEnvironment,
|
||||
} from "./server/auth/auth.js";
|
||||
export type { MCPServerFlags } from "./server/flags.js";
|
||||
export {
|
||||
createConfiguredAutumnOperationsMCPServer,
|
||||
type AutumnMcpServerOptions as ConfiguredAutumnMcpServerOptions,
|
||||
} from "./server/createServer.js";
|
||||
export {
|
||||
type AutumnMcpServerOptions,
|
||||
createAutumnOperationsMCPServer,
|
||||
@@ -36,4 +40,4 @@ export {
|
||||
getAutumnMcpRuntimeConfig,
|
||||
setAutumnMcpRuntimeConfig,
|
||||
} from "./server/runtime.js";
|
||||
export { createStaticAutumnMcpResources } from "./resources-v2/index.js";
|
||||
export { createStaticAutumnMcpResources } from "./resources-v2/staticResources.js";
|
||||
|
||||
39
packages/mcp/src/resources-v2/generated/workerResources.ts
Normal file
39
packages/mcp/src/resources-v2/generated/workerResources.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ import type { MCPServerResources } from "@mastra/mcp";
|
||||
import { parseResourceMarkdown } from "../resources/compileResources.js";
|
||||
import type { AutumnMcpResourceDoc } from "../resources/types.js";
|
||||
import { getAutumnMcpRuntimeConfig } from "../server/runtime.js";
|
||||
import { createStaticAutumnMcpResources } from "./staticResources.js";
|
||||
|
||||
const billingResource = {
|
||||
name: "billing",
|
||||
@@ -157,28 +158,6 @@ const compileResources = ({
|
||||
]);
|
||||
};
|
||||
|
||||
export const createStaticAutumnMcpResources = (
|
||||
docs: AutumnMcpResourceDoc[],
|
||||
): MCPServerResources => ({
|
||||
listResources: async () =>
|
||||
docs.map((doc) => ({
|
||||
uri: doc.uri,
|
||||
name: doc.name,
|
||||
title: doc.title,
|
||||
description: doc.description,
|
||||
mimeType: "text/markdown",
|
||||
size: doc.text.length,
|
||||
annotations: { audience: doc.audience, priority: doc.priority },
|
||||
})),
|
||||
getResourceContent: async ({ uri }) => {
|
||||
const doc = docs.find((entry) => entry.uri === uri);
|
||||
if (!doc) {
|
||||
throw new Error(`Unknown Autumn MCP resource: ${uri}`);
|
||||
}
|
||||
return { text: doc.text };
|
||||
},
|
||||
});
|
||||
|
||||
export const createAutumnMcpResources = ({
|
||||
baseUrl,
|
||||
}: {
|
||||
|
||||
24
packages/mcp/src/resources-v2/staticResources.ts
Normal file
24
packages/mcp/src/resources-v2/staticResources.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { MCPServerResources } from "@mastra/mcp";
|
||||
import type { AutumnMcpResourceDoc } from "../resources/types.js";
|
||||
|
||||
export const createStaticAutumnMcpResources = (
|
||||
docs: AutumnMcpResourceDoc[],
|
||||
): MCPServerResources => ({
|
||||
listResources: async () =>
|
||||
docs.map((doc) => ({
|
||||
uri: doc.uri,
|
||||
name: doc.name,
|
||||
title: doc.title,
|
||||
description: doc.description,
|
||||
mimeType: "text/markdown",
|
||||
size: doc.text.length,
|
||||
annotations: { audience: doc.audience, priority: doc.priority },
|
||||
})),
|
||||
getResourceContent: async ({ uri }) => {
|
||||
const doc = docs.find((entry) => entry.uri === uri);
|
||||
if (!doc) {
|
||||
throw new Error(`Unknown Autumn MCP resource: ${uri}`);
|
||||
}
|
||||
return { text: doc.text };
|
||||
},
|
||||
});
|
||||
37
packages/mcp/src/server/createServer.ts
Normal file
37
packages/mcp/src/server/createServer.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { MCPServer } from "@mastra/mcp";
|
||||
import { createRawAutumnOperationTools } from "../tools/index.js";
|
||||
import {
|
||||
type AutumnMcpRuntimeConfig,
|
||||
setAutumnMcpRuntimeConfig,
|
||||
} from "./runtime.js";
|
||||
|
||||
export type AutumnMcpServerOptions = {
|
||||
description?: string | undefined;
|
||||
id?: string | undefined;
|
||||
instructions: string;
|
||||
jsonSchemaValidator?: ConstructorParameters<
|
||||
typeof MCPServer
|
||||
>[0]["jsonSchemaValidator"];
|
||||
resources: ConstructorParameters<typeof MCPServer>[0]["resources"];
|
||||
runtime?: AutumnMcpRuntimeConfig | undefined;
|
||||
};
|
||||
|
||||
export const createConfiguredAutumnOperationsMCPServer = (
|
||||
options: AutumnMcpServerOptions,
|
||||
) => {
|
||||
if (options.runtime) {
|
||||
setAutumnMcpRuntimeConfig(options.runtime);
|
||||
}
|
||||
|
||||
return new MCPServer({
|
||||
id: options.id ?? "autumn-mcp",
|
||||
name: "Autumn MCP",
|
||||
version: "0.0.1",
|
||||
description:
|
||||
options.description ?? "Operate on Autumn customers, plans, and billing.",
|
||||
instructions: options.instructions,
|
||||
tools: createRawAutumnOperationTools(),
|
||||
resources: options.resources,
|
||||
jsonSchemaValidator: options.jsonSchemaValidator,
|
||||
});
|
||||
};
|
||||
@@ -1,36 +1,24 @@
|
||||
import { MCPServer } from "@mastra/mcp";
|
||||
import { autumnMcpResources } from "../resources/index.js";
|
||||
import { autumnMcpInstructions } from "../resources-v2/mcpInstructions.js";
|
||||
import { createRawAutumnOperationTools } from "../tools/index.js";
|
||||
import {
|
||||
type AutumnMcpRuntimeConfig,
|
||||
setAutumnMcpRuntimeConfig,
|
||||
} from "./runtime.js";
|
||||
createConfiguredAutumnOperationsMCPServer,
|
||||
type AutumnMcpServerOptions as ConfiguredAutumnMcpServerOptions,
|
||||
} from "./createServer.js";
|
||||
import type { AutumnMcpRuntimeConfig } from "./runtime.js";
|
||||
|
||||
export type AutumnMcpServerOptions = {
|
||||
instructions?: string | undefined;
|
||||
jsonSchemaValidator?: ConstructorParameters<
|
||||
typeof MCPServer
|
||||
>[0]["jsonSchemaValidator"];
|
||||
resources?: ConstructorParameters<typeof MCPServer>[0]["resources"];
|
||||
jsonSchemaValidator?: ConfiguredAutumnMcpServerOptions["jsonSchemaValidator"];
|
||||
resources?: ConfiguredAutumnMcpServerOptions["resources"];
|
||||
runtime?: AutumnMcpRuntimeConfig | undefined;
|
||||
};
|
||||
|
||||
export const createAutumnOperationsMCPServer = (
|
||||
options: AutumnMcpServerOptions = {},
|
||||
) => {
|
||||
if (options.runtime) {
|
||||
setAutumnMcpRuntimeConfig(options.runtime);
|
||||
}
|
||||
|
||||
return new MCPServer({
|
||||
id: "autumn-mcp",
|
||||
name: "Autumn MCP",
|
||||
version: "0.0.1",
|
||||
description: "Operate on Autumn customers, plans, and billing.",
|
||||
) =>
|
||||
createConfiguredAutumnOperationsMCPServer({
|
||||
instructions: options.instructions ?? autumnMcpInstructions,
|
||||
tools: createRawAutumnOperationTools(),
|
||||
resources: options.resources ?? autumnMcpResources,
|
||||
jsonSchemaValidator: options.jsonSchemaValidator,
|
||||
runtime: options.runtime,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user