@dynatrace-oss/dynatrace-mcp-server 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/dynatrace-clients.js +25 -3
- package/dist/index.js +3 -2
- package/package.json +1 -1
- package/dist/capabilities/get-monitored-entity-owner.js +0 -15
- package/dist/capabilities/workflow-operations.js +0 -27
- package/dist/dynatrace-oauth-client.js +0 -55
- package/dist/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -16,9 +16,10 @@ Bring real-time observability data directly into your development workflow.
|
|
|
16
16
|
|
|
17
17
|
- List and get [problem](https://www.dynatrace.com/hub/detail/problems/) details from your services (for example Kubernetes)
|
|
18
18
|
- List and get security problems / [vulnerability](https://www.dynatrace.com/hub/detail/vulnerabilities/) details
|
|
19
|
-
- Execute DQL(Dynatrace Query Language)
|
|
19
|
+
- Execute DQL (Dynatrace Query Language) and retrieve logs, events, spans and metrics
|
|
20
20
|
- Send Slack messages (via Slack Connector)
|
|
21
21
|
- Set up notification Workflow (via Dynatrace [AutomationEngine](https://docs.dynatrace.com/docs/discover-dynatrace/platform/automationengine))
|
|
22
|
+
- Get more information about a monitored entity
|
|
22
23
|
- Get Ownership of an entity
|
|
23
24
|
|
|
24
25
|
## Quickstart
|
|
@@ -27,6 +28,8 @@ Bring real-time observability data directly into your development workflow.
|
|
|
27
28
|
|
|
28
29
|
You can add this MCP server (using STDIO) to your MCP Client like VS Code, Claude, Cursor, Amazon Q Developer CLI, Windsurf Github Copilot via the package `@dynatrace-oss/dynatrace-mcp-server`.
|
|
29
30
|
|
|
31
|
+
We recommend to always set it up for your current workspace instead of using it globally.
|
|
32
|
+
|
|
30
33
|
**VS Code**
|
|
31
34
|
|
|
32
35
|
```json
|
|
@@ -34,6 +37,7 @@ You can add this MCP server (using STDIO) to your MCP Client like VS Code, Claud
|
|
|
34
37
|
"servers": {
|
|
35
38
|
"npx-dynatrace-mcp-server": {
|
|
36
39
|
"command": "npx",
|
|
40
|
+
"cwd": "${workspaceFolder}",
|
|
37
41
|
"args": ["-y", "@dynatrace-oss/dynatrace-mcp-server@latest"],
|
|
38
42
|
"envFile": "${workspaceFolder}/.env"
|
|
39
43
|
}
|
|
@@ -61,6 +65,7 @@ This only works if the config is stored in the current workspaces, e.g., `<your-
|
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
**Claude Desktop**
|
|
68
|
+
|
|
64
69
|
```json
|
|
65
70
|
{
|
|
66
71
|
"mcpServers": {
|
|
@@ -80,6 +85,7 @@ This only works if the config is stored in the current workspaces, e.g., `<your-
|
|
|
80
85
|
**Amazon Q Developer CLI**
|
|
81
86
|
|
|
82
87
|
The [Amazon Q Developer CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-mcp-configuration.html) provides an interactive chat experience directly in your terminal. You can ask questions, get help with AWS services, troubleshoot issues, and generate code snippets without leaving your command line environment.
|
|
88
|
+
|
|
83
89
|
```json
|
|
84
90
|
{
|
|
85
91
|
"mcpServers": {
|
|
@@ -96,6 +102,8 @@ The [Amazon Q Developer CLI](https://docs.aws.amazon.com/amazonq/latest/qdevelop
|
|
|
96
102
|
}
|
|
97
103
|
```
|
|
98
104
|
|
|
105
|
+
This configuration should be stored in `<your-repo>/.amazonq/mcp.json`.
|
|
106
|
+
|
|
99
107
|
## Environment Variables
|
|
100
108
|
|
|
101
109
|
A **Dynatrace OAuth Client** is needed to communicate with your Dynatrace Environment. Please follow the documentation about
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.callAppFunction = exports.createOAuthClient = void 0;
|
|
3
|
+
exports.callAppFunction = exports.createOAuthClient = exports.ExtendedOauthClient = void 0;
|
|
4
4
|
const http_client_1 = require("@dynatrace-sdk/http-client");
|
|
5
5
|
const dt_app_1 = require("dt-app");
|
|
6
|
+
const package_json_1 = require("../package.json");
|
|
6
7
|
/**
|
|
7
8
|
* Uses the provided oauth Client ID and Secret and requests a token
|
|
8
9
|
* @param clientId - OAuth Client ID for Dynatrace
|
|
@@ -32,6 +33,26 @@ const requestToken = async (clientId, clientSecret, authUrl, scopes) => {
|
|
|
32
33
|
// and return the JSON result, as it contains additional information
|
|
33
34
|
return await res.json();
|
|
34
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* ExtendedOAuthClient that takes parameters for clientId, secret, scopes, environmentUrl, authUrl, and the version of the dynatrace-mcp-server
|
|
38
|
+
*/
|
|
39
|
+
class ExtendedOauthClient extends http_client_1._OAuthHttpClient {
|
|
40
|
+
userAgent;
|
|
41
|
+
constructor(config, userAgent) {
|
|
42
|
+
super(config);
|
|
43
|
+
this.userAgent = userAgent;
|
|
44
|
+
}
|
|
45
|
+
send(options) {
|
|
46
|
+
// add the user-agent header to the request
|
|
47
|
+
options.headers = {
|
|
48
|
+
...options.headers,
|
|
49
|
+
'User-Agent': this.userAgent,
|
|
50
|
+
};
|
|
51
|
+
// call the parent send method
|
|
52
|
+
return super.send(options);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.ExtendedOauthClient = ExtendedOauthClient;
|
|
35
56
|
/** Create an Oauth Client based on clientId, clientSecret, environmentUrl and scopes */
|
|
36
57
|
const createOAuthClient = async (clientId, clientSecret, environmentUrl, scopes) => {
|
|
37
58
|
if (!clientId) {
|
|
@@ -54,13 +75,14 @@ const createOAuthClient = async (clientId, clientSecret, environmentUrl, scopes)
|
|
|
54
75
|
throw new Error(`Failed to retrieve OAuth token (IssueId: ${tokenResponse.issueId}): ${tokenResponse.error} - ${tokenResponse.error_description}. Note: Your OAuth client is most likely not configured correctly.`);
|
|
55
76
|
}
|
|
56
77
|
console.error(`Successfully retrieved token from SSO!`);
|
|
57
|
-
|
|
78
|
+
const userAgent = `dynatrace-mcp-server/v${package_json_1.version} (${process.platform}-${process.arch})`;
|
|
79
|
+
return new ExtendedOauthClient({
|
|
58
80
|
scopes,
|
|
59
81
|
clientId,
|
|
60
82
|
secret: clientSecret,
|
|
61
83
|
environmentUrl,
|
|
62
84
|
authUrl: ssoAuthUrl,
|
|
63
|
-
});
|
|
85
|
+
}, userAgent);
|
|
64
86
|
};
|
|
65
87
|
exports.createOAuthClient = createOAuthClient;
|
|
66
88
|
/** Helper function to call an app-function via platform-api */
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
7
7
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
8
8
|
const dotenv_1 = require("dotenv");
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
|
+
const package_json_1 = require("../package.json");
|
|
10
11
|
const dynatrace_clients_1 = require("./dynatrace-clients");
|
|
11
12
|
const list_vulnerabilities_1 = require("./capabilities/list-vulnerabilities");
|
|
12
13
|
const list_problems_1 = require("./capabilities/list-problems");
|
|
@@ -68,10 +69,10 @@ const main = async () => {
|
|
|
68
69
|
const { oauthClient, oauthClientSecret, dtEnvironment, slackConnectionId } = dynatraceEnv;
|
|
69
70
|
// create an oauth-client
|
|
70
71
|
const dtClient = await (0, dynatrace_clients_1.createOAuthClient)(oauthClient, oauthClientSecret, dtEnvironment, scopes);
|
|
71
|
-
console.error(
|
|
72
|
+
console.error(`Starting Dynatrace MCP Server v${package_json_1.version}...`);
|
|
72
73
|
const server = new mcp_js_1.McpServer({
|
|
73
74
|
name: "Dynatrace MCP Server",
|
|
74
|
-
version:
|
|
75
|
+
version: package_json_1.version,
|
|
75
76
|
}, {
|
|
76
77
|
capabilities: {
|
|
77
78
|
tools: {},
|
package/package.json
CHANGED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMonitoredEntityOwner = void 0;
|
|
4
|
-
const get_monitored_entity_details_1 = require("./get-monitored-entity-details");
|
|
5
|
-
const getMonitoredEntityOwner = async (dtClient, entityId) => {
|
|
6
|
-
const monitoredEntity = await (0, get_monitored_entity_details_1.getMonitoredEntityDetails)(dtClient, entityId);
|
|
7
|
-
const owner = monitoredEntity.tags?.find((tag) => {
|
|
8
|
-
return tag?.key === "owner";
|
|
9
|
-
});
|
|
10
|
-
return {
|
|
11
|
-
entity: monitoredEntity,
|
|
12
|
-
owner: owner?.value
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
exports.getMonitoredEntityOwner = getMonitoredEntityOwner;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.executeWorkflow = exports.deleteWorkflow = exports.getWorkflowDetails = exports.listWorkflows = void 0;
|
|
4
|
-
const client_automation_1 = require("@dynatrace-sdk/client-automation");
|
|
5
|
-
const listWorkflows = async (dtClient) => {
|
|
6
|
-
const workflowsClient = new client_automation_1.WorkflowsClient(dtClient);
|
|
7
|
-
return await workflowsClient.getWorkflows({});
|
|
8
|
-
};
|
|
9
|
-
exports.listWorkflows = listWorkflows;
|
|
10
|
-
const getWorkflowDetails = async (dtClient, workflowId) => {
|
|
11
|
-
const workflowsClient = new client_automation_1.WorkflowsClient(dtClient);
|
|
12
|
-
return await workflowsClient.getWorkflow({ id: workflowId });
|
|
13
|
-
};
|
|
14
|
-
exports.getWorkflowDetails = getWorkflowDetails;
|
|
15
|
-
const deleteWorkflow = async (dtClient, workflowId) => {
|
|
16
|
-
const workflowsClient = new client_automation_1.WorkflowsClient(dtClient);
|
|
17
|
-
return await workflowsClient.deleteWorkflow({ id: workflowId });
|
|
18
|
-
};
|
|
19
|
-
exports.deleteWorkflow = deleteWorkflow;
|
|
20
|
-
const executeWorkflow = async (dtClient, workflowId, input) => {
|
|
21
|
-
const workflowsClient = new client_automation_1.WorkflowsClient(dtClient);
|
|
22
|
-
return await workflowsClient.runWorkflow({
|
|
23
|
-
id: workflowId,
|
|
24
|
-
body: input || {}
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
exports.executeWorkflow = executeWorkflow;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OAuthHttpClient = void 0;
|
|
4
|
-
class OAuthHttpClient {
|
|
5
|
-
config;
|
|
6
|
-
oauthToken;
|
|
7
|
-
constructor(config) {
|
|
8
|
-
this.config = config;
|
|
9
|
-
}
|
|
10
|
-
async send(options) {
|
|
11
|
-
const { statusValidator = defaultStatusValidator } = options;
|
|
12
|
-
if (!this.oauthToken || this.oauthToken.isExpired()) {
|
|
13
|
-
this.oauthToken = await this.requestToken();
|
|
14
|
-
}
|
|
15
|
-
const requestBodyType = options.requestBodyType ?? 'json';
|
|
16
|
-
const url = new URL(options.url, this.config.environmentUrl);
|
|
17
|
-
const body = options.body !== undefined
|
|
18
|
-
? await encodeRequestBody(options.body, requestBodyType)
|
|
19
|
-
: undefined;
|
|
20
|
-
const headers = {
|
|
21
|
-
...applyContentTypeHeader(options.headers, requestBodyType),
|
|
22
|
-
Authorization: `${this.oauthToken.tokenType} ${this.oauthToken.accessToken}`,
|
|
23
|
-
};
|
|
24
|
-
const response = await send(url.toString(), {
|
|
25
|
-
method: options.method,
|
|
26
|
-
signal: options.abortSignal,
|
|
27
|
-
body,
|
|
28
|
-
headers,
|
|
29
|
-
});
|
|
30
|
-
const ok = statusValidator(response.status);
|
|
31
|
-
if (ok) {
|
|
32
|
-
return new HttpClientResponse(response);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
throw new HttpClientResponseError(response, { requestMethod: options.method });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async requestToken() {
|
|
39
|
-
const res = await send(this.config.authUrl, {
|
|
40
|
-
method: 'POST',
|
|
41
|
-
headers: {
|
|
42
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
43
|
-
},
|
|
44
|
-
body: new URLSearchParams({
|
|
45
|
-
grant_type: 'client_credentials',
|
|
46
|
-
client_id: this.config.clientId,
|
|
47
|
-
client_secret: this.config.secret,
|
|
48
|
-
scope: this.config.scopes.join(' '),
|
|
49
|
-
}),
|
|
50
|
-
});
|
|
51
|
-
const data = await res.json();
|
|
52
|
-
return new OAuthToken(data);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.OAuthHttpClient = OAuthHttpClient;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../src/dynatrace-clients.ts","../src/getDynatraceEnv.test.ts","../src/getDynatraceEnv.ts","../src/index.ts","../src/capabilities/create-workflow-for-problem-notification.ts","../src/capabilities/execute-dql.ts","../src/capabilities/find-monitored-entity-by-name.ts","../src/capabilities/get-events-for-cluster.ts","../src/capabilities/get-logs-for-entity.ts","../src/capabilities/get-monitored-entity-details.ts","../src/capabilities/get-ownership-information.ts","../src/capabilities/get-problem-details.ts","../src/capabilities/get-vulnerability-details.ts","../src/capabilities/list-problems.ts","../src/capabilities/list-vulnerabilities.ts","../src/capabilities/send-slack-message.ts","../src/capabilities/update-workflow.ts"],"version":"5.8.2"}
|