Skip to content

Commit 84180f9

Browse files
committed
Refactor tools and integrate Datadog configuration
- Refactor utility functions in the helper module to improve code clarity and remove deprecated components. - Introduce a new TypeScript utility for creating and managing tool schema definitions, enhancing type safety. - Streamline integration with Datadog by setting up environment-variable-based configuration, including validation checks. - Restructure the incident handling module for better organization and clearer API initialization. Signed-off-by: katsumata <12413150+winor30@users.noreply.github.com>
1 parent b432386 commit 84180f9

File tree

7 files changed

+84
-80
lines changed

7 files changed

+84
-80
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# Logs
2-
logs
32
*.log
43
npm-debug.log*
54
yarn-debug.log*

src/index.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
CallToolRequestSchema,
1414
ListToolsRequestSchema,
1515
} from '@modelcontextprotocol/sdk/types.js'
16-
import { config, log, mcpDatadogVersion } from './utils/helper'
16+
import { log, mcpDatadogVersion } from './utils/helper'
1717
import { INCIDENT_HANDLERS, INCIDENT_TOOLS } from './tools/incident'
1818
import { ToolHandlers } from './utils/types'
1919

@@ -77,11 +77,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
7777
* which sends and receives data through standard input and output.
7878
*/
7979
async function main() {
80-
if (config.apiKeyAuth == null || config.appKeyAuth == null) {
81-
log('error', 'Server error: Missing Datadog API key or app key')
82-
process.exit(1)
83-
}
84-
8580
const transport = new StdioServerTransport()
8681
await server.connect(transport)
8782
}

src/tools/incident/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { INCIDENT_TOOLS, INCIDENT_HANDLERS } from './incident'
1+
export { INCIDENT_TOOLS, INCIDENT_HANDLERS } from './tool'

src/tools/incident/incident.ts src/tools/incident/tool.ts

+4-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ExtendedTool, ToolHandlers } from '../../utils/types'
2-
import { client, v2 } from '@datadog/datadog-api-client'
3-
import { config, createToolSchema } from '../../utils/helper'
2+
import { v2 } from '@datadog/datadog-api-client'
3+
import { createToolSchema } from '../../utils/tool'
44
import { GetIncidentZodSchema, ListIncidentsZodSchema } from './schema'
5+
import { datadogConfig } from '../../utils/datadog'
56

67
type IncidentToolName = 'list_incidents' | 'get_incident'
78
type IncidentTool = ExtendedTool<IncidentToolName>
@@ -19,22 +20,7 @@ export const INCIDENT_TOOLS: IncidentTool[] = [
1920
),
2021
] as const
2122

22-
const CONFIG = client.createConfiguration({
23-
authMethods: {
24-
apiKeyAuth: config.apiKeyAuth,
25-
appKeyAuth: config.appKeyAuth,
26-
},
27-
})
28-
CONFIG.unstableOperations = {
29-
'v2.listIncidents': true,
30-
'v2.getIncident': true,
31-
}
32-
if (config.site != null) {
33-
CONFIG.setServerVariables({
34-
site: config.site,
35-
})
36-
}
37-
const API_INSTANCE = new v2.IncidentsApi(CONFIG)
23+
const API_INSTANCE = new v2.IncidentsApi(datadogConfig)
3824

3925
type IncidentToolHandlers = ToolHandlers<IncidentToolName>
4026

src/utils/datadog.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { client } from '@datadog/datadog-api-client'
2+
3+
const config = {
4+
apiKeyAuth: process.env.DATADOG_API_KEY,
5+
appKeyAuth: process.env.DATADOG_APP_KEY,
6+
site: process.env.DATADOG_SITE,
7+
}
8+
9+
if (!config.apiKeyAuth || !config.appKeyAuth) {
10+
throw new Error('Datadog API key and APP key are required')
11+
}
12+
13+
const datadogConfig = client.createConfiguration({
14+
authMethods: {
15+
apiKeyAuth: config.apiKeyAuth,
16+
appKeyAuth: config.appKeyAuth,
17+
},
18+
})
19+
20+
if (config.site != null) {
21+
datadogConfig.setServerVariables({
22+
site: config.site,
23+
})
24+
}
25+
26+
datadogConfig.unstableOperations = {
27+
'v2.listIncidents': true,
28+
'v2.getIncident': true,
29+
}
30+
31+
export { datadogConfig }

src/utils/helper.ts

-54
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { Tool } from '@modelcontextprotocol/sdk/types.js'
2-
import { ZodSchema } from 'zod'
3-
41
/**
52
* Logs a formatted message with a specified severity to stderr.
63
*
@@ -18,55 +15,4 @@ export function log(
1815
process.stderr.write(msg)
1916
}
2017

21-
export const config = {
22-
apiKeyAuth: process.env.DATADOG_API_KEY,
23-
appKeyAuth: process.env.DATADOG_APP_KEY,
24-
site: process.env.DATADOG_SITE,
25-
}
26-
2718
export { version as mcpDatadogVersion } from '../../package.json'
28-
29-
type JsonSchema = Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
30-
31-
function pickRootObjectProperty(
32-
fullSchema: JsonSchema,
33-
schemaName: string,
34-
): {
35-
type: 'object'
36-
properties: any // eslint-disable-line @typescript-eslint/no-explicit-any
37-
required?: string[]
38-
} {
39-
const definitions = fullSchema.definitions ?? {}
40-
const root = definitions[schemaName]
41-
return {
42-
type: 'object',
43-
properties: root?.properties ?? {},
44-
required: root?.required ?? [],
45-
}
46-
}
47-
48-
/**
49-
* Creates a tool definition object using the provided Zod schema.
50-
*
51-
* This function converts a Zod schema (acting as the single source of truth) into a JSON Schema,
52-
* extracts the relevant root object properties, and embeds them into the tool definition.
53-
* This approach avoids duplicate schema definitions and ensures type safety and consistency.
54-
*
55-
* Note: The provided name is also used as the tool's name in the Model Context Protocol.
56-
*
57-
* @param schema - The Zod schema representing the tool's parameters.
58-
* @param name - The name of the tool and the key used to extract the corresponding schema definition, and the tool's name in the Model Context Protocol.
59-
* @param description - A brief description of the tool's functionality.
60-
* @returns A tool object containing the name, description, and input JSON Schema.
61-
*/
62-
export function createToolSchema<T extends string>(
63-
schema: ZodSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
64-
name: T,
65-
description: string,
66-
): Tool & { name: T } {
67-
return {
68-
name,
69-
description,
70-
inputSchema: pickRootObjectProperty(schema, name),
71-
}
72-
}

src/utils/tool.ts

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Tool } from '@modelcontextprotocol/sdk/types.js'
2+
import { ZodSchema } from 'zod'
3+
4+
type JsonSchema = Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
5+
6+
function pickRootObjectProperty(
7+
fullSchema: JsonSchema,
8+
schemaName: string,
9+
): {
10+
type: 'object'
11+
properties: any // eslint-disable-line @typescript-eslint/no-explicit-any
12+
required?: string[]
13+
} {
14+
const definitions = fullSchema.definitions ?? {}
15+
const root = definitions[schemaName]
16+
return {
17+
type: 'object',
18+
properties: root?.properties ?? {},
19+
required: root?.required ?? [],
20+
}
21+
}
22+
23+
/**
24+
* Creates a tool definition object using the provided Zod schema.
25+
*
26+
* This function converts a Zod schema (acting as the single source of truth) into a JSON Schema,
27+
* extracts the relevant root object properties, and embeds them into the tool definition.
28+
* This approach avoids duplicate schema definitions and ensures type safety and consistency.
29+
*
30+
* Note: The provided name is also used as the tool's name in the Model Context Protocol.
31+
*
32+
* @param schema - The Zod schema representing the tool's parameters.
33+
* @param name - The name of the tool and the key used to extract the corresponding schema definition, and the tool's name in the Model Context Protocol.
34+
* @param description - A brief description of the tool's functionality.
35+
* @returns A tool object containing the name, description, and input JSON Schema.
36+
*/
37+
export function createToolSchema<T extends string>(
38+
schema: ZodSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
39+
name: T,
40+
description: string,
41+
): Tool & { name: T } {
42+
return {
43+
name,
44+
description,
45+
inputSchema: pickRootObjectProperty(schema, name),
46+
}
47+
}

0 commit comments

Comments
 (0)