Skip to content

Commit

Permalink
refactor: update Datadog tools to use dynamic configuration factory (#10
Browse files Browse the repository at this point in the history
)

* 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
  • Loading branch information
winor30 authored Mar 2, 2025
1 parent 95c8737 commit 4752257
Show file tree
Hide file tree
Showing 18 changed files with 591 additions and 484 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@winor30/mcp-server-datadog",
"version": "1.0.1",
"version": "1.1.0",
"description": "MCP server for interacting with Datadog API",
"repository": {
"type": "git",
Expand Down
42 changes: 28 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ import {
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js'
import { log, mcpDatadogVersion } from './utils/helper'
import { INCIDENT_HANDLERS, INCIDENT_TOOLS } from './tools/incident'
import { METRICS_TOOLS, METRICS_HANDLERS } from './tools/metrics'
import { LOGS_TOOLS, LOGS_HANDLERS } from './tools/logs'
import { MONITORS_TOOLS, MONITORS_HANDLERS } from './tools/monitors'
import { DASHBOARDS_TOOLS, DASHBOARDS_HANDLERS } from './tools/dashboards'
import { TRACES_TOOLS, TRACES_HANDLERS } from './tools/traces'
import { HOSTS_TOOLS, HOSTS_HANDLERS } from './tools/hosts'
import { INCIDENT_TOOLS, createIncidentToolHandlers } from './tools/incident'
import { METRICS_TOOLS, createMetricsToolHandlers } from './tools/metrics'
import { LOGS_TOOLS, createLogsToolHandlers } from './tools/logs'
import { MONITORS_TOOLS, createMonitorsToolHandlers } from './tools/monitors'
import {
DASHBOARDS_TOOLS,
createDashboardsToolHandlers,
} from './tools/dashboards'
import { TRACES_TOOLS, createTracesToolHandlers } from './tools/traces'
import { HOSTS_TOOLS, createHostsToolHandlers } from './tools/hosts'
import { ToolHandlers } from './utils/types'
import { createDatadogConfig } from './utils/datadog'

const server = new Server(
{
Expand Down Expand Up @@ -57,14 +61,24 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
}
})

if (!process.env.DATADOG_API_KEY || !process.env.DATADOG_APP_KEY) {
throw new Error('DATADOG_API_KEY and DATADOG_APP_KEY must be set')
}

const datadogConfig = createDatadogConfig({
apiKeyAuth: process.env.DATADOG_API_KEY,
appKeyAuth: process.env.DATADOG_APP_KEY,
site: process.env.DATADOG_SITE,
})

const TOOL_HANDLERS: ToolHandlers = {
...INCIDENT_HANDLERS,
...METRICS_HANDLERS,
...LOGS_HANDLERS,
...MONITORS_HANDLERS,
...DASHBOARDS_HANDLERS,
...TRACES_HANDLERS,
...HOSTS_HANDLERS,
...createIncidentToolHandlers(datadogConfig),
...createMetricsToolHandlers(datadogConfig),
...createLogsToolHandlers(datadogConfig),
...createMonitorsToolHandlers(datadogConfig),
...createDashboardsToolHandlers(datadogConfig),
...createTracesToolHandlers(datadogConfig),
...createHostsToolHandlers(datadogConfig),
}
/**
* Handler for invoking Datadog-related tools in the mcp-server-datadog.
Expand Down
2 changes: 1 addition & 1 deletion src/tools/dashboards/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { DASHBOARDS_TOOLS, DASHBOARDS_HANDLERS } from './tool'
export { DASHBOARDS_TOOLS, createDashboardsToolHandlers } from './tool'
88 changes: 45 additions & 43 deletions src/tools/dashboards/tool.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ExtendedTool, ToolHandlers } from '../../utils/types'
import { v1 } from '@datadog/datadog-api-client'
import { client, v1 } from '@datadog/datadog-api-client'
import { createToolSchema } from '../../utils/tool'
import { ListDashboardsZodSchema } from './schema'
import { datadogConfig } from '../../utils/datadog'

type DashboardsToolName = 'list_dashboards'
type DashboardsTool = ExtendedTool<DashboardsToolName>
Expand All @@ -15,51 +14,54 @@ export const DASHBOARDS_TOOLS: DashboardsTool[] = [
),
] as const

const API_INSTANCE = new v1.DashboardsApi(datadogConfig)

type DashboardsToolHandlers = ToolHandlers<DashboardsToolName>

export const DASHBOARDS_HANDLERS: DashboardsToolHandlers = {
list_dashboards: async (request) => {
const { name, tags } = ListDashboardsZodSchema.parse(
request.params.arguments,
)
export const createDashboardsToolHandlers = (
config: client.Configuration,
): DashboardsToolHandlers => {
const apiInstance = new v1.DashboardsApi(config)
return {
list_dashboards: async (request) => {
const { name, tags } = ListDashboardsZodSchema.parse(
request.params.arguments,
)

const response = await API_INSTANCE.listDashboards({
filterShared: false,
})
const response = await apiInstance.listDashboards({
filterShared: false,
})

if (!response.dashboards) {
throw new Error('No dashboards data returned')
}
if (!response.dashboards) {
throw new Error('No dashboards data returned')
}

// Filter dashboards based on name and tags if provided
let filteredDashboards = response.dashboards
if (name) {
const searchTerm = name.toLowerCase()
filteredDashboards = filteredDashboards.filter((dashboard) =>
dashboard.title?.toLowerCase().includes(searchTerm),
)
}
if (tags && tags.length > 0) {
filteredDashboards = filteredDashboards.filter((dashboard) => {
const dashboardTags = dashboard.description?.split(',') || []
return tags.every((tag) => dashboardTags.includes(tag))
})
}
// Filter dashboards based on name and tags if provided
let filteredDashboards = response.dashboards
if (name) {
const searchTerm = name.toLowerCase()
filteredDashboards = filteredDashboards.filter((dashboard) =>
dashboard.title?.toLowerCase().includes(searchTerm),
)
}
if (tags && tags.length > 0) {
filteredDashboards = filteredDashboards.filter((dashboard) => {
const dashboardTags = dashboard.description?.split(',') || []
return tags.every((tag) => dashboardTags.includes(tag))
})
}

const dashboards = filteredDashboards.map((dashboard) => ({
...dashboard,
url: `https://app.datadoghq.com/dashboard/${dashboard.id}`,
}))
const dashboards = filteredDashboards.map((dashboard) => ({
...dashboard,
url: `https://app.datadoghq.com/dashboard/${dashboard.id}`,
}))

return {
content: [
{
type: 'text',
text: `Dashboards: ${JSON.stringify(dashboards)}`,
},
],
}
},
} as const
return {
content: [
{
type: 'text',
text: `Dashboards: ${JSON.stringify(dashboards)}`,
},
],
}
},
}
}
4 changes: 2 additions & 2 deletions src/tools/hosts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
* Re-exports the tools and their handlers from the implementation file.
*
* HOSTS_TOOLS: Array of tool schemas defining the available host management operations
* HOSTS_HANDLERS: Object containing the implementation of each host management operation
* createHostsToolHandlers: Function that creates host management operation handlers
*/
export { HOSTS_TOOLS, HOSTS_HANDLERS } from './tool'
export { HOSTS_TOOLS, createHostsToolHandlers } from './tool'
Loading

0 comments on commit 4752257

Please sign in to comment.