Skip to main content
Glama

New Relic MCP Server

by cloudbring
nerdgraph-queries.test.ts6.15 kB
import { beforeEach, describe, expect, it, vi } from 'vitest'; import type { NewRelicClient } from '../../../src/client/newrelic-client'; import { NewRelicMCPServer } from '../../../src/server'; describe('NerdGraph Queries Feature', () => { let _server: NewRelicMCPServer; let mockClient: NewRelicClient; beforeEach(() => { mockClient = { validateCredentials: vi.fn().mockResolvedValue(true), getAccountDetails: vi.fn().mockResolvedValue({ accountId: '123456', name: 'Test Account' }), executeNerdGraphQuery: vi.fn().mockResolvedValue({ data: { actor: { account: { id: '123456', name: 'Test Account', }, }, }, }), } as any; process.env.NEW_RELIC_API_KEY = 'test-api-key'; process.env.NEW_RELIC_ACCOUNT_ID = '123456'; _server = new NewRelicMCPServer(mockClient); }); describe('Execute NerdGraph query successfully', () => { it('should execute a valid GraphQL query', async () => { const query = ` { actor { account(id: 123456) { name id } } } `; const result = await mockClient.executeNerdGraphQuery(query); expect(result).toBeDefined(); expect(result.data).toBeDefined(); expect(result.data.actor.account.id).toBe('123456'); expect(result.data.actor.account.name).toBe('Test Account'); }); }); describe('Execute NerdGraph mutation', () => { it('should execute a GraphQL mutation', async () => { mockClient.executeNerdGraphQuery = vi.fn().mockResolvedValue({ data: { alertsNrqlConditionStaticCreate: { id: 'condition-123', name: 'New Condition', }, }, }); const mutation = ` mutation { alertsNrqlConditionStaticCreate( accountId: 123456, policyId: "policy-1", condition: { name: "New Condition", enabled: true } ) { id name } } `; const result = await mockClient.executeNerdGraphQuery(mutation); expect(result.data.alertsNrqlConditionStaticCreate).toBeDefined(); expect(result.data.alertsNrqlConditionStaticCreate.id).toBe('condition-123'); }); }); describe('Handle NerdGraph errors', () => { it('should handle GraphQL errors properly', async () => { mockClient.executeNerdGraphQuery = vi.fn().mockResolvedValue({ errors: [ { message: 'Field "invalidField" does not exist', extensions: { code: 'GRAPHQL_VALIDATION_FAILED' }, }, ], }); const invalidQuery = ` { actor { invalidField } } `; const result = await mockClient.executeNerdGraphQuery(invalidQuery); expect(result.errors).toBeDefined(); expect(result.errors[0].message).toContain('invalidField'); }); }); describe('Query with variables', () => { it('should support query variables', async () => { mockClient.executeNerdGraphQuery = vi.fn().mockResolvedValue({ data: { actor: { entity: { guid: 'entity-123', name: 'Test Entity', }, }, }, }); const query = ` query GetEntity($guid: EntityGuid!) { actor { entity(guid: $guid) { guid name } } } `; const variables = { guid: 'entity-123' }; const result = await mockClient.executeNerdGraphQuery(query, variables); expect(mockClient.executeNerdGraphQuery).toHaveBeenCalledWith(query, variables); expect(result.data.actor.entity.guid).toBe('entity-123'); }); }); describe('Complex nested queries', () => { it('should handle complex nested structures', async () => { mockClient.executeNerdGraphQuery = vi.fn().mockResolvedValue({ data: { actor: { account: { nrql: { results: [ { count: 100, facet: 'error' }, { count: 50, facet: 'warning' }, ], }, }, }, }, }); const query = ` { actor { account(id: 123456) { nrql(query: "SELECT count(*) FROM Transaction FACET error") { results } } } } `; const result = await mockClient.executeNerdGraphQuery(query); expect(result.data.actor.account.nrql.results).toHaveLength(2); expect(result.data.actor.account.nrql.results[0].count).toBe(100); }); }); describe('Rate limiting handling', () => { it('should handle rate limit errors', async () => { mockClient.executeNerdGraphQuery = vi .fn() .mockRejectedValue(new Error('Rate limit exceeded. Please retry after 60 seconds.')); const query = '{ actor { account(id: 123456) { name } } }'; await expect(mockClient.executeNerdGraphQuery(query)).rejects.toThrow('Rate limit exceeded'); }); }); describe('Query introspection', () => { it('should support schema introspection queries', async () => { mockClient.executeNerdGraphQuery = vi.fn().mockResolvedValue({ data: { __schema: { types: [ { name: 'Account', kind: 'OBJECT' }, { name: 'Entity', kind: 'INTERFACE' }, ], }, }, }); const introspectionQuery = ` { __schema { types { name kind } } } `; const result = await mockClient.executeNerdGraphQuery(introspectionQuery); expect(result.data.__schema.types).toBeDefined(); expect(result.data.__schema.types).toContainEqual( expect.objectContaining({ name: 'Account', kind: 'OBJECT' }) ); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cloudbring/newrelic-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server