Skip to main content
Glama
Aashish079

Logpoint MCP Server

by Aashish079

Logpoint MCP Server

Logpoint Logo

An MCP server that lets an LLM triage agent (Claude, or an n8n AI Agent) work with a Logpoint SIEM. It can read incidents, run searches, enrich indicators with threat intel and, when you allow it, comment on, assign, resolve and close incidents.

It talks to the real Logpoint Incident, Search and Alert Rule APIs. Nothing is mocked.

Architecture

Architecture diagram

  1. Clients. Claude connects over stdio. n8n and other remote agents use streamable HTTP with a bearer token.

  2. MCP server. Tools are grouped as read, enrich and write. Every call passes through guardrails, then reaches the Logpoint clients or the integrations.

  3. Logpoint SIEM. The server uses the Incident, Search and Alert Rule APIs.

  4. Optional services. VirusTotal, AbuseIPDB, MISP, MITRE ATT&CK, Jira, SMTP and Microsoft Teams.

Related MCP server: wazuh-mcp

Tools

Tool

What it does

Registered when

get_incidents

Incidents in a time window, filtered by status, risk or name, newest first

always

get_incident_details

Rows the alert rule produced (aggregates for chart rules)

always

get_incident_raw_events

Raw events behind an incident: re-runs the rule's search part over the incident window

always

get_incident_states

Live status, assignee and comments, including closed incidents

always

list_users

Users and groups, for assignment

always

search_logs / get_search_results

Run a Logpoint query and wait for results

always

list_repos

Searchable repos

always

mitre_attack_lookup

MITRE ATT&CK Enterprise techniques by id or keywords (official STIX catalog)

always

list_alert_rules / get_alert_rule

Alert rule queries, risk and MITRE mapping

LOGPOINT_JWT_* set

lookup_virustotal / lookup_abuseipdb / lookup_misp

Indicator reputation

API key set

add_incident_comment, assign_incidents, resolve_incidents, close_incidents, reopen_incidents

Change incidents

MCP_ALLOW_WRITE_ACTIONS=true

create_jira_ticket

Open a Jira issue

writes allowed + JIRA_* set

send_email

Email allowlisted SOC recipients

writes allowed + SMTP_* set

announce_teams_triage_run

Timestamped start-of-run message that @mentions the Teams channel

writes allowed + TEAMS_WEBHOOK_URL and TEAMS_ANNOUNCE_WEBHOOK_URL set

notify_teams_triage

Post each triage outcome (verdict, severity, summary, evidence, actions) to a Teams channel

writes allowed + TEAMS_WEBHOOK_URL set

Quick start

Requires Python 3.10 or later.

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
cp .env.example .env        # then fill in LOGPOINT_URL, LOGPOINT_USERNAME, LOGPOINT_SECRET_KEY
.venv/bin/logpoint-mcp --check

--check checks the configuration and Logpoint access, then exits. Run it before you connect a client.

Connecting a client

Claude Code / Claude Desktop (stdio)

Add the server to .mcp.json (Claude Code) or claude_desktop_config.json (Claude Desktop):

{
  "mcpServers": {
    "logpoint": {
      "command": "/absolute/path/to/MCPServer-Logpoint/.venv/bin/logpoint-mcp",
      "env": {
        "LOGPOINT_URL": "https://logpoint.example.com",
        "LOGPOINT_USERNAME": "api-user",
        "LOGPOINT_SECRET_KEY": "..."
      }
    }
  }
}

The client launches the server from its own working directory, so a .env file in the repo is not read. Put the settings in env instead. Keep files that contain secrets out of version control (.mcp.json is in .gitignore).

Remote clients and n8n (streamable HTTP)

export MCP_AUTH_TOKENS="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')"
logpoint-mcp --transport http --host 0.0.0.0 --port 8000
  • MCP endpoint: http://<host>:8000/mcp. Clients send Authorization: Bearer <token>. In n8n, use the MCP Client Tool node with HTTP Streamable transport and header auth.

  • Health checks: GET /health (liveness) and GET /ready (checks Logpoint access) don't need a token.

  • Authentication is enforced. The server refuses to listen on a non-loopback address without MCP_AUTH_TOKENS, unless you set MCP_ALLOW_UNAUTHENTICATED=true because a proxy in front of it handles authentication.

  • Behind a reverse proxy, set MCP_ALLOWED_HOSTS to the public host name (DNS-rebinding protection) and terminate TLS at the proxy.

Docker

docker build -t logpoint-mcp .
docker run --env-file .env -e MCP_AUTH_TOKENS=... -p 8000:8000 logpoint-mcp

Configuration

Every setting is an environment variable. See .env.example for the full list.

Variable

Default

Notes

LOGPOINT_URL, LOGPOINT_USERNAME, LOGPOINT_SECRET_KEY

required

API user credentials. They stay on the server and are never tool arguments.

LOGPOINT_VERIFY_SSL / LOGPOINT_CA_BUNDLE

true

For a self-signed Logpoint, use the CA bundle instead of turning verification off.

LOGPOINT_SEARCH_TIMEOUT_SECONDS

90

Longest a search tool waits before returning partial results.

LOGPOINT_MAX_ROWS / LOGPOINT_MAX_FIELD_CHARS

500 / 2000

Caps tool output so it fits in an LLM context window.

MCP_ALLOW_WRITE_ACTIONS

false

Off: the agent can only read.

MCP_COMMENT_PREFIX

[AI triage]

Tags every comment the agent writes.

MCP_LOG_FORMAT

text

json for log shipping. Write actions are logged on the logpoint_mcp.audit logger.

Teams notifications

