@dynatrace-oss/dynatrace-mcp-server 0.1.3 → 0.1.4

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 CHANGED
@@ -25,7 +25,7 @@ Bring real-time observability data directly into your development workflow.
25
25
 
26
26
  **Work in progress**
27
27
 
28
- You can add this MCP server (using STDIO) to your MCP Client like VS Code, Claude, Cursor, Windsurf Github Copilot via the package `@dynatrace-oss/dynatrace-mcp-server`.
28
+ 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
29
 
30
30
  **VS Code**
31
31
 
@@ -79,7 +79,7 @@ This only works if the config is stored in the current workspaces, e.g., `<your-
79
79
 
80
80
  **Amazon Q Developer CLI**
81
81
 
82
- The [Amazon Q Developer CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-chat.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.
82
+ 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.
83
83
  ```json
84
84
  {
85
85
  "mcpServers": {
@@ -3,7 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.callAppFunction = exports.createOAuthClient = void 0;
4
4
  const http_client_1 = require("@dynatrace-sdk/http-client");
5
5
  const dt_app_1 = require("dt-app");
6
- /** Uses the provided oauth Client ID and Secret and requests a token */
6
+ /**
7
+ * Uses the provided oauth Client ID and Secret and requests a token
8
+ * @param clientId - OAuth Client ID for Dynatrace
9
+ * @param clientSecret - Oauth Client Secret for Dynatrace
10
+ * @param authUrl - SSO Authentication URL
11
+ * @param scopes - List of requested scopes
12
+ * @returns
13
+ */
7
14
  const requestToken = async (clientId, clientSecret, authUrl, scopes) => {
8
15
  const res = await fetch(authUrl, {
9
16
  method: 'POST',
@@ -17,9 +24,12 @@ const requestToken = async (clientId, clientSecret, authUrl, scopes) => {
17
24
  scope: scopes.join(' '),
18
25
  }),
19
26
  });
27
+ // check if the response was okay (HTTP 2xx) or not (HTTP 4xx or 5xx)
20
28
  if (!res.ok) {
29
+ // log the error
21
30
  console.error(`Failed to fetch token: ${res.status} ${res.statusText}`);
22
31
  }
32
+ // and return the JSON result, as it contains additional information
23
33
  return await res.json();
24
34
  };
25
35
  /** Create an Oauth Client based on clientId, clientSecret, environmentUrl and scopes */
@@ -39,8 +49,9 @@ const createOAuthClient = async (clientId, clientSecret, environmentUrl, scopes)
39
49
  console.error(`Using SSO auth URL: ${ssoAuthUrl}`);
40
50
  // try to request a token, just to verify that everything is set up correctly
41
51
  const tokenResponse = await requestToken(clientId, clientSecret, ssoAuthUrl, scopes);
42
- if (tokenResponse.error && tokenResponse.error_description) {
43
- throw new Error(`Failed to retrieve OAuth token: ${tokenResponse.error} - ${tokenResponse.error_description}`);
52
+ // in case we didn't get a token, or error / error_description / issueId is set, we throw an error
53
+ if (!tokenResponse.access_token || tokenResponse.error || tokenResponse.error_description || tokenResponse.issueId) {
54
+ 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.`);
44
55
  }
45
56
  console.error(`Successfully retrieved token from SSO!`);
46
57
  return new http_client_1._OAuthHttpClient({
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const client_platform_management_service_1 = require("@dynatrace-sdk/client-platform-management-service");
5
+ const shared_errors_1 = require("@dynatrace-sdk/shared-errors");
5
6
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
7
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
7
8
  const dotenv_1 = require("dotenv");
@@ -74,7 +75,7 @@ const main = async () => {
74
75
  tools: {},
75
76
  },
76
77
  });
77
- // quick abstraction/wrapper to make it easier to reply with text
78
+ // quick abstraction/wrapper to make it easier for tools to reply text instead of JSON
78
79
  const tool = (name, description, paramsSchema, cb) => {
79
80
  const wrappedCb = async (args) => {
80
81
  try {
@@ -84,6 +85,24 @@ const main = async () => {
84
85
  };
85
86
  }
86
87
  catch (error) {
88
+ // check if it's an error originating from the Dynatrace SDK / API Gateway and provide an appropriate message to the user
89
+ if ((0, shared_errors_1.isClientRequestError)(error)) {
90
+ const e = error;
91
+ let additionalErrorInformation = '';
92
+ if (e.response.status == 403) {
93
+ additionalErrorInformation = 'Note: Your user or service-user is most likely lacking the necessary permissions/scopes for this API Call.';
94
+ }
95
+ return {
96
+ content: [{
97
+ type: "text",
98
+ text: `Client Request Error: ${e.message} with HTTP status: ${e.response.status}. ${additionalErrorInformation} (body: ${JSON.stringify(e.body)})`
99
+ }
100
+ ],
101
+ isError: true,
102
+ };
103
+ }
104
+ // else: We don't know what kind of error happened - best-case we can provide error.message
105
+ console.log(error);
87
106
  return {
88
107
  content: [{ type: "text", text: `Error: ${error.message}` }],
89
108
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynatrace-oss/dynatrace-mcp-server",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Model Context Protocol (MCP) server for Dynatrace",
5
5
  "keywords": [
6
6
  "Dynatrace",
@@ -45,6 +45,7 @@
45
45
  "@dynatrace-sdk/client-classic-environment-v2": "^3.6.8",
46
46
  "@dynatrace-sdk/client-platform-management-service": "^1.6.3",
47
47
  "@dynatrace-sdk/client-query": "^1.18.1",
48
+ "@dynatrace-sdk/shared-errors": "^1.0.0",
48
49
  "@modelcontextprotocol/sdk": "^1.8.0",
49
50
  "dotenv": "^16.4.7",
50
51
  "dt-app": "^0.140.1",