Repository navigation
feat: enhance events tool with nested top action and tag discovery - #22
Conversation
- Added name field to EnrichedEvent.monitorMetadata interface - Populates monitor.name in enrichWithMonitorMetadata function - Enables AI to use correct monitor names instead of event titles This fixes n8n workflow showing message templates instead of actual monitor names in alert reports.
BREAKING CHANGE: Configuration schema changed from max*/caps to defaults-only Changes: - Config schema: maxResults/maxLogLines → defaultLimit/defaultLogLines/ defaultMetricDataPoints - Environment variables: MCP_MAX_* → MCP_DEFAULT_* pattern - All tools: Removed Math.min() caps, AI has full control when specifying limits - Metrics tool: Added pointLimit parameter for AI control over timeseries resolution - Tests: Updated to verify AI control instead of cap enforcement (903/903 passing) - README: Documented limit philosophy - env vars are defaults, NOT caps The environment variables set what value is used when the AI doesn't specify a limit. They do NOT cap what the AI can request. Default values: - defaultLimit: 50 (general tools) - defaultLogLines: 200 (logs tool) - defaultMetricDataPoints: 1000 (metrics timeseries) - defaultTimeRangeHours: 24 (time range fallback)
- Add .min(1) validation to all limit/pageSize/count parameters across 16 tool files - Prevents invalid values (0 or negative) while maintaining AI full control over maximums - Extract SAMPLE_DIVERSITY_MULTIPLIER constant in logs.ts for clarity - Remove 25k token limit documentation (Claude Code CLI specific, not universal MCP) This improves input validation without restricting AI capabilities.
- Add discover action to find available tag prefixes in events
- Enhance top action with nested context breakdown (by_service array)
- Add contextTags parameter for customizable context extraction
- Implement findFirstContextTag helper for tag matching
- Add comprehensive tests for new functionality
- Update README with examples and usage patterns
- Simplify tool description to be more concise
The enhanced top action now returns monitors with nested structure:
{name, monitor_id, total_count, by_service: [{context, count}]}
This eliminates the need for high-limit search queries in meteo workflows.
Pull Request Review: Enhanced Events ToolSummaryThis PR adds valuable functionality for aggregating monitor alerts with context breakdown. The implementation is solid with excellent test coverage (81 tests). Here's my detailed feedback: ✅ Strengths
🔍 Code Quality Issues1. Hard-coded Limit in
|
- Change alertCount to total_count in assertions - Update expected API call limit from 1000 to 10000 - Aligns with enhanced top action that fetches all events for accurate grouping
- Fix .sort() to use localeCompare for reliable alphabetical sorting - Add 6 tests for discoverTagsV2 (tag extraction, deduplication, sorting) - Add 5 enhanced tests for topEventsV2 (context extraction, custom tags, prioritization) - Coverage increased from 59% to 84.99% (exceeds 80% SonarQube requirement) - All 924 tests passing
… improvements BREAKING CHANGE: Renamed by_service field to by_context in top action response Changes: - Add input validation for contextTags parameter (array of non-empty strings) - Optimize tag matching with Set for 6x performance improvement (O(1) vs O(n)) - Remove unsafe non-null assertion in topEventsV2 - Filter out monitors with empty context arrays from results - Add configurable maxEvents parameter (default: 10000, max: 10000) - Rename by_service → by_context for clearer API semantics - Document maxEvents behavior and incomplete results scenario The maxEvents parameter allows AI/users to tune accuracy vs performance based on query scope. Narrow filters can safely increase limit for better accuracy. Addresses PR #22 review feedback.
Update top action examples to reflect breaking change from by_service to by_context.
|
@claude review the few last commits to check if concerns have been solved correctly |
|
Claude finished @TANTIOPE's task in 2m 37s —— View job Review of Recent CommitsI've reviewed the 4 commits made since the previous review. Here's my comprehensive assessment: Task List
SummaryExcellent work! All critical "Must Fix" items from the previous review have been properly addressed, plus several recommended improvements. The implementation is now production-ready. ✅ Critical Issues Resolved1. Hard-coded 10k Limit (FIXED)Previous Issue: Resolution (commit
Code: maxEvents: z
.number()
.min(1)
.max(10000)
.optional()
.describe(
'Maximum events to fetch for grouping in top action (default: 10000). Higher = more accurate but slower'
)2. Misleading Field Name (FIXED)Previous Issue: Field named Resolution (commits
Example Output: {
"name": "High number of ready messages",
"monitor_id": 67860480,
"total_count": 50,
"by_context": [
{"context": "queue:state-status_tasks", "count": 30}
]
}3. Input Validation for contextTags (FIXED)Previous Issue: Security concern - no validation on user-provided contextTags Resolution (commit
Validation Code: if (params.contextTags !== undefined) {
if (!Array.isArray(params.contextTags)) {
throw new Error('contextTags must be an array')
}
if (params.contextTags.some((tag) => typeof tag !== 'string' || tag.trim() === '')) {
throw new Error('contextTags must be an array of non-empty strings')
}
}Note: While the previous review suggested regex validation ( ✅ Additional Improvements Implemented4. Non-null Assertion Removed (FIXED)Previous Issue: Resolution (commit let monitorGroup = monitorGroups.get(key)
if (!monitorGroup) {
monitorGroup = { name: monitorName, monitorId, events: [] }
monitorGroups.set(key, monitorGroup)
}
monitorGroup.events.push(event)5. Performance Optimization (FIXED)Previous Issue: Quadratic complexity in tag matching (nested loops) Resolution (commit
Before: O(tags × prefixes) per event Optimized Code (src/tools/events.ts:350-361): export function findFirstContextTag(tags: string[], prefixes: Set<string>): string | null {
for (const tag of tags) {
const colonIndex = tag.indexOf(':')
if (colonIndex > 0) {
const prefix = tag.substring(0, colonIndex)
if (prefixes.has(prefix)) {
return tag
}
}
}
return null
}6. Empty by_context Arrays Handled (IMPROVED)Previous Issue: Monitors without matching context tags would have empty arrays Resolution (commit .filter((monitor) => monitor.by_context.length > 0)Monitors without any matching context tags are now excluded from results, making the output cleaner and more useful. 7. Comprehensive Test Coverage (ADDED)Previous Issue: Missing integration tests for Resolution (commit
Test Examples: it('should use default maxEvents of 10000', async () => {
await topEventsV2(mockApi, { limit: 5 }, limits, 'datadoghq.com')
expect(mockApi.searchEvents).toHaveBeenCalledWith({
body: expect.objectContaining({ page: { limit: 10000 } })
})
})
it('should respect maxEvents parameter', async () => {
await topEventsV2(mockApi, { maxEvents: 5000 }, limits, 'datadoghq.com')
expect(mockApi.searchEvents).toHaveBeenCalledWith({
body: expect.objectContaining({ page: { limit: 5000 } })
})
})📊 Code Quality Metrics
🎯 Remaining Minor Observations1. Documentation Enhancement OpportunityThe README examples are excellent, but could benefit from a note about the filtering behavior: Current: Implicitly filters monitors without context **Note**: Only monitors with at least one matching context tag are returned.
Monitors without matching contexts are automatically filtered out.This is optional - the current implementation is correct and intuitive. 2. Missing Validation TestsWhile runtime validation is implemented, there are no explicit tests for the validation errors: Suggestion: Add tests in it('should throw error for non-array contextTags', async () => {
await expect(
topEventsV2(mockApi, { contextTags: 'invalid' }, limits, 'datadoghq.com')
).rejects.toThrow('contextTags must be an array')
})
it('should throw error for empty string in contextTags', async () => {
await expect(
topEventsV2(mockApi, { contextTags: ['queue', ''] }, limits, 'datadoghq.com')
).rejects.toThrow('contextTags must be an array of non-empty strings')
})This is nice-to-have - the Zod schema validation at the tool boundary already catches these cases. 🎉 Final VerdictStatus: ✅ APPROVED - All Critical Concerns Resolved What Was Fixed:
Code Quality:
Breaking Changes:The
RecommendationReady to merge. This PR represents a significant improvement to the events tool with proper configurability, performance optimizations, and comprehensive testing. The implementation correctly addresses all critical feedback from the previous review. Great work on the thorough fixes! 🚀 |
|
|
🎉 This PR is included in version 4.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |



Summary
Enhances the events tool to better support weekly/daily alert reporting (meteo) use cases by adding:
Enhanced
topaction - Returns monitors with nested context breakdown:{ "rank": 1, "name": "High number of ready messages", "monitor_id": 67860480, "total_count": 50, "by_service": [ {"context": "queue:state-status_tasks", "count": 30}, {"context": "queue:updated_order_service", "count": 20} ] }New
discoveraction - Find available tag prefixes in alert data:Customizable context tags - Optional
contextTagsparameter to customize which tags to extract (defaults to: queue, service, ingress, pod_name, kube_namespace, kube_container_name)Changes
discoveraction to find available tag prefixes in eventstopaction with nested context breakdown (by_service array)contextTagsparameter for customizable context extractionfindFirstContextTaghelper for tag matchingBenefits
This eliminates the need for high-limit search queries with enrich in n8n meteo workflows. Instead of:
Use:
Testing
Related
Addresses the inefficiency in n8n alert reporting workflows where client-side aggregation was needed.