When notify_teams_triage is registered, the server tells the agent to call it once after every triage, after any comment, close or Jira action, so the card lists what actually happened. The card shows the verdict (colour-coded), severity, incident ids, summary, evidence, actions taken and the Jira key.

To set it up, open the channel in Teams and choose ⋯ > Workflows > Post to a channel when a webhook request is received. Put the URL it gives you in TEAMS_WEBHOOK_URL. The older Office 365 connector webhooks are retired and aren't supported.

Start-of-run announcement with @channel (optional)

With TEAMS_ANNOUNCE_WEBHOOK_URL set, the agent calls announce_teams_triage_run once before the first card of a run. It posts a message like @SOC Alerts [AI triage] Triage run started 2026-10-13 09:00 UTC: 5 incidents follow.

Workflow cards can only mention individual users, not a channel, team or tag. So this message goes through a second workflow that posts with Microsoft Graph as a user. Use a dedicated service account, because the message shows up as that account's post.

  1. In Power Automate, create a flow with the trigger When a Teams webhook request is received (anyone can trigger). The server sends {"kind", "timestamp", "incident_count", "text"}.

  2. Add Office 365 Groups > Send an HTTP request, signed in as the service account (a member of the team):

    • Method POST, URI https://graph.microsoft.com/v1.0/teams/<team-id>/channels/<channel-id>/messages

    • Body (replace <channel-name>, and insert the trigger's text as dynamic content):

      {
        "body": {"contentType": "html", "content": "<at id=\"0\"><channel-name></at> @{triggerBody()?['text']}"},
        "mentions": [{
          "id": 0,
          "mentionText": "<channel-name>",
          "mentioned": {"conversation": {"id": "<channel-id>", "displayName": "<channel-name>",
                                         "conversationIdentityType": "channel"}}
        }]
      }
  3. Save, then put the flow's webhook URL in TEAMS_ANNOUNCE_WEBHOOK_URL.

The team and channel ids are in the channel link (⋯ > Get link to channel): groupId is the team id, and the 19:…@thread.tacv2 part is the channel id. An @channel mention notifies members who show or follow the channel. To reach everyone in the team, use "conversationIdentityType": "team" with the team id and name instead.

Logpoint behaviour this server handles

These quirks were confirmed against a live Logpoint and are built into the client:

  • Two incident ids. get_incidents returns id (24 hex, the object id) and incident_id (32 hex). Every API call takes id, and the tools reject incident_id with a hint.

  • Closed incidents are missing from /incidents. get_incident_states combines /incident_states and /incidents. An id that's in neither is reported as closed with "inferred": true.

  • Close order is enforced. Logpoint only resolves or closes incidents assigned to the API user, and only closes resolved ones. resolve_incidents and close_incidents assign and resolve first where needed, and report what they did.

  • Incident details are aggregates. get_incident_details returns what the rule produced. get_incident_raw_events re-runs the part of the rule query before the first | over the incident's time range and repos.

  • Comments are UI-escaped. The Logpoint UI double-escapes " ' < > &, so comments swap them for look-alike characters.

  • Rejected queries are errors. A query Logpoint rejects (e.g. an unquoted process) raises an error, never an empty result.

Security model

  • Read-only by default. Write and outbound tools are only registered when MCP_ALLOW_WRITE_ACTIONS=true, and each is annotated (readOnlyHint, destructiveHint) so clients can ask for confirmation.

  • Log content is untrusted. Its text can contain prompt injection, so send_email only reaches SMTP_ALLOWED_RECIPIENTS, and the Jira project and Teams channel are fixed by configuration. URLs in Teams cards are defanged (hxxps://) and Markdown links are broken, so a log line can't plant a clickable link in the SOC channel.

  • Private IPs stay internal. They're never sent to VirusTotal or AbuseIPDB.

  • Secrets stay out of output. They're SecretStr in memory, and error messages never include request bodies or the Teams webhook URL.

  • Retries are safe. Reads retry transient failures with backoff. Writes are only retried when the request can't have reached Logpoint (connection failure, HTTP 429), so a comment is never posted twice.

Development

.venv/bin/pytest                               # unit tests (fake Logpoint via httpx.MockTransport)
LOGPOINT_LIVE_TESTS=1 .venv/bin/pytest tests/live -v   # read-only checks against a real Logpoint
logpoint_mcp/
├── __main__.py         CLI: stdio | http | --check
├── config.py           Environment-driven settings, one section per integration
├── server.py           MCP tool definitions and registration rules
├── http_app.py         Streamable HTTP app: bearer auth, /health, /ready
├── services.py         Builds clients from settings and owns their lifecycle
├── http.py             Shared httpx client and retry policy
├── logpoint/           Logpoint API clients (transport, incidents, search, alert rules)
└── integrations/       VirusTotal, AbuseIPDB, MISP, Jira, SMTP, Teams, MITRE ATT&CK

To add a tool, put the API call in a client under logpoint/ or integrations/ and test it against the fake server. Then register it in server.py under the right risk group.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that provides AI assistants with comprehensive access to n8n workflow automation nodes, properties, and documentation. It enables models like Claude to search for nodes, access configuration templates, and manage workflows through natural language.
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    An MCP server for the Wazuh SIEM/XDR platform that enables users to query agents, security alerts, detection rules, and decoders through Claude or other MCP clients. It provides specialized tools and prompts for investigating security alerts, performing agent health checks, and generating environmental security overviews.
    28
    116 npm
    7
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A security-focused MCP server that enables automated log retrieval and threat analysis using LangGraph orchestration and RAG. It allows users to detect suspicious activity and generate structured security insights by integrating LLM reasoning with log data and runbook documentation.
    -