IncidentIQ MCP Implementation Guide¶
Based on Community Insights & Best Practices
🚀 Quick Wins - Implement These First¶
1. View-Based Filtering (Highest Impact)¶
// Instead of complex filter arrays, use pre-configured views
const payload = {
Filters: [{
Facet: "View",
Id: "your-view-guid-here"
}],
Paging: {
PageSize: 1000 // Use large page sizes
}
};
Why this matters: - Views encapsulate complex business logic configured in the UI - Reduces API complexity dramatically - Maintains consistency with what users see in IncidentIQ - Leverages district-specific configurations
How to get View IDs: 1. Log into IncidentIQ 2. Navigate to the view you want to use 3. Check the URL or use browser developer tools 4. The GUID in the URL is your View ID
2. Optimal Pagination Strategy¶
// Community-proven page sizes
const PAGE_SIZES = {
DEFAULT: 100, // For normal operations (not 20!)
BULK: 1000, // For exports and analytics
MAX: 99999, // To avoid pagination entirely
};
Impact: - 80% reduction in API calls - 50% faster bulk operations - Significantly reduces rate limiting issues
3. Rate Limiting Pattern¶
// Always implement 10-second delays
async function apiRequestWithDelay(config: any) {
const response = await client.request(config);
await new Promise(resolve => setTimeout(resolve, 10000));
return response;
}
📊 Analytics Dashboard Architecture¶
Community-Proven 15-Minute Update Pattern¶
graph LR
A[IncidentIQ API] -->|Every 15 min| B[Google Apps Script]
B --> C[Google Sheets]
C --> D[Looker Studio]
B --> E[Cache Layer]
Implementation Steps¶
Step 1: Create Google Apps Script¶
function updateDashboardData() {
// Fetch from IncidentIQ API
const tickets = fetchTicketsFromAPI();
// Process and transform data
const metrics = calculateKPIs(tickets);
// Store in Google Sheets
updateGoogleSheet(metrics);
}
// Set trigger for every 15 minutes
function setupTrigger() {
ScriptApp.newTrigger('updateDashboardData')
.timeBased()
.everyMinutes(15)
.create();
}
Step 2: Use Incremental Updates¶
// Only fetch changed data
const modifiedSince = getLastUpdateTimestamp();
const updates = await fetchTickets({
modifiedSince: modifiedSince,
pageSize: 1000
});
Step 3: Calculate KPIs¶
const kpis = {
avgDaysToStart: calculateResponseTime(tickets),
avgDaysToResolve: calculateResolutionTime(tickets),
lowPriority: tickets.filter(t => t.Priority === 'Low').length,
mediumPriority: tickets.filter(t => t.Priority === 'Medium').length,
highPriority: tickets.filter(t => t.Priority === 'High').length,
criticalPriority: tickets.filter(t => t.Priority === 'Critical').length,
};
🔗 Webhook Integration Patterns¶
POST Webhook Template (Working)¶
{
"ticketId": "{Ticket.TicketId}",
"ticketNumber": "{Ticket.TicketNumber}",
"subject": "{Ticket.Subject}",
"status": "{Ticket.Status}",
"customField": "{Ticket.CustomField.YourFieldName}"
}
Middleware Architecture (for GET webhooks)¶
IncidentIQ → Webhook → Middleware → External System
↓
Database/Cache
↓
Analytics/Dashboard
Middleware Options: - Google Apps Script (Free, 15-min triggers) - Zapier/Make (Low-code, paid) - AWS Lambda (Scalable, serverless) - Custom API Gateway (Full control)
🎯 Implementation Priorities¶
Phase 1: Core Enhancements (Week 1)¶
- Add view-based filtering to search tools
- Increase default page sizes to 100-1000
- Implement retry logic with exponential backoff
- Add rate limiting (10-second delays)
Phase 2: Analytics Support (Week 2)¶
- Create bulk export tools
- Add incremental update support
- Implement CSV export option
- Add date range filtering
Phase 3: Integration Features (Week 3)¶
- Webhook payload generator
- Google Sheets export template
- Dashboard data formatter
- Integration examples
Phase 4: Documentation (Week 4)¶
- View configuration guide
- Webhook integration tutorial
- Analytics dashboard setup
- Best practices document
📈 Success Metrics¶
Performance Improvements¶
- API Calls: 80% reduction through larger page sizes
- Response Time: 50% faster bulk operations
- Rate Limiting: 90% fewer rate limit errors
- Data Freshness: 15-minute update cycles
Feature Adoption Targets¶
- View Filtering: 60% of searches using views
- Bulk Export: 40% reduction in manual exports
- Webhook Integration: 30% of districts using webhooks
- Dashboard Adoption: 50% using analytics dashboards
🔧 Code Examples¶
Enhanced Ticket Search¶
async function searchTicketsOptimized(viewId: string) {
const response = await client.request({
method: 'POST',
url: '/tickets',
data: {
Filters: [{
Facet: 'View',
Id: viewId
}],
Paging: {
PageSize: 1000 // Optimal size
}
}
});
// Process results
return response.Items;
}
Bulk Export for Analytics¶
async function* bulkExportTickets(modifiedSince?: Date) {
let pageIndex = 0;
let hasMore = true;
while (hasMore) {
const response = await client.request({
method: 'POST',
url: '/tickets',
data: {
Paging: {
PageIndex: pageIndex,
PageSize: 1000
}
}
});
yield response.Items;
hasMore = response.Items.length === 1000;
pageIndex++;
// Rate limiting
await sleep(10000);
}
}
Dashboard Data Collector¶
class DashboardCollector {
private lastUpdate: Date = new Date();
async collectIncrementalData() {
const tickets = await this.getModifiedTickets();
const metrics = this.calculateMetrics(tickets);
this.lastUpdate = new Date();
return metrics;
}
private async getModifiedTickets() {
const tickets = [];
for await (const batch of bulkExportTickets(this.lastUpdate)) {
tickets.push(...batch);
}
return tickets;
}
private calculateMetrics(tickets: Ticket[]) {
return {
total: tickets.length,
byStatus: this.groupByStatus(tickets),
byPriority: this.groupByPriority(tickets),
avgResponseTime: this.calculateAvgResponseTime(tickets),
slaCompliance: this.calculateSLACompliance(tickets)
};
}
}
🚨 Common Pitfalls to Avoid¶
- Using default page size (20) - Always use 100+
- Not implementing rate limiting - Will hit API limits
- Ignoring view-based filtering - Missing most powerful feature
- Expecting GET webhook responses - Not accessible in IncidentIQ
- Not using incremental updates - Wastes API calls and time
📚 Resources¶
- IncidentIQ Community Forum
- Google Apps Script Documentation
- Looker Studio Templates
- MCP TypeScript SDK
💡 Pro Tips from the Community¶
- Cache Static Data: Statuses, priorities, and categories rarely change
- Use Views for Everything: Let IncidentIQ handle complex logic
- Design for Problems: Build dashboards to solve specific issues
- Combine Data Sources: Integrate with Google Admin, SIS, MDM
- Test with Real Data: Use production GUIDs for validation
🎉 Next Steps¶
- Implement view-based filtering immediately
- Update pagination to use 100+ page sizes
- Set up a proof-of-concept dashboard
- Share your success with the community!
This guide is based on real-world implementations from K-12 districts successfully using IncidentIQ