mcp-syslog
Enables secure search, tail, grep, and correlation of centrally collected infrastructure logs, turning blind restarts into informed remediation decisions.
README
mcp-syslog-crunchtools
MCP server for the logs collected by crunchtools/syslog.
Built for RT #1460, to close a specific gap: Hermes gets paged by Nagios and can restart a service, but it cannot read the service's logs — so every remediation is a blind restart. This turns that into an informed one.
Capabilities
| Tool | What it answers |
|---|---|
syslog_sources_tool |
What can I query? |
syslog_search_tool |
Show me ERRs from this service in the last 15 minutes |
syslog_grep_tool |
Where does this string appear across the whole fleet? |
syslog_tail_tool |
What are this service's most recent lines? |
syslog_context_tool |
What was everything saying around 03:14? |
syslog_stats_tool |
Which service is loudest, and which is actually unhealthy? |
The triage loop
nagios_current_problems_tool → what is broken
syslog_search_tool(source=…, → why it broke
severity="ERR",
since="15m")
syslog_context_tool(timestamp=…) → what else was happening at that moment
nagios_schedule_check_tool → confirm the fix
syslog_context_tool without a source is the one that earns its keep. It spans
every source at once, which is how "the app died" gets connected to "the database
container OOMed four seconds earlier".
Design notes
Every result is bounded, and says when it is. Logs are unbounded and this output lands in a model's context window. Each tool caps its results, caps how many lines it will scan, and annotates the answer when either limit is hit:
[!] Stopped after the 2,000,000-line scan limit, so this result is INCOMPLETE
and an empty or short result does not mean nothing happened.
That annotation is load-bearing. A caller that cannot distinguish "no errors occurred" from "I stopped looking" will draw the wrong conclusion from an empty result — and this server exists to inform remediation decisions.
Time filtering is cheap. The collector puts the date in the filename, so a ten-minute query opens one file rather than reading ninety days of history.
Source names are untrusted. They come from a model and are used to build a
filesystem path. Each is resolved and then confirmed to still be inside the log
root, which catches traversal, absolute paths, and symlinks pointing out of the
tree — see tests/test_security.py.
Severity is "at least this severe". severity="ERR" returns ERR, CRIT, ALERT
and EMERG. An unrecognised severity is kept rather than dropped, on the grounds
that hiding a line you do not understand is worse than showing it — but it is
not counted as an error in syslog_stats_tool, or a healthy service would
report a 57% error rate.
Severity is not badness. Podman records anything a container writes to stderr
at priority err, and plenty of services log routine INFO there. On lotor,
mcp-trentina sits around 65% "ERR" while being entirely healthy:
PRIORITY=3 | 2026-08-23 15:55:24 INFO httpx: HTTP Request: GET https://... "200 OK"
The collector is reporting the journal faithfully; the journal is reporting the file descriptor. Read the message, and prefer a change in error rate to its absolute value. This caveat is in the server's MCP instructions too, so an agent querying it is told the same thing.
Two line formats are parsed. The collector emitted five fields before 2026-08-23 and six after, and the old lines stay in retention for 90 days. Which layout a line uses is decided by where a real severity sits, not by counting fields.
Log format
The collector writes six space-delimited fields:
2026-08-23T15:41:52+00:00 crunchtools.com crunchtools.com httpd ERR AH00169: caught SIGTERM
└─ timestamp ───────────┘ └─ host ──────┘ └─ source ────┘ └prog┘ └sev┘ └─ message ────────┘
source is the log stream — normally a container name. program is the process
inside it, which matters for systemd containers where httpd, php-fpm and
mariadb all file under one service name.
Configuration
| Variable | Default | Purpose |
|---|---|---|
SYSLOG_LOG_ROOT |
/logs |
Collector log root, mounted read-only |
SYSLOG_MAX_RESULTS |
200 |
Cap on entries returned per call |
SYSLOG_SCAN_LIMIT |
2000000 |
Cap on lines examined per call |
No credentials — the server reads files off a read-only bind mount.
Running
podman run -d --name mcp-syslog \
--network crunchtools \
-p 127.0.0.1:8027:8027 \
-v /srv/syslog.crunchtools.com/data/logs:/logs:ro \
quay.io/crunchtools/mcp-syslog:latest \
--transport streamable-http --host 0.0.0.0 --port 8027
Mount :ro. This server never needs to write, and a read-only mount means a bug
here cannot destroy the forensic record it exists to protect.
Development
uv sync
uv run ruff check src tests
uv run mypy src
uv run pytest -v
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。