newrelic-mcp 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 @cloudbring
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,430 @@
1
+ # New Relic MCP Server
2
+
3
+ A Model Context Protocol (MCP) server that provides seamless integration with New Relic's observability platform. Query metrics, manage alerts, monitor applications, and interact with your entire observability stack through a simple, unified interface.
4
+
5
+ > **Disclaimer**: This is an unofficial community project and is not affiliated with, endorsed by, or supported by New Relic, Inc. All trademarks are the property of their respective owners.
6
+
7
+ ## Features
8
+
9
+ - 📊 **NRQL Queries** - Execute powerful queries to analyze your data
10
+ - 🚀 **APM Integration** - Monitor application performance and health
11
+ - 🔔 **Alert Management** - View and acknowledge alerts and incidents
12
+ - 🔍 **Entity Search** - Discover and inspect entities across your infrastructure
13
+ - 📈 **Synthetics Monitoring** - Manage synthetic monitors and checks
14
+ - 🔧 **NerdGraph API** - Direct access to New Relic's GraphQL API
15
+
16
+ ## Installation
17
+
18
+ ### Quick Install with Smithery
19
+
20
+ To install New Relic MCP for Claude Desktop automatically via [Smithery](https://smithery.ai/mcp/newrelic-mcp):
21
+
22
+ ```bash
23
+ npx @smithery/cli install newrelic-mcp --client claude
24
+ ```
25
+
26
+ ### Manual Installation
27
+
28
+ <details>
29
+ <summary>Claude Desktop</summary>
30
+
31
+ Add to your Claude Desktop configuration file:
32
+
33
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
34
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "newrelic": {
40
+ "command": "npx",
41
+ "args": [
42
+ "-y",
43
+ "newrelic-mcp"
44
+ ],
45
+ "env": {
46
+ "NEW_RELIC_API_KEY": "your-api-key-here",
47
+ "NEW_RELIC_ACCOUNT_ID": "your-account-id"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+ </details>
54
+
55
+ <details>
56
+ <summary>Cline (VS Code)</summary>
57
+
58
+ Add to your Cline settings in VS Code:
59
+
60
+ ```json
61
+ {
62
+ "cline.mcpServers": [
63
+ {
64
+ "name": "newrelic",
65
+ "command": "npx",
66
+ "args": ["-y", "newrelic-mcp"],
67
+ "env": {
68
+ "NEW_RELIC_API_KEY": "your-api-key-here",
69
+ "NEW_RELIC_ACCOUNT_ID": "your-account-id"
70
+ }
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+ </details>
76
+
77
+ <details>
78
+ <summary>Zed Editor</summary>
79
+
80
+ Add to your Zed configuration file at `~/.config/zed/settings.json`:
81
+
82
+ ```json
83
+ {
84
+ "language_models": {
85
+ "mcp": {
86
+ "servers": {
87
+ "newrelic": {
88
+ "command": "npx",
89
+ "args": ["-y", "newrelic-mcp"],
90
+ "env": {
91
+ "NEW_RELIC_API_KEY": "your-api-key-here",
92
+ "NEW_RELIC_ACCOUNT_ID": "your-account-id"
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+ </details>
101
+
102
+ <details>
103
+ <summary>Windsurf Editor</summary>
104
+
105
+ Add to your Windsurf Cascade configuration:
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "newrelic": {
111
+ "command": "npx",
112
+ "args": ["-y", "newrelic-mcp"],
113
+ "env": {
114
+ "NEW_RELIC_API_KEY": "your-api-key-here",
115
+ "NEW_RELIC_ACCOUNT_ID": "your-account-id"
116
+ }
117
+ }
118
+ }
119
+ }
120
+ ```
121
+ </details>
122
+
123
+ <details>
124
+ <summary>Local Development</summary>
125
+
126
+ 1. Clone the repository:
127
+ ```bash
128
+ git clone https://github.com/cloudbring/newrelic-mcp.git
129
+ cd newrelic-mcp
130
+ ```
131
+
132
+ 2. Install dependencies and build:
133
+ ```bash
134
+ npm install
135
+ npm run build
136
+ ```
137
+
138
+ 3. Add to your MCP client configuration:
139
+ ```json
140
+ {
141
+ "mcpServers": {
142
+ "newrelic": {
143
+ "command": "node",
144
+ "args": ["/path/to/newrelic-mcp/dist/server.js"],
145
+ "env": {
146
+ "NEW_RELIC_API_KEY": "your-api-key-here",
147
+ "NEW_RELIC_ACCOUNT_ID": "your-account-id"
148
+ }
149
+ }
150
+ }
151
+ }
152
+ ```
153
+ </details>
154
+
155
+ ## Configuration
156
+
157
+ ### Required Environment Variables
158
+
159
+ - `NEW_RELIC_API_KEY` - Your New Relic User API Key (required)
160
+ - `NEW_RELIC_ACCOUNT_ID` - Your New Relic Account ID (optional, can be provided per tool call)
161
+
162
+ ### Getting Your New Relic Credentials
163
+
164
+ 1. **API Key**:
165
+ - Log in to [New Relic](https://one.newrelic.com)
166
+ - Navigate to **API Keys** in the left sidebar
167
+ - Create a new User API Key with appropriate permissions
168
+
169
+ 2. **Account ID**:
170
+ - Find your Account ID in the URL when logged into New Relic
171
+ - Or navigate to **Administration** → **Access management** → **Accounts**
172
+
173
+ For detailed setup instructions, see [docs/new-relic-setup.md](docs/new-relic-setup.md).
174
+
175
+ ## Usage Examples
176
+
177
+ Once configured, you can interact with New Relic through your MCP client:
178
+
179
+ ### Query Your Data
180
+ ```
181
+ "Show me the average response time for my web application over the last hour"
182
+ "What are the top 10 slowest database queries today?"
183
+ "Display error rate trends for the production environment"
184
+ ```
185
+
186
+ ### Monitor Applications
187
+ ```
188
+ "List all my APM applications and their current status"
189
+ "Show me the health of my Node.js services"
190
+ "Which applications have active alerts?"
191
+ ```
192
+
193
+ ### Manage Alerts
194
+ ```
195
+ "Show me all open incidents"
196
+ "What critical alerts fired in the last 24 hours?"
197
+ "Acknowledge incident #12345"
198
+ ```
199
+
200
+ ### Search Infrastructure
201
+ ```
202
+ "Find all Redis databases in production"
203
+ "Show me entities with high CPU usage"
204
+ "List all synthetic monitors and their success rates"
205
+ ```
206
+
207
+ ## Available Tools
208
+
209
+ | Tool | Description |
210
+ |------|-------------|
211
+ | `run_nrql_query` | Execute NRQL queries to analyze your data |
212
+ | `list_apm_applications` | List all APM applications in your account |
213
+ | `search_entities` | Search for entities by name, type, or tags |
214
+ | `get_entity_details` | Get detailed information about a specific entity |
215
+ | `run_nerdgraph_query` | Execute custom NerdGraph GraphQL queries |
216
+ | `list_alert_policies` | List all alert policies in your account |
217
+ | `list_open_incidents` | List all open incidents with priority filtering |
218
+ | `acknowledge_incident` | Acknowledge an open incident |
219
+ | `list_synthetics_monitors` | List all Synthetics monitors |
220
+ | `create_browser_monitor` | Create a new browser-based Synthetics monitor |
221
+ | `get_account_details` | Get New Relic account details |
222
+
223
+ ## Troubleshooting
224
+
225
+ <details>
226
+ <summary>Connection Issues</summary>
227
+
228
+ If you're having trouble connecting:
229
+
230
+ 1. Verify your API key is valid:
231
+ ```bash
232
+ curl -X POST https://api.newrelic.com/graphql \
233
+ -H 'Content-Type: application/json' \
234
+ -H 'API-Key: YOUR_API_KEY' \
235
+ -d '{"query":"{ actor { user { email } } }"}'
236
+ ```
237
+
238
+ 2. Check that your Account ID is correct
239
+ 3. Ensure your API key has the necessary permissions
240
+ 4. Check the MCP client logs for detailed error messages
241
+ </details>
242
+
243
+ <details>
244
+ <summary>Permission Errors</summary>
245
+
246
+ If you receive permission errors:
247
+
248
+ 1. Verify your API key has the required permissions:
249
+ - For NRQL queries: `NRQL query` permission
250
+ - For APM data: `APM` read permissions
251
+ - For alerts: `Alerts` read/write permissions
252
+
253
+ 2. Create a new API key with broader permissions if needed
254
+ </details>
255
+
256
+ ## Development
257
+
258
+ ### Project Structure
259
+
260
+ ```
261
+ src/
262
+ ├── server.ts # Main MCP server implementation
263
+ ├── client/
264
+ │ └── newrelic-client.ts # New Relic API client
265
+ └── tools/
266
+ ├── nrql.ts # NRQL query tool
267
+ ├── apm.ts # APM applications tool
268
+ ├── entity.ts # Entity management tools
269
+ ├── alert.ts # Alert and incident tools
270
+ ├── synthetics.ts # Synthetics monitoring tools
271
+ └── nerdgraph.ts # NerdGraph query tool
272
+ ```
273
+
274
+ ### Setup Development Environment
275
+
276
+ 1. Clone the repository:
277
+ ```bash
278
+ git clone https://github.com/cloudbring/newrelic-mcp.git
279
+ cd newrelic-mcp
280
+ ```
281
+
282
+ 2. Install dependencies:
283
+ ```bash
284
+ npm install
285
+ ```
286
+
287
+ 3. Create a `.env` file:
288
+ ```bash
289
+ NEW_RELIC_API_KEY=your-api-key-here
290
+ NEW_RELIC_ACCOUNT_ID=your-account-id
291
+ ```
292
+
293
+ 4. Build the project:
294
+ ```bash
295
+ npm run build
296
+ ```
297
+
298
+ ### Development Commands
299
+
300
+ ```bash
301
+ # Start development server with hot reload
302
+ npm run dev
303
+
304
+ # Build for production
305
+ npm run build
306
+
307
+ # Run tests
308
+ npm test
309
+
310
+ # Run tests with coverage
311
+ npm run test:coverage
312
+
313
+ # Run linting
314
+ npm run lint
315
+
316
+ # Format code
317
+ npm run format
318
+
319
+ # Test server startup
320
+ npm run test:server
321
+ ```
322
+
323
+ ### Testing
324
+
325
+ The project uses Test-Driven Development (TDD) with:
326
+ - **Vitest** for unit testing
327
+ - **Gherkin** for BDD testing
328
+ - **Evalite** for LLM response validation
329
+
330
+ ```bash
331
+ # Run all tests
332
+ npm test
333
+
334
+ # Run with coverage
335
+ npm run test:coverage
336
+
337
+ # Run BDD tests only
338
+ npm run test:bdd
339
+
340
+ # Run integration tests with real API
341
+ USE_REAL_ENV=true npm test
342
+ ```
343
+
344
+ ### Debugging
345
+
346
+ Use the MCP Inspector to test and debug the server:
347
+
348
+ ```bash
349
+ # Run with MCP Inspector
350
+ npm run inspect
351
+
352
+ # Run with development server
353
+ npm run inspect:dev
354
+
355
+ # Run with environment variables
356
+ npm run inspect:env
357
+ ```
358
+
359
+ See [docs/mcp-inspector-setup.md](docs/mcp-inspector-setup.md) for detailed instructions.
360
+
361
+ ### Architecture
362
+
363
+ The server follows a modular architecture with:
364
+ - **Client Layer**: Handles New Relic API communication
365
+ - **Tools Layer**: Implements MCP tool specifications
366
+ - **Server Layer**: Manages MCP protocol and tool routing
367
+
368
+ Each tool:
369
+ - Has a single, focused purpose
370
+ - Validates inputs using Zod schemas
371
+ - Returns structured, typed responses
372
+ - Includes comprehensive error handling
373
+
374
+ ## Contributing
375
+
376
+ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
377
+
378
+ ### Development Workflow
379
+
380
+ 1. Fork the repository
381
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
382
+ 3. Write tests first (TDD approach)
383
+ 4. Implement your feature
384
+ 5. Ensure all tests pass (`npm test`)
385
+ 6. Maintain >90% code coverage
386
+ 7. Run linting (`npm run lint`)
387
+ 8. Commit your changes (commits will be auto-formatted)
388
+ 9. Push to your branch
389
+ 10. Open a Pull Request
390
+
391
+ ### Code Style
392
+
393
+ This project uses:
394
+ - **Biome** for linting and formatting
395
+ - **TypeScript** with strict mode
396
+ - **2 spaces** for indentation
397
+ - **Single quotes** for strings
398
+ - **Semicolons** always
399
+
400
+ ## Documentation
401
+
402
+ - [New Relic Setup Guide](docs/new-relic-setup.md) - Detailed credential setup
403
+ - [MCP Inspector Setup](docs/mcp-inspector-setup.md) - Testing and debugging
404
+ - [Logging & Telemetry](docs/logging-telemetry.md) - Test monitoring
405
+ - [Implementation Details](docs/implementation.md) - Architecture deep dive
406
+
407
+ ## Support
408
+
409
+ - 🐛 [Report bugs](https://github.com/cloudbring/newrelic-mcp/issues)
410
+ - 💡 [Request features](https://github.com/cloudbring/newrelic-mcp/issues)
411
+ - 💬 [Join discussions](https://github.com/cloudbring/newrelic-mcp/discussions)
412
+ - 📖 [Read the docs](https://github.com/cloudbring/newrelic-mcp/tree/main/docs)
413
+
414
+ ## License
415
+
416
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
417
+
418
+ ## Disclaimer
419
+
420
+ This project is not affiliated with, endorsed by, or supported by New Relic, Inc. It is an independent open-source project that uses New Relic's public APIs.
421
+
422
+ ## Acknowledgments
423
+
424
+ - Built on the [Model Context Protocol](https://modelcontextprotocol.io) specification
425
+ - Integrates with [New Relic's](https://newrelic.com) observability platform APIs
426
+ - Inspired by the broader MCP ecosystem
427
+
428
+ ---
429
+
430
+ Made with ❤️ by [@cloudbring](https://github.com/cloudbring) using Cursor and Claude Code
@@ -0,0 +1,40 @@
1
+ export interface NrqlQueryResult {
2
+ results: any[];
3
+ metadata: {
4
+ eventTypes?: string[];
5
+ timeWindow?: {
6
+ begin: number;
7
+ end: number;
8
+ };
9
+ facets?: string[];
10
+ timeSeries?: boolean;
11
+ };
12
+ }
13
+ export interface AccountDetails {
14
+ accountId: string;
15
+ name: string;
16
+ region?: string;
17
+ }
18
+ export interface ApmApplication {
19
+ guid: string;
20
+ name: string;
21
+ language: string;
22
+ reporting: boolean;
23
+ alertSeverity?: string;
24
+ tags?: Record<string, string>;
25
+ }
26
+ export declare class NewRelicClient {
27
+ private apiKey;
28
+ private defaultAccountId?;
29
+ constructor(apiKey?: string, defaultAccountId?: string);
30
+ validateCredentials(): Promise<boolean>;
31
+ getAccountDetails(accountId?: string): Promise<AccountDetails>;
32
+ runNrqlQuery(params: {
33
+ nrql: string;
34
+ accountId: string;
35
+ }): Promise<NrqlQueryResult>;
36
+ listApmApplications(accountId?: string): Promise<ApmApplication[]>;
37
+ private parseTags;
38
+ executeNerdGraphQuery(query: string, variables?: any): Promise<any>;
39
+ }
40
+ //# sourceMappingURL=newrelic-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newrelic-client.d.ts","sourceRoot":"","sources":["../../src/client/newrelic-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,QAAQ,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,EAAE;YACX,KAAK,EAAE,MAAM,CAAC;YACd,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;QACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAC,CAAS;gBAEtB,MAAM,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAKhD,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBvC,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA2B9D,YAAY,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IA2DnF,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAyCxE,OAAO,CAAC,SAAS;IAYX,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;CAwB1E"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NewRelicClient = void 0;
4
+ const NERDGRAPH_URL = 'https://api.newrelic.com/graphql';
5
+ class NewRelicClient {
6
+ apiKey;
7
+ defaultAccountId;
8
+ constructor(apiKey, defaultAccountId) {
9
+ this.apiKey = apiKey || process.env.NEW_RELIC_API_KEY || '';
10
+ this.defaultAccountId = defaultAccountId || process.env.NEW_RELIC_ACCOUNT_ID;
11
+ }
12
+ async validateCredentials() {
13
+ try {
14
+ const query = `{
15
+ actor {
16
+ user {
17
+ id
18
+ email
19
+ }
20
+ }
21
+ }`;
22
+ const response = await this.executeNerdGraphQuery(query);
23
+ return !!response.data?.actor?.user;
24
+ }
25
+ catch (_error) {
26
+ return false;
27
+ }
28
+ }
29
+ async getAccountDetails(accountId) {
30
+ const id = accountId || this.defaultAccountId;
31
+ if (!id) {
32
+ throw new Error('Account ID must be provided');
33
+ }
34
+ const query = `{
35
+ actor {
36
+ account(id: ${id}) {
37
+ id
38
+ name
39
+ }
40
+ }
41
+ }`;
42
+ const response = await this.executeNerdGraphQuery(query);
43
+ if (!response.data?.actor?.account) {
44
+ throw new Error(`Account ${id} not found`);
45
+ }
46
+ return {
47
+ accountId: response.data.actor.account.id,
48
+ name: response.data.actor.account.name,
49
+ };
50
+ }
51
+ async runNrqlQuery(params) {
52
+ if (!params.nrql || typeof params.nrql !== 'string') {
53
+ throw new Error('Invalid or empty NRQL query provided');
54
+ }
55
+ if (!params.accountId || !/^\d+$/.test(params.accountId)) {
56
+ throw new Error('Invalid account ID format');
57
+ }
58
+ const query = `{
59
+ actor {
60
+ account(id: ${params.accountId}) {
61
+ nrql(query: "${params.nrql.replace(/"/g, '\\"')}") {
62
+ results
63
+ metadata {
64
+ eventTypes
65
+ timeWindow {
66
+ begin
67
+ end
68
+ }
69
+ facets
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }`;
75
+ try {
76
+ const response = await this.executeNerdGraphQuery(query);
77
+ if (response.errors) {
78
+ const errorMessage = response.errors[0]?.message || 'NRQL query failed';
79
+ throw new Error(errorMessage);
80
+ }
81
+ const nrqlResult = response.data?.actor?.account?.nrql;
82
+ if (!nrqlResult) {
83
+ throw new Error('No results returned from NRQL query');
84
+ }
85
+ // Detect if it's a time series query
86
+ const isTimeSeries = params.nrql.toLowerCase().includes('timeseries');
87
+ return {
88
+ results: nrqlResult.results || [],
89
+ metadata: {
90
+ ...nrqlResult.metadata,
91
+ timeSeries: isTimeSeries,
92
+ },
93
+ };
94
+ }
95
+ catch (error) {
96
+ if (error.message.includes('Syntax error')) {
97
+ throw new Error(`NRQL Syntax error: ${error.message}`);
98
+ }
99
+ throw error;
100
+ }
101
+ }
102
+ async listApmApplications(accountId) {
103
+ const id = accountId || this.defaultAccountId;
104
+ if (!id) {
105
+ throw new Error('Account ID must be provided');
106
+ }
107
+ const query = `{
108
+ actor {
109
+ entitySearch(query: "domain = 'APM' AND type = 'APPLICATION' AND accountId = '${id}'") {
110
+ results {
111
+ entities {
112
+ guid
113
+ name
114
+ ... on ApmApplicationEntityOutline {
115
+ language
116
+ reporting
117
+ alertSeverity
118
+ tags {
119
+ key
120
+ values
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }`;
128
+ const response = await this.executeNerdGraphQuery(query);
129
+ const entities = response.data?.actor?.entitySearch?.results?.entities || [];
130
+ return entities.map((entity) => ({
131
+ guid: entity.guid,
132
+ name: entity.name,
133
+ language: entity.language || 'unknown',
134
+ reporting: entity.reporting || false,
135
+ alertSeverity: entity.alertSeverity,
136
+ tags: this.parseTags(entity.tags),
137
+ }));
138
+ }
139
+ parseTags(tags) {
140
+ if (!tags)
141
+ return {};
142
+ const result = {};
143
+ tags.forEach((tag) => {
144
+ if (tag.key && tag.values?.length > 0) {
145
+ result[tag.key] = tag.values[0];
146
+ }
147
+ });
148
+ return result;
149
+ }
150
+ async executeNerdGraphQuery(query, variables) {
151
+ // Check if API key is missing or empty
152
+ if (!this.apiKey || this.apiKey === '' || this.apiKey.length === 0) {
153
+ throw new Error('NEW_RELIC_API_KEY environment variable is not set');
154
+ }
155
+ const response = await fetch(NERDGRAPH_URL, {
156
+ method: 'POST',
157
+ headers: {
158
+ 'Content-Type': 'application/json',
159
+ 'API-Key': this.apiKey,
160
+ },
161
+ body: JSON.stringify({ query, variables }),
162
+ });
163
+ if (!response.ok) {
164
+ if (response.status === 401) {
165
+ throw new Error('Unauthorized: Invalid API key');
166
+ }
167
+ throw new Error(`NerdGraph API error: ${response.status} ${response.statusText}`);
168
+ }
169
+ return await response.json();
170
+ }
171
+ }
172
+ exports.NewRelicClient = NewRelicClient;
173
+ //# sourceMappingURL=newrelic-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newrelic-client.js","sourceRoot":"","sources":["../../src/client/newrelic-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { type Tool } from '@modelcontextprotocol/sdk/types.js';
3
+ import { NewRelicClient } from './client/newrelic-client';
4
+ export declare class NewRelicMCPServer {
5
+ private server;
6
+ private client;
7
+ private tools;
8
+ private defaultAccountId?;
9
+ constructor(client?: NewRelicClient);
10
+ private registerTools;
11
+ private setupHandlers;
12
+ start(): Promise<void>;
13
+ executeTool(name: string, args: any): Promise<any>;
14
+ private requiresAccountId;
15
+ getMetadata(): {
16
+ name: string;
17
+ version: string;
18
+ description: string;
19
+ };
20
+ getRegisteredTools(): string[];
21
+ getTool(name: string): Tool | undefined;
22
+ getDefaultAccountId(): string | undefined;
23
+ }
24
+ //# sourceMappingURL=server.d.ts.map