secops_mcp_lookup_entity_formatter_bug
- Dominant language
- Python
- Stars
- 528
- Forks
- 141
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 6
Description
`lookup_entity` output drops related-entity names, prevalence data, and likely timeline/alert counts
`secops_mcp` 0.1.3. `secops_mcp/tools/entity_lookup.py::lookup_entity` only emits `entity_type` for each related entity, never the canonical `Entity.name` (or asset/domain detail in `Entity.entity`). The prevalence section is a string-only tease — `"Prevalence Information Available"` — with no actual data. Timeline event/alert totals and the Associated Alerts section also come back empty for entities with confirmed recent activity, but those may be SDK-call issues rather than formatter omissions (see below).
Smoke test against `10.6.20.143` (28 detections from `Win_Repeat_Failed_Logins` in the last 7d):
```
Entity Summary for 10.6.20.143:
Primary Entity:
Entity Type: ASSET
First Seen: 2026-04-09 ...
Last Seen: 2026-05-28 ...
Related Entities (2):
1. Type: IP_ADDRESS
2. Type: ASSET <-- which assets??
Timeline Summary:
Total Events: 0 <-- 28 detections in 7d, this is wrong
Total Alerts: 0
Prevalence Information Available <-- but no data emitted
```
SDK model (`secops/chronicle/models.py`):
- `Entity` has `name: str` and `entity: dict` (asset/domain detail) — both ignored by the wrapper
- `PrevalenceData` has `prevalence_time`, `count` — ignored
- `TimelineBucket` has `event_count: int = 0`, `alert_count: int = 0` (defaulted) — wrapper sums these correctly, so the zeros likely originate from the SDK call not populating buckets
Fix for the two clear formatter omissions:
```diff
for i, entity in enumerate(related_entities[:5], 1):
entity_type = 'Unknown'
if hasattr(entity, 'metadata') and hasattr(entity.metadata, 'entity_type'):
entity_type = entity.metadata.entity_type
- result += f'{i}. Type: {entity_type}\n'
+ name = getattr(entity, 'name', 'Unknown')
+ extra = ''
+ if hasattr(entity, 'entity') and isinstance(entity.entity, dict):
+ if 'asset' in entity.entity and 'ip' in entity.entity['asset']:
+ extra = f" ip={','.join(entity.entity['asset']['ip'])}"
+ elif 'domain' in entity.entity and 'name' in entity.entity['domain']:
+ extra = f" domain={entity.entity['domain']['name']}"
+ result += f'{i}. {name} (Type: {entity_type}){extra}\n'
```
```diff
if hasattr(entity_summary, 'prevalence') and entity_summary.prevalence:
- result += 'Prevalence Information Available\n\n'
+ result += 'Prevalence:\n'
+ for p in entity_summary.prevalence[:10]:
+ result += f' - {p.prevalence_time}: count={p.count}\n'
+ result += '\n'
```
Separately worth investigating: why `chronicle.summarize_entity()` returns empty `timeline.buckets` / empty `alert_counts` for entities with known activity. May need different SDK args.
Contributor guide
Assessment
This issue has not been assessed yet.