Skip to content

Commit 4752257

Browse files
authored
refactor: update Datadog tools to use dynamic configuration factory (#10)
* refactor: update Datadog tools to use dynamic configuration factory functions This commit introduces a significant refactoring of Datadog tool handlers: - Replace static API instances with dynamic configuration factory functions - Remove direct import of datadogConfig from utils/datadog - Update index files to export new factory functions instead of static handlers - Improve flexibility by allowing dynamic Datadog client configuration - Standardize tool handler creation across different modules The changes enable more flexible and configurable Datadog tool integrations while maintaining the existing tool interfaces. * test: add comprehensive tests for Datadog configuration utilities This commit introduces a new test suite for Datadog configuration functions: - Create tests for `createDatadogConfig` with various configuration scenarios - Add tests for `getDatadogSite` to verify site retrieval - Validate configuration creation with and without custom sites - Ensure proper error handling for missing API and APP keys * feat: integrate Datadog configuration with tool handlers This commit updates the main index file to: - Validate Datadog API and APP key environment variables - Create a dynamic Datadog configuration using environment settings - Refactor tool handlers to use the new configuration factory functions - Ensure consistent configuration across all Datadog tool handlers * chore: bump package version to 1.1.0 This version bump reflects the recent feature additions and improvements to the Datadog server integration, including: - Dynamic Datadog configuration - Enhanced tool handlers - New host management functionality * test: remove commented-out test configuration in Datadog test suite
1 parent 95c8737 commit 4752257

File tree

18 files changed

+591
-484
lines changed

18 files changed

+591
-484
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@winor30/mcp-server-datadog",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "MCP server for interacting with Datadog API",
55
"repository": {
66
"type": "git",

src/index.ts

+28-14
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ import {
1414
ListToolsRequestSchema,
1515
} from '@modelcontextprotocol/sdk/types.js'
1616
import { log, mcpDatadogVersion } from './utils/helper'
17-
import { INCIDENT_HANDLERS, INCIDENT_TOOLS } from './tools/incident'
18-
import { METRICS_TOOLS, METRICS_HANDLERS } from './tools/metrics'
19-
import { LOGS_TOOLS, LOGS_HANDLERS } from './tools/logs'
20-
import { MONITORS_TOOLS, MONITORS_HANDLERS } from './tools/monitors'
21-
import { DASHBOARDS_TOOLS, DASHBOARDS_HANDLERS } from './tools/dashboards'
22-
import { TRACES_TOOLS, TRACES_HANDLERS } from './tools/traces'
23-
import { HOSTS_TOOLS, HOSTS_HANDLERS } from './tools/hosts'
17+
import { INCIDENT_TOOLS, createIncidentToolHandlers } from './tools/incident'
18+
import { METRICS_TOOLS, createMetricsToolHandlers } from './tools/metrics'
19+
import { LOGS_TOOLS, createLogsToolHandlers } from './tools/logs'
20+
import { MONITORS_TOOLS, createMonitorsToolHandlers } from './tools/monitors'
21+
import {
22+
DASHBOARDS_TOOLS,
23+
createDashboardsToolHandlers,
24+
} from './tools/dashboards'
25+
import { TRACES_TOOLS, createTracesToolHandlers } from './tools/traces'
26+
import { HOSTS_TOOLS, createHostsToolHandlers } from './tools/hosts'
2427
import { ToolHandlers } from './utils/types'
28+
import { createDatadogConfig } from './utils/datadog'
2529

2630
const server = new Server(
2731
{
@@ -57,14 +61,24 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
5761
}
5862
})
5963

64+
if (!process.env.DATADOG_API_KEY || !process.env.DATADOG_APP_KEY) {
65+
throw new Error('DATADOG_API_KEY and DATADOG_APP_KEY must be set')
66+
}
67+
68+
const datadogConfig = createDatadogConfig({
69+
apiKeyAuth: process.env.DATADOG_API_KEY,
70+
appKeyAuth: process.env.DATADOG_APP_KEY,
71+
site: process.env.DATADOG_SITE,
72+
})
73+
6074
const TOOL_HANDLERS: ToolHandlers = {
61-
...INCIDENT_HANDLERS,
62-
...METRICS_HANDLERS,
63-
...LOGS_HANDLERS,
64-
...MONITORS_HANDLERS,
65-
...DASHBOARDS_HANDLERS,
66-
...TRACES_HANDLERS,
67-
...HOSTS_HANDLERS,
75+
...createIncidentToolHandlers(datadogConfig),
76+
...createMetricsToolHandlers(datadogConfig),
77+
...createLogsToolHandlers(datadogConfig),
78+
...createMonitorsToolHandlers(datadogConfig),
79+
...createDashboardsToolHandlers(datadogConfig),
80+
...createTracesToolHandlers(datadogConfig),
81+
...createHostsToolHandlers(datadogConfig),
6882
}
6983
/**
7084
* Handler for invoking Datadog-related tools in the mcp-server-datadog.

src/tools/dashboards/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { DASHBOARDS_TOOLS, DASHBOARDS_HANDLERS } from './tool'
1+
export { DASHBOARDS_TOOLS, createDashboardsToolHandlers } from './tool'

src/tools/dashboards/tool.ts

+45-43
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { ExtendedTool, ToolHandlers } from '../../utils/types'
2-
import { v1 } from '@datadog/datadog-api-client'
2+
import { client, v1 } from '@datadog/datadog-api-client'
33
import { createToolSchema } from '../../utils/tool'
44
import { ListDashboardsZodSchema } from './schema'
5-
import { datadogConfig } from '../../utils/datadog'
65

76
type DashboardsToolName = 'list_dashboards'
87
type DashboardsTool = ExtendedTool<DashboardsToolName>
@@ -15,51 +14,54 @@ export const DASHBOARDS_TOOLS: DashboardsTool[] = [
1514
),
1615
] as const
1716

18-
const API_INSTANCE = new v1.DashboardsApi(datadogConfig)
19-
2017
type DashboardsToolHandlers = ToolHandlers<DashboardsToolName>
2118

22-
export const DASHBOARDS_HANDLERS: DashboardsToolHandlers = {
23-
list_dashboards: async (request) => {
24-
const { name, tags } = ListDashboardsZodSchema.parse(
25-
request.params.arguments,
26-
)
19+
export const createDashboardsToolHandlers = (
20+
config: client.Configuration,
21+
): DashboardsToolHandlers => {
22+
const apiInstance = new v1.DashboardsApi(config)
23+
return {
24+
list_dashboards: async (request) => {
25+
const { name, tags } = ListDashboardsZodSchema.parse(
26+
request.params.arguments,
27+
)
2728

28-
const response = await API_INSTANCE.listDashboards({
29-
filterShared: false,
30-
})
29+
const response = await apiInstance.listDashboards({
30+
filterShared: false,
31+
})
3132

32-
if (!response.dashboards) {
33-
throw new Error('No dashboards data returned')
34-
}
33+
if (!response.dashboards) {
34+
throw new Error('No dashboards data returned')
35+
}
3536

36-
// Filter dashboards based on name and tags if provided
37-
let filteredDashboards = response.dashboards
38-
if (name) {
39-
const searchTerm = name.toLowerCase()
40-
filteredDashboards = filteredDashboards.filter((dashboard) =>
41-
dashboard.title?.toLowerCase().includes(searchTerm),
42-
)
43-
}
44-
if (tags && tags.length > 0) {
45-
filteredDashboards = filteredDashboards.filter((dashboard) => {
46-
const dashboardTags = dashboard.description?.split(',') || []
47-
return tags.every((tag) => dashboardTags.includes(tag))
48-
})
49-
}
37+
// Filter dashboards based on name and tags if provided
38+
let filteredDashboards = response.dashboards
39+
if (name) {
40+
const searchTerm = name.toLowerCase()
41+
filteredDashboards = filteredDashboards.filter((dashboard) =>
42+
dashboard.title?.toLowerCase().includes(searchTerm),
43+
)
44+
}
45+
if (tags && tags.length > 0) {
46+
filteredDashboards = filteredDashboards.filter((dashboard) => {
47+
const dashboardTags = dashboard.description?.split(',') || []
48+
return tags.every((tag) => dashboardTags.includes(tag))
49+
})
50+
}
5051

51-
const dashboards = filteredDashboards.map((dashboard) => ({
52-
...dashboard,
53-
url: `https://app.datadoghq.com/dashboard/${dashboard.id}`,
54-
}))
52+
const dashboards = filteredDashboards.map((dashboard) => ({
53+
...dashboard,
54+
url: `https://app.datadoghq.com/dashboard/${dashboard.id}`,
55+
}))
5556

56-
return {
57-
content: [
58-
{
59-
type: 'text',
60-
text: `Dashboards: ${JSON.stringify(dashboards)}`,
61-
},
62-
],
63-
}
64-
},
65-
} as const
57+
return {
58+
content: [
59+
{
60+
type: 'text',
61+
text: `Dashboards: ${JSON.stringify(dashboards)}`,
62+
},
63+
],
64+
}
65+
},
66+
}
67+
}

src/tools/hosts/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
* Re-exports the tools and their handlers from the implementation file.
44
*
55
* HOSTS_TOOLS: Array of tool schemas defining the available host management operations
6-
* HOSTS_HANDLERS: Object containing the implementation of each host management operation
6+
* createHostsToolHandlers: Function that creates host management operation handlers
77
*/
8-
export { HOSTS_TOOLS, HOSTS_HANDLERS } from './tool'
8+
export { HOSTS_TOOLS, createHostsToolHandlers } from './tool'

0 commit comments

Comments
 (0)