import * as Sentry from "@sentry/cloudflare";
import OAuthProvider from "@cloudflare/workers-oauth-provider";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpAgent } from "agents/mcp";
import { Props } from "./types";
import { GitHubHandler } from "./auth/github-handler";
import { closeDb } from "./database/connection";
import { registerDatabaseToolsWithSentry } from "./tools/database-tools-sentry";
export class MyMCP extends McpAgent<Env, Record<string, never>, Props> {
server = new McpServer({
name: "PostgreSQL Database MCP Server",
version: "1.0.0",
});
/**
* Cleanup database connections when Durable Object is shutting down
*/
async cleanup(): Promise<void> {
try {
await closeDb();
console.log('Database connections closed successfully');
} catch (error) {
console.error('Error during database cleanup:', error);
}
}
/**
* Durable Objects alarm handler - used for cleanup
*/
async alarm(): Promise<void> {
await this.cleanup();
}
async init() {
// Configure Sentry for Durable Objects
// Note: We use instrumentOutgoingRequests instead of withSentry wrapper
if ((this.env as any).SENTRY_DSN) {
const versionId = (this.env as any).CF_VERSION_METADATA?.id || 'unknown';
// Set Sentry context for this request
Sentry.setContext('durable_object', {
name: 'MyMCP',
version: versionId,
});
// Configure Sentry options
Sentry.setTag('worker_type', 'durable_object');
Sentry.setTag('version', versionId);
}
// Register all tools with Sentry instrumentation
registerDatabaseToolsWithSentry(this.server, this.env, this.props);
}
}
const oauthProvider = new OAuthProvider({
apiHandlers: {
'/sse': MyMCP.serveSSE('/sse') as any,
'/mcp': MyMCP.serve('/mcp') as any,
},
authorizeEndpoint: "/authorize",
clientRegistrationEndpoint: "/register",
defaultHandler: GitHubHandler as any,
tokenEndpoint: "/token",
});
// Wrap the fetch handler with Sentry instrumentation
export default Sentry.withSentry(
(env: Env) => {
const versionId = (env as any).CF_VERSION_METADATA?.id || 'unknown';
return {
dsn: (env as any).SENTRY_DSN,
tracesSampleRate: 1.0,
release: versionId,
environment: (env as any).ENVIRONMENT || 'production',
};
},
oauthProvider
) as typeof oauthProvider;