LogScale MCP Server
by bhayanak
README.md
<p align="center">
<img src="logo.png" alt="Falcon LogScale MCP Server" width="500" height="400" />
</p>
<p align="center">
<strong>LogScale MCP Server</strong><br/>
<em>Query CrowdStrike Falcon LogScale(formerly humio) logs from AI assistants via the Model Context Protocol</em>
</p>
<p align="center">
<a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%E2%89%A5%2018-brightgreen.svg" alt="Node.js ≥ 18"></a>
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.8-blue.svg?logo=typescript&logoColor=white" alt="TypeScript 5.8"></a>
<a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-1.12-purple.svg" alt="MCP SDK 1.12"></a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/coverage-97%25-brightgreen.svg" alt="Coverage 97%">
<img src="https://img.shields.io/badge/tests-67%20passed-brightgreen.svg" alt="67 Tests Passed">
<img src="https://img.shields.io/badge/build-passing-brightgreen.svg" alt="Build Passing">
</p>
<p align="center">
<img src="https://img.shields.io/badge/ESLint-security%20rules-4B32C3.svg?logo=eslint&logoColor=white" alt="ESLint Security">
<img src="https://img.shields.io/badge/Prettier-formatted-F7B93E.svg?logo=prettier&logoColor=white" alt="Prettier">
<img src="https://img.shields.io/badge/CodeQL-analyzed-2980B9.svg" alt="CodeQL">
<img src="https://img.shields.io/badge/Trivy-SBOM%20scanned-1904DA.svg" alt="Trivy SBOM">
<img src="https://img.shields.io/badge/Gitleaks-no%20secrets-critical.svg" alt="Gitleaks">
<img src="https://img.shields.io/badge/pnpm%20audit-0%20vulnerabilities-brightgreen.svg" alt="pnpm Audit Clean">
</p>
<p align="center">
<a href="#features">Features</a> •
<a href="#quick-start">Quick Start</a> •
<a href="#tools">Tools</a> •
<a href="#usage">Usage</a> •
<a href="#cql-query-examples">Queries</a> •
<a href="#security">Security</a> •
<a href="#ci-pipeline">CI</a> •
<a href="#architecture">Architecture</a> •
<a href="#contributing">Contributing</a>
</p>
---
## Introduction
LogScale MCP Server lets you **query CrowdStrike LogScale logs through natural language** in VS Code Copilot Chat, Claude Desktop, or any MCP-compatible client. Instead of writing raw CQL queries and managing API calls, just ask:
> "Show me errors in the xxxx namespace from the last hour"
> "Find all 500 errors from the xyxyxy pod today"
> "Search logs for request ID f6796646b043d231bf67f589b7306e9b"
The server handles query submission, polling, result formatting, and pagination automatically.
## Features
- **2 MCP tools** — `search_logs` and `get_query_job` for comprehensive log querying
- **CrowdStrike Query Language (CQL)** — full support for filters, pipes, aggregations, and field searches
- **Automatic poll loop** — submits query jobs and polls with server-suggested intervals until completion
- **Smart result formatting** — structured output with field statistics, event counts, and metadata
- **Configurable defaults** — custom timeouts, pagination limits, poll intervals, and max events
- **Time range support** — relative (`1h`, `7d`) and absolute (epoch milliseconds) time ranges
- **VS Code Extension** — bundled extension with built-in configuration UI for LogScale connection settings
- **Monorepo architecture** — clean separation between server (`logscale-mcp-server`) and extension (`logscale-mcp-vscode`)
### Quality & Security
| Area | Details |
|------|---------|
| **Test Coverage** | 97% statements · 91% branches · 95% functions — 67 tests across 6 suites |
| **Type Safety** | Strict TypeScript with `noEmit` type checking on every CI run |
| **Linting** | ESLint with `eslint-plugin-security` for vulnerability pattern detection |
| **Formatting** | Prettier-enforced code style across all source and test files |
| **Static Analysis** | GitHub CodeQL with `security-extended` query suite |
| **Dependency Audit** | `pnpm audit` at moderate+ severity — zero known vulnerabilities |
| **SBOM & CVE Scan** | Trivy filesystem scan for CRITICAL and HIGH severity vulnerabilities |
| **Secret Scanning** | Gitleaks in CI + pre-commit hook for local secret detection |
| **Dependency Review** | PR-level review blocking moderate+ severity and GPL-3.0/AGPL-3.0 licenses |
| **Commit Standards** | Conventional Commits enforced via commitlint |
| **Multi-Node Testing** | CI tests on Node.js 18, 20, and 22 |
## Quick Start
### Prerequisites
- **Node.js ≥ 18**
- **pnpm** (recommended) or npm
- A LogScale instance with API access and a Bearer token
### Install from npm
```bash
# Install globally
npm install -g logscale-mcp-server
# Or run directly with npx
npx logscale-mcp-server
```
### Install from Source
```bash
git clone https://github.com/your-org/logscale-mcp-server.git
cd logscale-mcp-server
pnpm install
pnpm -r build
```
### Configuration
| Variable | Required | Description |
|---|---|---|
| `LOGSCALE_BASE_URL` | Yes | LogScale instance URL (include path prefix like `/logs` if needed) |
| `LOGSCALE_API_TOKEN` | Yes | Bearer token for authentication |
| `LOGSCALE_REPOSITORY` | No | Default repository name |
| `LOGSCALE_TIMEOUT_MS` | No | Max poll timeout (default: 60000) |
| `LOGSCALE_POLL_INTERVAL_MS` | No | Poll interval (default: 1000) |
| `LOGSCALE_MAX_EVENTS` | No | Default pagination limit (default: 200) |
## Tools
### `search_logs`
Submit a CQL query, wait for results, and return formatted log events.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `queryString` | string | Yes | CQL query string |
| `start` | string/number | No | Start time — relative (`"1h"`, `"7d"`) or epoch ms |
| `end` | string/number | No | End time — `"now"` or epoch ms |
| `repository` | string | No | Target repository (overrides default) |
| `maxEvents` | number | No | Max events to return (default: 200, max: 500) |
### `get_query_job`
Check status or retrieve results of an existing query job.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | Query job ID from a previous `search_logs` call |
| `repository` | string | No | Repository the job was submitted to |
| `maxEvents` | number | No | Max events to return |
## Usage
### VS Code (MCP)
Add to `.vscode/mcp.json`:
```json
{
"servers": {
"logscale": {
"command": "npx",
"args": ["-y", "logscale-mcp-server"],
"env": {
"LOGSCALE_BASE_URL": "https://your-logscale-instance.com",
"LOGSCALE_API_TOKEN": "your-api-token",
"LOGSCALE_REPOSITORY": "your-repository"
}
}
}
}
```
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"logscale": {
"command": "npx",
"args": ["-y", "logscale-mcp-server"],
"env": {
"LOGSCALE_BASE_URL": "https://your-logscale-instance.com",
"LOGSCALE_API_TOKEN": "your-api-token",
"LOGSCALE_REPOSITORY": "your-repository"
}
}
}
}
```
### VS Code Extension
Install the bundled VS Code extension for a GUI-configured experience or download from marketplace:
```bash
# From VSCode Extensions marketplace
Search "LogScale MCP Server", install.
# From local VSIX
code --install-extension packages/vscode-extension/logscale-mcp-vscode-0.1.0.vsix
```
The extension provides VS Code settings for `logscale.baseUrl`, `logscale.repository`, `logscale.timeoutMs`, `logscale.pollIntervalMs`, and `logscale.maxEvents`.
### Development
```bash
pnpm run dev # Start server in dev mode
pnpm -r build # Build all packages
pnpm run test:coverage # Run tests with coverage
pnpm run ci # Full CI pipeline locally
```
### Test with MCP Inspector
```bash
npx @modelcontextprotocol/inspector node packages/server/dist/index.js
```
## CQL Query Examples
```bash
# Simple namespace filter
"kubernetes.namespace_name" = "your-namespace"
# Filter by namespace AND app label
"kubernetes.namespace_name" = "your-namespace"
| "kubernetes.labels.app_kubernetes_io/instance" = "your-instance-name"
# Search for errors in a namespace
kubernetes.namespace_name = "your-namespace" | ERROR
# Search by correlation ID
kubernetes.namespace_name = "your-namespace" | "f6796646b043d231bf67f589b7306e9b"
# Chain multiple filters
kubernetes.namespace_name = "your-namespace"
| 81bd572b6f202eccb9538408cb764c89
| "Pod Network CIDR is not provided"
# Aggregations
ERROR | groupBy(kubernetes.pod_name, function=count())
ERROR | top(log, limit=10)
ERROR | timechart(span=5m)
```
### Time Ranges
| Format | Example | Description |
|--------|---------|-------------|
| Relative | `"1h"`, `"24h"`, `"7d"`, `"30m"` | Lookback from now |
| Absolute | `1773599400000` | Epoch milliseconds |
| End | `"now"` or epoch ms | End of time window |
## Architecture
```
AI Client (VS Code Copilot, Claude Desktop)
↕ MCP (stdio transport)
LogScale MCP Server (TypeScript / Node.js)
↕ HTTPS (REST API)
CrowdStrike LogScale (Query Jobs API)
```
The server uses LogScale's 2-step Query Jobs API:
1. **Submit** — `POST /api/v1/repositories/{repo}/queryjobs` → returns job ID
2. **Poll** — `GET /api/v1/repositories/{repo}/queryjobs/{id}` → poll until done, return results
## Security
| Control | Implementation |
|---------|---------------|
| **Static Analysis** | CodeQL `security-extended` queries on every push and PR |
| **Dependency Audit** | `pnpm audit` at moderate+ with zero tolerance |
| **SBOM Scanning** | Trivy filesystem scan for CRITICAL/HIGH CVEs |
| **Secret Detection** | Gitleaks CI job + pre-commit hook (full git history scan) |
| **License Compliance** | Dependency review blocks GPL-3.0 and AGPL-3.0 |
| **Security Linting** | `eslint-plugin-security` catches unsafe patterns (eval, non-literal require, etc.) |
| **Supply Chain** | `pnpm.overrides` to force patched transitive dependency versions |
| **Input Validation** | Zod schemas for all tool parameters |
## CI Pipeline
The CI runs **11 jobs** on every push and pull request:
```
┌─────────────┐ ┌───────────────────────┐ ┌──────────────────┐
│ typecheck │ │ lint (ESLint+security)│ │ format (Prettier)│
└──────┬───────┘ └───────────┬────────────┘ └────────┬─────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ test (Node 18 / 20 / 22 + coverage) │
└──────────────────────────────┬───────────────────────────────────┘
▼
┌──────────────────┐
│ build │
└────────┬─────────┘
▼
┌───────────────────────┐
│ package-extension │
│ (VSIX artifact) │
└───────────────────────┘
(parallel)
┌──────────────────┐ ┌──────────┐ ┌────────────────────┐ ┌──────────┐
│ security-audit │ │ codeql │ │ dependency-review │ │ gitleaks │
│ (pnpm audit) │ │ │ │ (PR only) │ │ │
└──────────────────┘ └──────────┘ └────────────────────┘ └──────────┘
│
▼
┌──────────────────┐
│ sbom (Trivy) │
└──────────────────┘
```
## Troubleshooting
### "Unexpected token '<'" / HTML response error
The `LOGSCALE_BASE_URL` is likely incorrect. Many LogScale deployments serve the API under a path prefix (e.g., `/logs`). Check the URL in your browser's network tab — if API calls go to `https://host/logs/api/v1/...`, set:
```
LOGSCALE_BASE_URL=https://your-host/logs
```
### Authentication failures (401/403)
Verify your `LOGSCALE_API_TOKEN` is valid and has read permission on the target repository.
### Repository not found (404)
Check the `LOGSCALE_REPOSITORY` name matches exactly (case-sensitive).
## Contributing
1. Fork the repository
2. Create a feature branch: `git checkout -b feat/my-feature`
3. Make changes following [Conventional Commits](https://www.conventionalcommits.org/)
4. Run the full CI locally: `pnpm run ci`
5. Submit a pull request
### Commit Format
```
feat: add new search filter → minor version bump
fix: handle empty results → patch version bump
feat!: redesign query API → major version bump
```
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues