#
tokens: 2525/50000 10/10 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .gitignore
├── .idea
│   ├── .gitignore
│   ├── inspectionProfiles
│   │   └── profiles_settings.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── new_relic.iml
│   └── vcs.xml
├── .python-version
├── app.py
├── pyproject.toml
├── README.md
└── uv.lock
```

# Files

--------------------------------------------------------------------------------
/.python-version:
--------------------------------------------------------------------------------

```
3.13

```

--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------

```
# Default ignored files
/shelf/
/workspace.xml

```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info

# Virtual environments
.venv
./.gitignore

```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/ivlad003-mcp-newrelic-badge.png)](https://mseep.ai/app/ivlad003-mcp-newrelic)

# New Relic MCP Server

A simple Model Context Protocol (MCP) server for querying New Relic logs using NRQL queries. This server enables Large Language Models (LLMs) like Claude to interact with your New Relic data.

## Features

- Query New Relic logs and metrics using NRQL
- Detailed error logging
- Easy integration with Claude Desktop
- Human-readable output formatting
- Configurable New Relic account ID

## Setup Instructions

### Prerequisites

- Python 3.10 or higher
- New Relic account and API key
- Claude Desktop application

### Installation Steps

1. Install `uv` package manager:
```bash
# On macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```

2. Create and setup project:
```bash
# Create directory
mkdir newrelic-mcp
cd newrelic-mcp

# Create virtual environment
uv venv

# Activate virtual environment
source .venv/bin/activate  # On Unix/macOS
.venv\Scripts\activate     # On Windows

# Install dependencies
uv pip install "mcp[cli]" httpx
```

3. Create server file `newrelic_logs_server.py` with the provided code.

4. Configure your environment variables:
```bash
# On Unix/macOS
export NEW_RELIC_API_KEY="your-api-key-here"
export NEW_RELIC_ACCOUNT_ID="your-account-id-here"

# On Windows (CMD)
set NEW_RELIC_API_KEY=your-api-key-here
set NEW_RELIC_ACCOUNT_ID=your-account-id-here

# On Windows (PowerShell)
$env:NEW_RELIC_API_KEY = "your-api-key-here"
$env:NEW_RELIC_ACCOUNT_ID = "your-account-id-here"
```

### Claude Desktop Integration

Configure Claude Desktop by editing your configuration file:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

Add the following configuration:
```json
{
    "mcpServers": {
        "newrelic": {
            "command": "uv",
            "args": [
                "--directory",
                "/absolute/path/to/newrelic-mcp",
                "run",
                "newrelic_logs_server.py"
            ],
            "env": {
                "NEW_RELIC_API_KEY": "your-api-key-here",
                "NEW_RELIC_ACCOUNT_ID": "your-account-id-here"
            }
        }
    }
}
```

## Usage

### Example NRQL Queries

1. Basic Transaction Query:
```sql
SELECT * FROM Transaction SINCE 1 hour ago
```

2. Error Analysis:
```sql
SELECT * FROM Transaction WHERE error IS TRUE SINCE 1 hour ago LIMIT 10
```

3. Performance Analysis:
```sql
SELECT average(duration) FROM Transaction FACET name ORDER BY average(duration) DESC LIMIT 5
```

### Example Claude Prompts

You can ask Claude questions like:
- "Show me all transactions from the last hour"
- "Are there any errors in our application?"
- "What are our slowest endpoints?"

## Debugging

### Viewing Logs

```bash
# On macOS/Linux
tail -f ~/Library/Logs/Claude/mcp-server-newrelic.log

# On Windows
type %APPDATA%\Claude\logs\mcp-server-newrelic.log
```

### Testing with MCP Inspector

Test your server functionality using:
```bash
npx @modelcontextprotocol/inspector uv run newrelic_logs_server.py
```

### Common Issues

1. Authentication Errors:
- Check if NEW_RELIC_API_KEY is set correctly
- Verify API key has correct permissions
- Ensure API key is valid

2. Query Errors:
- Verify NRQL syntax
- Check account ID in code matches your account
- Ensure queried data exists in the time range

3. Connection Issues:
- Check network connectivity
- Verify GraphQL endpoint is accessible
- Ensure no firewalls are blocking connections

## Security Notes

- Never commit API keys to version control
- Use environment variables for sensitive data
- Keep dependencies updated
- Monitor query patterns and access logs

## Development

### Local Testing

1. Set environment variables:
```bash
export NEW_RELIC_API_KEY="your-api-key-here"
export NEW_RELIC_ACCOUNT_ID="your-account-id-here"
```

2. Run the server:
```bash
uv run newrelic_logs_server.py
```

### Code Structure

The server implements:
- Single NRQL query tool
- Configurable New Relic account ID
- Comprehensive error handling
- Detailed logging
- Response formatting

### Testing Changes

1. Modify code as needed
2. Test with MCP Inspector
3. Restart Claude Desktop to apply changes

## Troubleshooting Guide

1. Server Not Starting:
- Check Python version
- Verify all dependencies are installed
- Ensure virtual environment is activated

2. Query Not Working:
- Check logs for detailed error messages
- Verify NRQL syntax
- Ensure data exists in queried time range

3. Claude Not Connecting:
- Verify configuration file syntax
- Check paths are absolute
- Restart Claude Desktop

## Contributing

1. Fork the repository
2. Create a feature branch
3. Submit a pull request

## License

This project is licensed under the MIT License.

## Support

If you encounter issues:
1. Check the logs
2. Review common issues section
3. Test with MCP Inspector
4. File an issue on GitHub
```

--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------

```
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="" vcs="Git" />
  </component>
</project>
```

--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------

```
<component name="InspectionProjectProfileManager">
  <settings>
    <option name="USE_PROJECT_PROFILE" value="false" />
    <version value="1.0" />
  </settings>
</component>
```

--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------

```toml
[project]
name = "mcp-newrelic"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "httpx>=0.28.1",
    "mcp[cli]>=1.2.0",
    "pydantic>=2.10.5",
]

