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:
2026-07-14 01:27:00 -07:00
parent 488ad6b3fd
commit 6136fc863f
8 changed files with 162 additions and 44 deletions

View File

@@ -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",

View 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);

View File

@@ -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";

File diff suppressed because one or more lines are too long

View File

@@ -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,
}: {

View 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 };
},
});

View 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,
});
};

View File

@@ -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,
});
};