MCP Server Malcolm
MCP server for Malcolm (Zeek/Suricata/Arkime/OpenSearch): threat-hunting access for AI agents
Connector by nagameTW · GitHub account verified by the MCP Registry
Chalk Labs
Need help deploying MCP Server Malcolm?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.
npx agentmarket install connector/nagametw-mcp-server-malcolm
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.
- Tools
- 51 read · 6 write · 1 delete
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Tools by what they do 58
Read from the source code; the running server may list different tools.
Read 51 · Look things up without changing anything.
arkime_build_queryarkime_connectionsarkime_cronsarkime_field_searcharkime_file_by_hasharkime_hunt_statusarkime_multiuniquearkime_node_statsarkime_pcap_filesarkime_reverse_dnsarkime_session_detailarkime_session_file_by_hash
Show 39 more tools
arkime_session_payloadarkime_session_pcaparkime_sessionsarkime_sessions_csvarkime_sessions_summaryarkime_shortcutsarkime_spigrapharkime_spigraphhierarchyarkime_spiviewarkime_uniquearkime_viewscluster_healthcountindex_mappinglist_indicesmalcolm_aggregatemalcolm_alerting_alertsmalcolm_alerting_monitor_detailmalcolm_alerting_monitorsmalcolm_alertsmalcolm_anomaly_detectorsmalcolm_anomaly_resultsmalcolm_dashboard_exportmalcolm_data_coveragemalcolm_extract_filemalcolm_field_profilemalcolm_field_searchmalcolm_field_valuesmalcolm_file_scansmalcolm_netbox_lookupmalcolm_netbox_querymalcolm_netbox_sitesmalcolm_pingmalcolm_related_sessionsmalcolm_saved_object_detailmalcolm_saved_objectsmalcolm_searchmalcolm_service_statussearch_dsl
Write 6 · Create, change, send or run things.
arkime_add_tagsarkime_create_huntarkime_create_shortcutarkime_create_viewmalcolm_create_alertmalcolm_upload_pcap
Delete 1 · Delete, drop, revoke or wipe things.
arkime_cancel_hunt
Network hosts it talks to 2
github.com· found in codeglama.ai· found in code
Files it touches
- Any path the agent passes to its tools
Tools (58)
Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].
arkime_add_tagsTag Arkime sessionsAdd label tag(s) to existing Arkime session(s) (POST /arkime/api/sessions/addtags). Use this to mark sessions you have already found — first run arkime_sessions to get the session ids, then pass them here. To label a standing pattern instead of one set of ids, Arkime's cron queries do it on a schedule; arkime_crons shows the ones this deployment runs. Additive only: it appends tags and changes nothing else. Arkime skips a tag a session already carries, so a repeat adds no duplicates, but it is not a safe retry — it re-runs the update on every id, and a batch that reached some ids and not othe…
arkime_build_queryCompile an Arkime expression to OpenSearch DSLread-onlyTranslate an Arkime expression into the OpenSearch DSL it compiles to, without running it. Do NOT use this to run a search: nothing is executed and no session comes back. Come here only when the DSL itself is the goal — a substring, wildcard, fuzzy or script clause Arkime's syntax cannot say, or a look at the compiled query before spending a scan on it. Compile the part the expression can express, edit the returned DSL, then run it with search_dsl (or count, which takes the inner query clause only). When the expression already says what you mean, send it straight to arkime_sessions for the ro…
arkime_cancel_huntCancel hunt jobcan change or delete dataStop an Arkime hunt job that is queued or running (PUT /arkime/api/hunt/<id>/cancel). Use this to call off an arkime_create_hunt that was scoped too widely: a hunt has every capture node re-read raw PCAP, and this is the only way to make it stop. Take the id from arkime_hunt_status with active_only=true; the hunt *name* is rejected. Not additive like the rest of this class: it ends work in progress and the scan cannot be resumed, though the hunt row and whatever it matched before stopping stay in place and stay visible to arkime_hunt_status. An id Arkime cannot act on — one that never existed…
arkime_connectionsBuild connection graphread-onlyBuild a source/destination connection graph of who talked to whom. Returns nodes and links between two fields — useful for tracing lateral movement or mapping which hosts a suspect IP communicated with. NOTE the src/dst fields take Arkime *db* names (srcIp, dstIp, dstPort, node) or the dotted storage paths (source.ip, destination.port), which resolve to the same graph; the one vocabulary this route rejects is the expression names arkime_sessions uses in `expression` (ip.src, port.dst). For distinct field-tuple pairs as text rather than a graph use arkime_multiunique; for a nested top-N hierar…
arkime_create_huntCreate hunt jobQueue an Arkime hunt job that re-scans stored PCAP for a byte/regex pattern. Use this only when indexed session metadata can't answer the question and you must look inside packet payloads. It is expensive: capture nodes re-read raw PCAP, so scope it tightly. Before creating one, size it with arkime_sessions_summary — same expression, same window, same dialect — and pass its session total as total_sessions. To tag sessions you already found instead, use arkime_add_tags; to save a metadata search, use arkime_create_view. Additive — queues a new job and changes nothing existing (calling twice qu…
arkime_create_shortcutCreate Arkime shortcutCreate an Arkime shortcut — a named value list / IOC set (POST /arkime/api/shortcut). Use this to store a reusable list of values (IPs, hostnames, hashes) that any Arkime expression can reference as $<name>, e.g. ip == $c2_ips. To save a whole search expression instead, use arkime_create_view. Additive — creates a new shortcut and changes nothing existing (calling twice with the same name creates a second shortcut). The action is audited, and the tool is registered only when the arkime-view write class is enabled. Read it back with arkime_shortcuts, which hands you the exact $name token to pa…
arkime_create_viewSave Arkime viewSave an Arkime search view — a named, reusable expression (POST /arkime/api/view). Use this to persist a hunt query so analysts can rerun it from the Arkime UI. To save a reusable value list (IOC set) instead, use arkime_create_shortcut; to actually run a payload search now, use arkime_create_hunt. Additive — creates a new view and changes nothing existing (calling twice with the same name creates a second view). The action is audited, and the tool is registered only when the arkime-view write class is enabled. Arkime files the view under the account this server authenticates as and shares it…
arkime_cronsList Arkime cron queriesread-onlyList Arkime's cron queries — saved expressions that re-run on a schedule. Use this for two questions. First, the same one arkime_views answers: which searches have analysts thought worth keeping. Second, and only this tool can answer it: where a tag came from. A cron query re-runs its expression every few minutes and stamps its own tags onto whatever matches, so those tags sit in session data with nothing in the session explaining them — this list is the explanation. For saved searches nobody schedules use arkime_views, for named value lists (IOC sets) use arkime_shortcuts, and to see the tag…
arkime_field_searchSearch Arkime expression fieldsread-onlyDiscover the field names Arkime's routes accept — call before writing one. Arkime names the same field more than once, and which spelling a parameter wants is decided per PARAMETER, not per tool. This is the field-discovery tool for every arkime_* tool, as malcolm_field_search is for the malcolm_* ones. Returns "exp | db | type | group" lines with the help text. Route the two columns like this: - "exp" (ip.src, port.dst, protocols): every `expression` argument, and the field lists of arkime_unique, arkime_multiunique and arkime_spigraphhierarchy. exp=srcIp,dstIp gets the body "Unknown …
arkime_file_by_hashExtract file by hashread-onlyExtract the transferred file matching a content hash across sessions; returns METADATA ONLY. Pivots from a file-hash IOC to the actual bytes: Arkime finds the most recent session carrying a body with this hash, resolves the capture node, and fetches the file. That "most recent" is the catch — when the same file moved several times, this answers about the last transfer, which is usually not the one under investigation. Use this to find out whether a known-bad hash appeared at all, and arkime_session_file_by_hash to pin the answer to a session you already hold — a "no match" here is not proof t…
arkime_hunt_statusList hunt jobsread-onlyList Arkime hunt jobs with their progress, match counts and status. Use this to see what packet-payload searches this Arkime is running or has run — the ones a human queued in the Arkime UI as much as the ones arkime_create_hunt queued, since both land in the same list. Poll it to watch a job finish and see how many sessions matched, and read a hunt's `id` here before passing it to arkime_cancel_hunt. Registered unconditionally: it only reads /arkime/api/hunts, so it stays available with every write class off; creating and cancelling hunts are the parts the hunt-job write class gates. Note th…
arkime_multiuniqueList unique field combinationsread-onlyList distinct value COMBINATIONS across a tuple of Arkime fields as plain text. Like arkime_unique but for a field tuple — e.g. every distinct (source.ip, destination.port) pair. Good for spotting a host scanning many ports, or a few talkers behind a lot of traffic. For a single field use arkime_unique; for a source/destination graph use arkime_connections; for a nested hierarchy use arkime_spigraphhierarchy. Returns plain TEXT (one combination per line, not JSON). "(no values)" with no time range usually means the data predates Arkime's default recent window rather than being absent: pass t…
arkime_node_statsCheck capture node healthread-onlyReport each Arkime capture node's health: drops, disk, memory, queues. Use this to decide whether the data can be trusted before concluding anything from an absence: a node dropping packets or out of disk has gaps that look exactly like "no such traffic". For whether the Malcolm services are up at all use malcolm_service_status, and for OpenSearch cluster state use cluster_health — this one is about the capture side. `packets_dropped` is a running total, not a rate, so a non-zero one is history rather than a live fault; `dropped_per_sec` is the rate over Arkime's last stats interval, and the…
arkime_pcap_filesList indexed PCAP filesread-onlyList the PCAP files Arkime has indexed, with each file's coverage. Use this to answer "what capture does this Malcolm hold" — which files exist, how big they are, how many sessions each carries and the time span it covers. That is the file-level view; for the dataset-level view (how fresh each sensor is, how many documents per log type) use malcolm_data_coverage, and to search the sessions themselves use arkime_sessions. On one node, an interval between a file's last packet and the next file's first is an interval with no captured packets, and no search can tell you whether the link was quie…
arkime_reverse_dnsReverse-resolve an IPread-onlyResolve one IP address to its PTR hostname, using Arkime's resolver. Use this to put a name on an external address a session talked to — `idf-rtr.example.com` says more than `198.51.100.1`. For internal assets, malcolm_netbox_lookup gives a far richer answer than a PTR record. This is a live outbound PTR query leaving the Malcolm deployment now, not a read of the capture: it answers `dns.google` for 8.8.8.8 whether or not that name appears anywhere in the capture. So it reports DNS today rather than the traffic, and resolving an address an adversary controls can signal your interest to them.…
Show 43 more tools
arkime_session_detailLook up one session by idread-onlyFetch the session Arkime holds under one id — a point lookup, not a search. What comes back is the full stored document for that session, including @timestamp, `tags`, the `event` block and the Zeek / Suricata detail that arkime_sessions rows leave out. For the session's raw packets use arkime_session_pcap; for what the two sides actually sent, the payload bytes rather than parsed fields, use arkime_session_payload; for distinct values across many sessions use arkime_unique / arkime_spiview. An id this deployment does not hold is answered with a sentence rather than an error, so a bare "no s…
arkime_session_file_by_hashFetch a file carried by ONE sessionread-onlyFetch the file one NAMED session carried, by content hash; returns METADATA ONLY. Session-scoped, which is the whole difference from arkime_file_by_hash: that one serves the most recent body carrying the hash across all sessions, so once a file has moved twice it answers about the wrong transfer. Prefer this whenever you hold a session id: this route can serve the body from each session that carried a hash while the sibling answers found:false, "No match found." for the same hash. Use malcolm_extract_file instead when Zeek carved the file to disk — that needs no session, but only works where …
arkime_session_payloadRead a session's decoded payloadread-onlyRead the decoded payload of one Arkime session — the bytes that crossed the wire. This is the only tool here that returns payload CONTENT. The siblings deliberately do not: arkime_session_pcap downloads the capture and reports metadata only, arkime_session_detail returns parsed fields, and arkime_file_by_hash / arkime_session_file_by_hash report a carried file's size and magic without its bytes. Use those when you need provenance or a hash; use this when the question is what was said — the HTTP request, the Modbus function code, the cleartext credential. Being payload, it can carry hostile co…
arkime_session_pcapDownload session PCAPread-onlyFetch and validate the PCAP for one or more Arkime sessions; returns METADATA ONLY. Downloads the raw PCAP bytes, checks the file-magic (pcap/pcapng), and returns metadata (magic, format, size) only — never the raw bytes, and nothing is persisted to disk. A download over 500 MB is refused before a byte is read; url_only=True is the way through, and the way to hand the URL to something outside this agent. Needs a session id, which only arkime_sessions produces. For a session's parsed fields rather than its packets use arkime_session_detail; for the bytes that crossed the wire rather than the …
arkime_sessionsSearch Arkime sessionsread-onlySearch Arkime sessions by expression; returns trimmed rows each carrying a session id. This is the ONLY search returning a session id, and every session-scoped tool needs one: arkime_session_detail, arkime_session_pcap, arkime_session_payload, arkime_session_file_by_hash and arkime_add_tags. For one session's own row use arkime_session_detail; for its PCAP bytes/metadata use arkime_session_pcap. To search with Malcolm filter dicts and dateparser times instead of Arkime expressions and epoch seconds, use malcolm_search. Returns `matched` (how many sessions the expression found, which is usuall…
arkime_sessions_csvExport sessions as CSVread-onlyExport many sessions as a compact CSV table, one row each. Use this when you want a lot of sessions cheaply: CSV costs far fewer tokens than the same rows as JSON, so it suits "show me every DNS session this host made" when you intend to read the result as a table. Use arkime_sessions instead when you need a session id to drill into (this returns none), and arkime_connections for a who-talked-to-whom summary. Returns raw CSV TEXT with a header row, not JSON. `limit` bounds the rows exactly. A request naming a column Arkime does not accept hangs rather than failing, so a timeout is reported a…
arkime_sessions_summarySize a session set before acting on itread-onlyTotal sessions, bytes and packets for an expression, plus per-field breakdowns. Sizes a result set in one call, before something expensive acts on it. It is what arkime_create_hunt's total_sessions wants, in one call and in the same dialect — count means a dialect switch, and neither count nor arkime_sessions reports bytes or packets. For the matching sessions themselves use arkime_sessions, and for a value distribution without the totals use arkime_unique or arkime_spiview. Returns JSON {"totals", "breakdowns"}: totals carry sessions, bytes, dataBytes, packets and the first/last packet time…
arkime_shortcutsList saved Arkime value listsread-onlyList Arkime's named value lists (IOC sets) and what each one contains. A shortcut is a named list of IPs, strings or numbers that an expression can reference as `$name` instead of spelling every value out. Use this before writing an expression so you reference a list that exists and know what is in it. For saved queries rather than value lists use arkime_views, for scheduled queries that stamp their own tags use arkime_crons, and to add a list of your own use arkime_create_shortcut (needs the arkime-view write class). Arkime scopes shortcuts by owner and role the same way it scopes views: it…
arkime_spigraphGraph top values over timeread-onlyReturn top values of ONE Arkime field plus a per-value time-series graph. Use for top talkers or spotting a value that spikes over time. For distinct values of one field without the graph use arkime_unique; for a nested multi-level hierarchy use arkime_spigraphhierarchy; for many fields profiled at once use arkime_spiview. Returns the raw Arkime spigraph response (top values with time-bucketed counts). The bucket width is Arkime's choice, taken from the range asked for and not exposed as a parameter: it widens as the range does. Buckets holding no session are left out entirely, so a window r…
arkime_spigraphhierarchyBuild nested field hierarchyread-onlyBuild a nested top-N hierarchy across Arkime fields (a treemap / drill-down). Returns a nested hierarchy (level 1 -> its top level-2 values -> ...), matching Arkime's SPI-graph hierarchy view. Unlike malcolm_aggregate's flat multi-field buckets and arkime_multiunique's flat tuple list, the result is nested. For a single field plus a time graph use arkime_spigraph; for a source/destination graph use arkime_connections. Returns the raw Arkime spigraph-hierarchy response (nested value tree). Level 1 is the outermost, and every deeper level's top values are counted inside their own parent rather…
arkime_spiviewProfile many fields at onceread-onlyProfile top values across SEVERAL Arkime fields at once, each with counts. One call covers many fields — lighter than running one aggregation per field. For a single field use arkime_unique (plain text) or arkime_spigraph (adds a time graph); for distinct field-tuple combinations use arkime_multiunique; for a nested drill-down hierarchy use arkime_spigraphhierarchy. Returns the raw Arkime spiview response (per-field top values with counts). Each field also reports sum_other_doc_count, the sessions its listed values do not account for; a large one means the top-N hid most of the distribution.…
arkime_uniqueList unique values of one fieldread-onlyList distinct values of ONE Arkime field as plain text, optionally with counts. For distinct value COMBINATIONS across a tuple of fields use arkime_multiunique; for top values of one field plus a time-series graph use arkime_spigraph; to profile many fields in one call use arkime_spiview. Lighter than a full aggregation when you only need to see what values a field holds. Returns plain TEXT (one value per line, not JSON) — Arkime streams it directly. "(no values)" has TWO causes and this route cannot tell them apart: the window holds nothing, or the field name does not resolve. field="nosuch…
arkime_viewsList saved Arkime viewsread-onlyList the saved search views this Arkime holds, with each one's expression. Use this to find the queries analysts already curated before writing your own — a view names an investigation someone thought worth keeping. Take a view's `expression` and pass it to arkime_sessions to run it. For named value lists (IOC sets) rather than saved queries, use arkime_shortcuts; to discover field names for a new expression, use arkime_field_search; to add one of your own use arkime_create_view (needs the arkime-view write class), and it lands in this same list. Views are per-user and per-role, so this show…
cluster_healthCluster healthread-onlyReport OpenSearch cluster health: green/yellow/red status plus node and shard counts. This checks the storage backend (OpenSearch) itself, cluster-wide. To check whether the Malcolm API is reachable, use malcolm_ping; for the readiness of Malcolm's individual services, use malcolm_service_status; for per-index status rather than the whole cluster, use list_indices. Returns the raw OpenSearch _cluster/health document. This is a storage-layer answer only: every shard allocated says nothing about whether packets are still being captured or parsed. A healthy single-node Malcolm settles at green …
countCount matching documentsread-onlyCount documents matching a DSL query clause, without returning the documents. Use this instead of search_dsl when you only need the number of matches, not the documents themselves. Note the query_dsl shape differs from search_dsl's — the schema says how. Returns the raw OpenSearch _count response ({"count": N, ...}), with an "INCOMPLETE:" line above it when some shards failed or the count timed out. This tool takes no time arguments and applies no default window, so a bare call counts everything the index still holds, which on any real capture is millions of documents. Bound it with a range …
index_mappingGet index field mappingread-onlyReturn one index's field mapping: every field name and its OpenSearch type. Use this to learn what fields an index holds and how they are typed before writing a DSL query against it. To list which indices exist rather than inspect one index's schema, use list_indices. For Malcolm's non-standard field names across all indices, malcolm_field_search is easier than reading raw mappings. Returns the raw OpenSearch _mapping response; a non-existent index is reported as an error carrying OpenSearch's index_not_found_exception. A wildcard returns one mapping block per matching index rather than a me…
list_indicesList indicesread-onlyList indices with their health, status, and document count. Use this to discover which indices exist before querying one. For the field schema (field names and types) of a single index, use index_mapping instead; for cluster-wide health rather than per-index status, use cluster_health. Returns a JSON array, one object per index, with name, health, status, and doc count. This reads OpenSearch's index list directly, so Malcolm's own internals come back beside the traffic, and most of what is listed holds no network data at all (.kibana_1, .opendistro_security, the arkime_*_v* config indices, t…
malcolm_aggregateAggregate traffic by fieldread-onlyAggregate network traffic into top-N value buckets for one or more fields. Use this to count distinct values (top talkers, protocol distribution) rather than fetch documents — for the documents themselves use malcolm_search. For distinct values of a single field with less setup, malcolm_field_values is simpler. Returns the raw Malcolm /mapi/agg response (bucket keys with doc counts); when no buckets came back and an aggregated or filtered field is not one Malcolm indexes, the correct field name is reported above the response. With no time_from this covers only the LAST 24 HOURS, unlike malco…
malcolm_alerting_alertsList alerts raised by alerting monitorsread-onlyRead what OpenSearch alerting monitors have actually fired, in any state. Use this for "what fired overnight". malcolm_alerting_monitors lists the standing rules and counts only ACTIVE alerts, so a monitor that fired and then recovered — state COMPLETED — is invisible there, as are the per-monitor, per-severity and free-text filters. That tool answers "what is being watched", this one answers "what happened". These are OpenSearch alerting alerts, a different mechanism from Suricata's IDS alerts: for those use malcolm_alerts. To read the rule behind an alert, take its monitor id to malcolm_ale…
malcolm_alerting_monitor_detailRead one alerting monitor's query and triggersread-onlyRead one alerting monitor in full: the query it runs and the conditions that fire it. Use this to decide whether a monitor's SILENCE means anything. malcolm_alerting_monitors says a monitor exists and whether it is enabled, but cannot show the query or the trigger condition, so it cannot separate a monitor that watches the right traffic from one whose condition no traffic can satisfy — Malcolm's shipped loopback monitor fires on `ctx.results[0].hits.total.value > 999999999`. Take the id from malcolm_alerting_monitors; for the alerts a monitor has raised use malcolm_alerting_alerts with monito…
malcolm_alerting_monitorsList alerting monitorsread-onlyList OpenSearch alerting monitors, what each watches, and whether any have fired. Use this to find the standing detections someone already configured, and to check they are actually running — a disabled monitor is silent in exactly the way a healthy one is. It stops at what each monitor is and whether it is enabled: the query and trigger condition behind one need malcolm_alerting_monitor_detail, and what has actually fired needs malcolm_alerting_alerts. These are OpenSearch alerting rules, which are a different thing from Suricata's IDS alerts: for those use malcolm_alerts. To record a new fi…
malcolm_alertsSearch Suricata alertsread-onlySearch Suricata alerts with structured parameters, no field knowledge needed. Use this instead of malcolm_search when hunting Suricata alerts: it maps each argument to the correct Malcolm field for you (you don't need to know whether it's suricata.alert.signature or rule.name). It always filters event.dataset=alert. These are Suricata IDS alerts, signature matches on the wire; three other things on this server are also called alerts and are different mechanisms — malcolm_alerting_monitors and malcolm_alerting_alerts are the OpenSearch alerting plugin's standing rules and their firings, malcol…
malcolm_anomaly_detectorsList anomaly detectorsread-onlyList OpenSearch anomaly detectors, what each models, and whether any anomalies exist. Use this to see what machine-learning baselines Malcolm is maintaining over the traffic and whether they have produced anything. It counts anomalies across every detector at once; for which entities one named detector scored, and when, take its `id` to malcolm_anomaly_results. This reads the detector configuration, not the traffic: for the underlying documents use malcolm_search, and for Suricata's signature-based alerts use malcolm_alerts, which is a different detection method entirely. Returns JSON {"tota…
malcolm_anomaly_resultsRead one anomaly detector's top anomaliesread-onlyRead which entities one anomaly detector scored as anomalous in a window, worst first. Use this after malcolm_anomaly_detectors, which reports a single anomaly count across every detector and admits it cannot tell "the detector ran and found nothing" from "the detector was never started". This asks one named detector for its own results and reports its run state beside them, which settles that question and names WHICH entity was anomalous and WHEN. For signature-based detection use malcolm_alerts (Suricata) or malcolm_alerting_alerts (standing OpenSearch rules); this is the machine-learning b…
malcolm_create_alertCreate Malcolm alertCreate a Malcolm alert document from an analyst/agent finding (POST /mapi/event). Use this to record a hunting conclusion as an alert that shows up in Malcolm's dashboards alongside Suricata alerts. This is the only write tool that mints a Malcolm-native event; to persist a reusable search instead use arkime_create_view, or to tag sessions use arkime_add_tags. Additive — indexes a new document and changes nothing that already exists (calling twice creates two alerts). The action is audited, and the tool is registered only when the alerting write class is enabled. Read it back with malcolm_sea…
malcolm_dashboard_exportExport OpenSearch dashboardread-onlyExport one OpenSearch Dashboards dashboard as its full saved-object JSON. Use this after malcolm_saved_objects — the only tool here that lists the ids this takes — to read how a shipped dashboard is built. It resolves ids as DASHBOARDS ONLY: given a visualization, saved-search or index-pattern id it answers with a normal body carrying an embedded 404 at objects[0].error.statusCode instead of failing, so read the body rather than treating a returned object as success. For those three types use malcolm_saved_object_detail, which resolves them and hands back the query already parsed; for network…
malcolm_data_coverageData coverage and freshnessread-onlySummarize what data exists: feeding sensors, freshness, and per-dataset volume. Use this before a hunt to see which sensors are live, how stale the newest data is (latest_age_seconds), document counts per event.dataset (conn, dns, ssl, alert, ...), and index count. For overall service/stack health rather than data volume, use malcolm_service_status. For distinct values of one arbitrary field rather than the dataset breakdown, use malcolm_field_values. Returns a JSON summary; each sub-section reports its own error key on failure instead of aborting, unless every one of them fails, which raises…
malcolm_extract_fileFetch a Zeek-extracted fileread-onlyFetch one Zeek-extracted file from Malcolm's extracted-files server; returns METADATA ONLY. Use this after malcolm_file_scans, which supplies the filename. Use arkime_file_by_hash instead when you hold a content hash but no Zeek file record, and arkime_session_pcap for a session's packets rather than one carved file. The bytes never enter the response and nothing is written to disk — a carved file may be live malware. The body is streamed against a 100 MB cap — under Malcolm's own 128 MB extraction ceiling (EXTRACTED_FILE_MAX_BYTES) — and a larger file is refused before it is read; url_only=…
malcolm_field_profileProfile field by datasetread-onlyShow which event.dataset types actually contain a given field, with doc counts. Use this to learn where a field lives (e.g. whether it only appears in SSL or DNS records) before scoping a query. To confirm the field NAME first, use malcolm_field_search; to list its distinct VALUES, use malcolm_field_values. Behavior: first resolves the name against the index mapping, then aggregates over event.dataset. Three distinct text outcomes — (1) unknown field → a "not found" message with close-name suggestions (no profile); (2) known field but no matching documents in the time window → an "exists but…
malcolm_field_searchSearch index fieldsread-onlyDiscover which field NAMES exist in Malcolm's index, by keyword, prefix, or type. Use this first, before any query, to confirm a field name exists — Malcolm uses non-standard names (e.g. http.useragent, NOT http.user_agent). To then see the VALUES a field holds, use malcolm_field_values; to see which datasets contain it, use malcolm_field_profile. Do NOT source an arkime_* argument from here: these are the names malcolm_* and search_dsl take, and Arkime has its own spelling for the same field (ip.src, srcIp) that arkime_field_search reports. Pass at least one argument. Returns a text list of …
malcolm_field_valuesList field valuesread-onlyList a single field's distinct VALUES with per-value document counts. Use this to see what values a field actually holds before filtering on it, so you don't invent values. To confirm the field NAME exists first, use malcolm_field_search; to see which datasets carry the field, use malcolm_field_profile. For multi-field or nested bucketing, use malcolm_aggregate. A "-" in the output is Malcolm's placeholder for documents where the field is absent, not a value you can filter on. Returns a text list of "value (N docs)" lines. With no time range this reads only the last 24 hours, so a value that…
malcolm_file_scansSearch extracted files and scan verdictsread-onlyList the files Zeek saw cross the wire, with their hashes and scan verdicts. Use this for any file-centric question — it filters event.dataset=files for you and returns one compact row per file instead of the multi-KB raw document. Use malcolm_search instead for any other record type (conn, dns, http); search_dsl for a substring or wildcard filename match, which Malcolm's exact-match filters cannot express; arkime_file_by_hash to pull bytes by a hash Arkime recorded on a session rather than by Zeek's file record. Both record types Malcolm files under this dataset are returned, so one file ca…
malcolm_netbox_lookupLook up NetBox assetread-onlyResolve an IP, device name, or prefix to its NetBox asset (role, site, tenant). Use this to tell whether observed traffic involves a known asset and where it sits — the fast path for the three common NetBox lookups. For any other NetBox endpoint (services, VLANs, interfaces, VMs, contacts) use malcolm_netbox_query; to list sites use malcolm_netbox_sites. Pass at least one of ip/device/prefix. Returns a JSON object with a summarized section per lookup you supplied; a lookup that fails carries its own error key while the others still answer, and every one failing is reported as an error rather …
malcolm_netbox_queryQuery NetBox endpointread-onlyQuery any NetBox REST endpoint via Malcolm's read-only GET proxy. Use this as the general escape hatch for NetBox endpoints the shortcuts don't cover (services, VLANs, interfaces, VMs, contacts, ...). For the common ip/device/prefix lookups prefer malcolm_netbox_lookup; to list sites use malcolm_netbox_sites — though this tool with path "dcim/sites/" is what returns a site's full record. The path is validated to a NetBox app/model shape before proxying, so a bad path fails here rather than upstream. Returns the raw NetBox JSON response for the endpoint, which for a list endpoint is paginated:…
malcolm_netbox_sitesList NetBox sitesread-onlyList the NetBox site directory: the physical or logical locations assets sit in. Use this to learn which sites exist before drilling into a specific asset. To then resolve a device, IP, or prefix use malcolm_netbox_lookup; for any other NetBox endpoint use malcolm_netbox_query. Returns Malcolm's own condensed view, not NetBox's: an object keyed by site id, each value carrying display, name and slug only. Everything else a site record holds — status, tenant, device and VM counts — needs malcolm_netbox_query with path "dcim/sites/", which returns the full records plus NetBox's count/next pagin…
malcolm_pingPing Malcolm APIread-onlyQuick liveness check that the Malcolm API answers (GET /mapi/ping). Use this as the cheapest reachability probe. For readiness of the individual services behind the API use malcolm_service_status; for the OpenSearch cluster status specifically use cluster_health. Returns the raw /mapi/ping response ({"ping": "pong"}); an unreachable API is reported as an error, not as an answer. A pass proves exactly two things: the HTTP endpoint answers, and the configured credentials authenticate — a wrong password comes back as an upstream 401, not as a pass. It proves nothing about OpenSearch, the captur…
malcolm_related_sessionsFind related sessions by UIDread-onlyCorrelate one Zeek UID across sessions via both direct and cross-reference matches. Use this to pivot from a single connection UID to everything tied to it. "direct" is every record carrying the UID in zeek.uid: the conn record and its dns, http, ssl, files and other protocol records. "related" is every record whose rootId is the UID but whose zeek.uid is not, chiefly the connections carried inside a tunnel when the UID is the tunnel's. For an ordinary connection "related" is empty, which is the normal answer. Zeek UIDs only: to pivot from an Arkime session id use arkime_session_detail, and f…
malcolm_saved_object_detailRead one saved object's query and filtersread-onlyRead one saved object with its query, filters and index pattern already resolved. Use this on a saved SEARCH to recover the query a human curated — Malcolm ships over a hundred of them, and the Arkime-side equivalent is arkime_views — and on a visualization to find the search it is built from. malcolm_saved_objects lists the catalogue and stops there; malcolm_dashboard_export resolves DASHBOARD ids only and answers 200 with an embedded 404 for a visualization or saved-search id, so for those two this is the only route. For the traffic a query matches, take the string to malcolm_search or sear…
malcolm_saved_objectsFind Dashboards saved objectsread-onlyFind the dashboards, visualizations and saved searches this Malcolm ships. Use this to discover what pre-built analysis already exists before building a query by hand — Malcolm ships over a hundred dashboards, and one of them usually already covers the protocol you are looking at. This is catalogue metadata only: for the query behind a saved search or visualization take its `id` to malcolm_saved_object_detail, and for how a DASHBOARD is built take its `id` to malcolm_dashboard_export — that endpoint resolves ids as dashboards only, and answers 200 with an embedded 404 for a visualization or s…
malcolm_searchSearch network traffic (Malcolm filters)read-onlySearch Malcolm's indexed network traffic using Malcolm's simple filter dict. Use this for field-based filtering with human-readable time ranges. To search with Arkime expression syntax instead, or when you need a session id to feed arkime_session_pcap / arkime_add_tags afterward, use arkime_sessions (only its rows carry that id). For raw OpenSearch DSL, use search_dsl. Confirm field names with malcolm_field_search first — Malcolm uses non-standard names. Returns the raw Malcolm /mapi/document response (matching documents); when nothing matched and a filter names a field Malcolm does not index…
malcolm_service_statusMalcolm service statusread-onlyReport readiness of each Malcolm service plus Malcolm version and OpenSearch health. Call this before a hunt to confirm the whole stack is up. For a bare is-the-API-alive check use malcolm_ping; for the OpenSearch cluster's green/yellow/red detail alone use cluster_health; for data freshness and per-dataset counts use malcolm_data_coverage. Returns a JSON summary with malcolm_version, mode, opensearch_health, a per-service readiness map, and an "N/total services ready" line. One probe failing adds an `errors` entry and keeps the rest; both failing is reported as an error, since there is then …
malcolm_upload_pcapUpload PCAPUpload a local capture file to Malcolm for ingestion (POST /server/php/submit.php). Use this to feed a PCAP into Malcolm so Zeek/Suricata parse it and it becomes searchable via malcolm_search / arkime_sessions. The file must already sit inside the server's staging directory (MALCOLM_MCP_UPLOAD_DIR); files outside it, and all uploads when that variable is unset, are refused — this boundary stops a prompt-injected caller from shipping arbitrary host files off-box, and there is no second tool that uploads without it, so a refusal means staging the file server-side first. Additive — ingests new d…
search_dslRun OpenSearch DSL queryread-onlyRun a raw OpenSearch DSL query and return its hits plus aggregations. Use this for full DSL control over the query and aggregation bodies. When you only need a match count and not the documents, use count. For Malcolm's simpler field-filter syntax instead of raw DSL, use malcolm_search. Aggregations honor the time filter inside the DSL body, so there is no hidden default time window. Returns the raw OpenSearch _search response. A body OpenSearch rejects comes back as an error carrying OpenSearch's own reason, e.g. a parsing_exception naming the unknown query type. A reply from only some shard…
Signals
- Stars
- 2
- Forks
- 0
- Open issues
- 0
- Weekly downloads
- 106
- Last commit
- Oct 22, 2026 (14 days ago)
- Last release
- Oct 13, 2026 (23 days ago)
- Last package publish
- Oct 13, 2026 (23 days ago)
From GitHub (fetched Oct 24, 2026) and the package registry.
Details
- Registry name
io.github.nagameTW/mcp-server-malcolm- Version
- 1.2.1
- Auth
- No auth
- Packages
- pypi mcp-server-malcolm
- License
- MIT
- Repository
- github.com/nagameTW/mcp-server-malcolm
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
More from nagameTW
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get MCP Server Malcolm running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
MCP Server Malcolm. Agent Mart. https://agentmart.dev/connectors/nagametw-mcp-server-malcolm (last updated 2026-10-24)