```

--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------

```
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/new_relic.iml" filepath="$PROJECT_DIR$/.idea/new_relic.iml" />
    </modules>
  </component>
</project>
```

--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------

```
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Black">
    <option name="sdkName" value="Python 3.13 (new_relic)" />
  </component>
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (new_relic)" project-jdk-type="Python SDK" />
</project>
```

--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------

```python
import os
import httpx
from mcp.server.fastmcp import FastMCP
import logging

# Initialize FastMCP server
mcp = FastMCP("newrelic-logs")

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

# Constants
NR_GRAPHQL_URL = "https://api.newrelic.com/graphql"
DEFAULT_ACCOUNT_ID = os.getenv("NEW_RELIC_ACCOUNT_ID", "1892029")

@mcp.tool()
async def query_logs(query: str, account_id: str = DEFAULT_ACCOUNT_ID) -> str:
    """Query New Relic logs using NRQL.

    Args:
        query: NRQL query string (e.g., "SELECT * FROM Transaction")
        account_id: New Relic account ID (default from env var)
    """
    graphql_query = f"""
    {{
        actor {{
            account(id: {account_id}) {{
                nrql(query: "{query}") {{
                    results
                }}
            }}
        }}
    }}
    """

    headers = {
        "Content-Type": "application/json",
        "API-Key": os.getenv("NEW_RELIC_API_KEY")
    }

    payload = {
        "query": graphql_query
    }

    try:
        async with httpx.AsyncClient() as client:
            response = await client.post(
                NR_GRAPHQL_URL,
                headers=headers,
                json=payload
            )
            response.raise_for_status()
            result = response.json()

            # Log the full response content
            logger.debug("Response JSON: %s", result)

            # Check for errors in the response
            if "errors" in result:
                logger.error("GraphQL errors: %s", result["errors"])
                return f"GraphQL errors: {result['errors']}"

            # Extract logs from response
            data = result.get("data")
            if data is None:
                logger.error("No 'data' field in response")
                return "Error: No 'data' field in response"

            account = data.get("actor", {}).get("account")
            if account is None:
                logger.error("No 'account' field in 'actor'")
                return "Error: No 'account' field in 'actor'"

            nrql = account.get("nrql")
            if nrql is None:
                logger.error("No 'nrql' field in 'account'")
                return "Error: No 'nrql' field in 'account'"

            logs = nrql.get("results", [])

            # Format the logs into a readable string
            formatted_logs = []
            for log in logs:
                formatted_logs.append("---\n" + "\n".join(f"{k}: {v}" for k, v in log.items()))

            return "\n".join(formatted_logs) if formatted_logs else "No logs found"
    except Exception as e:
        logger.error("Error querying logs: %s", str(e))
        return f"Error querying logs: {str(e)}"


if __name__ == "__main__":
    mcp.run()
```