Context7
Feeds AI the latest docs for libraries and frameworks before it answers, so code it writes does not use outdated, removed functions.
Description from the maker (original English)
Query logs from Graylog: get streams, search messages, aggregate, and get full data.
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
GRAYLOG_BASE_URL_INSTANCE_1, GRAYLOG_API_TOKEN_INSTANCE_1, GRAYLOG_LABEL_INSTANCE_1Values marked secret are keys to your account. Never share them or paste them into a chat.
You need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"graylog": {
"command": "npx",
"args": [
"-y",
"@jperelli/graylog-mcp"
],
"env": {
"GRAYLOG_BASE_URL_INSTANCE_1": "your-value",
"GRAYLOG_API_TOKEN_INSTANCE_1": "your-value",
"GRAYLOG_LABEL_INSTANCE_1": "your-value"
}
}
}
}Run this in your terminal
claude mcp add graylog --env GRAYLOG_BASE_URL_INSTANCE_1=your-value --env GRAYLOG_API_TOKEN_INSTANCE_1=your-value --env GRAYLOG_LABEL_INSTANCE_1=your-value -- npx -y @jperelli/graylog-mcpFill in the empty values before running it.
Paste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"graylog": {
"command": "npx",
"args": [
"-y",
"@jperelli/graylog-mcp"
],
"env": {
"GRAYLOG_BASE_URL_INSTANCE_1": "your-value",
"GRAYLOG_API_TOKEN_INSTANCE_1": "your-value",
"GRAYLOG_LABEL_INSTANCE_1": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"graylog": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@jperelli/graylog-mcp"
],
"env": {
"GRAYLOG_BASE_URL_INSTANCE_1": "your-value",
"GRAYLOG_API_TOKEN_INSTANCE_1": "your-value",
"GRAYLOG_LABEL_INSTANCE_1": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
GRAYLOG_LABEL_INSTANCE_1 envThese settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 7, 2026
The registry name was verified with the GitHub account jperelli, which owns the repo
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
You need to fill in: GRAYLOG_BASE_URL_INSTANCE_1, GRAYLOG_API_TOKEN_INSTANCE_1
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (1.3.0) reached the registry 4 months ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.
In the same category: Context7, Codebase Memory, Exa
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
Feeds AI the latest docs for libraries and frameworks before it answers, so code it writes does not use outdated, removed functions.
Codebase knowledge graph for AI agents — 162 languages, sub-ms queries, 99% fewer tokens.
Connect AI agents to Exa for web search, content fetching, and multi-step research.
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
A minimal MCP (Model Context Protocol) server in JavaScript that integrates with Graylog.
search (read matching log lines across multiple streams), analyze (aggregate matches by a field, with an optional time histogram), list_fields (which fields exist), list_streams (discover readable streams), and get_message (fetch one full document)list_fields and analyze's valueContains let an agent look up real field names and values instead of inventing them, since a wrong guess returns 0 hits and reads as "no logs exist"search returns a concise projection of high-signal fields by default; opt into full documents with verboseConfigure one or more Graylog instances using numbered env vars:
| Variable | Required | Description |
|---|---|---|
GRAYLOG_BASE_URL_INSTANCE_N | yes | Graylog base URL for instance N |
GRAYLOG_API_TOKEN_INSTANCE_N | yes | API token for instance N |
GRAYLOG_LABEL_INSTANCE_N | no | Human-readable label (default: instance_N) |
Replace N with 1, 2, 3, … to register as many instances as needed. Only instances with both BASE_URL and API_TOKEN set will be active.
No installation needed, npx downloads and runs the server automatically.
claude mcp add graylog-mcp \
-e GRAYLOG_BASE_URL_INSTANCE_1=http://your-graylog-production.example.com:9000 \ -e GRAYLOG_API_TOKEN_INSTANCE_1=your_production_token \ -e GRAYLOG_LABEL_INSTANCE_1=production \ -e GRAYLOG_BASE_URL_INSTANCE_2=http://your-graylog-staging.example.com:9000 \ -e GRAYLOG_API_TOKEN_INSTANCE_2=your_staging_token \ -e GRAYLOG_LABEL_INSTANCE_2=staging \ -- npx -y @jperelli/graylog-mcp@latest
Or add it manually to ~/.claude.json:
{
"mcpServers": { "graylog-mcp": { "command": "npx", "args": ["-y", "@jperelli/graylog-mcp@latest"], "env": { "GRAYLOG_BASE_URL_INSTANCE_1": "http://your-graylog-production.example.com:9000", "GRAYLOG_API_TOKEN_INSTANCE_1": "your_production_token", "GRAYLOG_LABEL_INSTANCE_1": "production",
"GRAYLOG_BASE_URL_INSTANCE_2": "http://your-graylog-staging.example.com:9000", "GRAYLOG_API_TOKEN_INSTANCE_2": "your_staging_token", "GRAYLOG_LABEL_INSTANCE_2": "staging" } } } }
Add to ~/.cursor/mcp.json:
{
"mcpServers": { "graylog-mcp": { "command": "npx", "args": ["-y", "@jperelli/graylog-mcp@latest"], "env": { "GRAYLOG_BASE_URL_INSTANCE_1": "http://your-graylog-production.example.com:9000", "GRAYLOG_API_TOKEN_INSTANCE_1": "your_production_token", "GRAYLOG_LABEL_INSTANCE_1": "production",
"GRAYLOG_BASE_URL_INSTANCE_2": "http://your-graylog-staging.example.com:9000", "GRAYLOG_API_TOKEN_INSTANCE_2": "your_staging_token", "GRAYLOG_LABEL_INSTANCE_2": "staging" } } } }
Config file locations:
~/Library/Application Support/Claude/claude_desktop_config.json~/.config/claude-desktop/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonUse the same JSON structure shown above for Cursor.
Once configured, the tools become available and are called automatically when needed. The usual flow is to search the Default Stream (000000000000000000000001), which covers everything the token can read, then analyze to spot patterns, search to read individual lines, and get_message to inspect one hit in full. Reach for list_streams only to scope to a specific named stream. Example prompts:
Search Graylog for errors in the payments namespace in the last 15 minutes.
Query the "staging" instance.
Which containers produced the most errors in the last hour?
Which namespaces have "payments" in the name?
Don't let the agent guess field names or values. A query on a field or value that doesn't exist matches nothing, which looks exactly like "there are no logs". list_fields answers which fields exist, and analyze with valueContains answers which values a field actually has.
List the streams the configured API token can read (id + title). Only readable ones are returned.
You usually don't need this: pass the Default Stream id 000000000000000000000001 to search/analyze to cover everything the token can read. A cluster can hold thousands of streams (the author's has 1,205), so output is capped — use titleContains when you want one specific named stream.
Parameters:
instance (string, optional): Label of the Graylog instance to query. Defaults to the first configured instance.titleContains (string, optional): Case-insensitive substring filter on the stream title (e.g. catalogue).limit (number, optional): Max streams to return. Default: 50. The Default Stream is always included and never counts against the cap.List the message fields that actually exist in the index. Use it before searching on a field you haven't seen in a result, so you never guess a field name.
A cluster indexes thousands of fields (the author's: 3,269), and near-duplicates are common — namespace_name, Pod_namespace, pod_namespace and Namespace may all exist while only one is populated by your shipper. Pass contains to narrow.
Parameters:
contains (string, optional): Case-insensitive substring filter on the field name, e.g. namespace, pod, level.limit (number, optional): Max field names to return. Default: 100.instance (string, optional): Instance label. Defaults to the first configured instance.Read matching log lines across one or more streams, merged newest-first. By default it returns a concise projection of high-signal fields (timestamp, source, level, container_name, pod_name, namespace_name, application_name, service, logger_name, name, msg, err, stack, message) plus each hit's _id/_index, with the raw message body truncated to 500 chars, this keeps the agent's context small. Set verbose: true (or pass explicit fields) to get every populated field, untruncated. Stream IDs are required, an all-streams search is not performed implicitly, because a limited-permission token would be rejected with 403 Not authorized.
name/msg/err/stack are there because a shipper that parses a JSON log line (pino, bunyan, structlog) extracts its keys into real fields. Those fields *are* the summary of the event, and they're cheap — the raw message body that contains them is neither, which is why it's truncated hard by default.
Reach for `analyze` before `search`. Raw lines are the most expensive thing this server returns. A hundred repetitions of one error cost a hundred times as much via
searchas one aggregated row viaanalyze, and tell you less. Usesearchonce you know which line you want.
Tip: to search everything the token can see (including messages not routed to a named stream), pass the Default Stream id
000000000000000000000001.list_streamsalso surfaces it.
Parameters:
query (string, required): Search query, using Graylog/Elasticsearch syntax. Examples: msg:Error, namespace_name:app-payments-qa AND error, source:api-*, *.streams (string, required): Comma-separated stream IDs to search. Get them from list_streams.instance (string, optional): Label of the Graylog instance to query. Defaults to the first configured instance.searchTimeRangeInSeconds (number, optional): Relative time range in seconds. Default: 900 (15 minutes).from / to (string, optional): Absolute window in ISO-8601 UTC (e.g. 2026-07-11 14:00:00). When both are set they override the relative range, use them to investigate a known incident window.searchCountLimit (number, optional): Max number of messages. Default: 50.messageChars (number, optional): Max characters of the raw message body per hit. Default: 500. Raise it only when the detail you need lives in the raw body rather than the parsed fields.verbose (boolean, optional): Return every populated field, untruncated, instead of the concise projection. Default: false.fields (string, optional): Comma-separated explicit field list to return. Overrides the concise projection.The response is { returned, total_matched, streams, messages, note?, projection?, why_no_results? }, where total_matched is the total number of hits across the streams (may exceed returned, which is capped by searchCountLimit); when it does, note explains how to see more.
When a search matches nothing, it tells you why. A bare total_matched: 0 is ambiguous, and the three causes need opposite responses, so why_no_results names the one that applies:
list_fields / analyze.That last case is easy to misread as "this service produced no logs", and it's the reason this project exists in its current shape: the pipeline can lag ingestion by hours under load.
Note on log levels — severity must be discovered, not guessed. Some services emit a top-level Graylog
level(syslog: 3=error, 4=warn). Others log JSON, and the shipper extracts its keys into their *own* fields: pino's{"level":50,"msg":"Error","name":"SvcX"}typically becomes fieldsmsgandname, while its numericlevelis lost — it collides with the container's ownlevel(often7), solevel:50andlevel:ERRORboth match nothing even though the errors are plainly there. Guessing a disjunction likelevel:ERROR OR level:50 OR error OR exception OR fatalis how agents waste turns. Instead runlist_fields(contains: "level","msg","err"), thenanalyzeonmsgto see the actual values. Free-texterrorworks as a fallback; don't assumeexceptionorfatalexist. And avoid"level":50as a query, a quoted string before:is invalid Lucene.
Aggregate matching messages by the top values of a field instead of returning raw lines, e.g. which source, container_name, or level dominates the errors in a window. Optionally add a time histogram of total
Only the beginning is shown; read the rest in the repo