# 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
[](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()
```