strategic-intelligence-mcp
Version:
Strategic Intelligence MCP Server - connecting technical progress to business outcomes with systematic strategic planning
327 lines • 12.8 kB
JavaScript
// Strategic collaboration features for team-based planning
import { v4 as uuidv4 } from 'uuid';
export class StrategicCollaboration {
sessions = new Map();
templates = new Map();
constructor() {
this.initializeTemplates();
}
initializeTemplates() {
// Strategic Planning Session Template
this.templates.set('strategic-planning', {
id: 'strategic-planning',
name: 'Strategic Planning Session',
type: 'planning',
suggestedDuration: 120, // minutes
agendaTemplate: [
{
title: 'Current State Review',
description: 'Review current goals, milestones, and progress',
timeAllocation: 20,
priority: 'must-discuss'
},
{
title: 'Market & Competitive Analysis',
description: 'Discuss market trends and competitive positioning',
timeAllocation: 30,
priority: 'must-discuss'
},
{
title: 'Strategic Opportunities',
description: 'Identify and prioritize strategic opportunities',
timeAllocation: 40,
priority: 'must-discuss'
},
{
title: 'Resource Allocation',
description: 'Discuss resource needs and allocation',
timeAllocation: 20,
priority: 'should-discuss'
},
{
title: 'Next Steps & Action Items',
description: 'Define concrete next steps and assignments',
timeAllocation: 10,
priority: 'must-discuss'
}
],
requiredRoles: ['strategist', 'technical-lead', 'product-owner'],
recommendedPrep: [
'Review recent milestone completions',
'Analyze competitive intelligence',
'Prepare market trend data',
'List strategic questions'
]
});
// Decision Making Session Template
this.templates.set('decision-making', {
id: 'decision-making',
name: 'Strategic Decision Session',
type: 'decision-making',
suggestedDuration: 90,
agendaTemplate: [
{
title: 'Decision Context',
description: 'Present the decision to be made and its context',
timeAllocation: 15,
priority: 'must-discuss'
},
{
title: 'Options Analysis',
description: 'Review and analyze available options',
timeAllocation: 30,
priority: 'must-discuss'
},
{
title: 'Risk Assessment',
description: 'Evaluate risks for each option',
timeAllocation: 20,
priority: 'must-discuss'
},
{
title: 'Decision & Rationale',
description: 'Make decision and document rationale',
timeAllocation: 20,
priority: 'must-discuss'
},
{
title: 'Implementation Planning',
description: 'Define implementation approach',
timeAllocation: 5,
priority: 'should-discuss'
}
],
requiredRoles: ['strategist', 'technical-lead'],
recommendedPrep: [
'Prepare decision options matrix',
'Gather supporting data',
'Identify key stakeholders',
'Prepare risk analysis'
]
});
}
createSession(params) {
const template = params.templateId ? this.templates.get(params.templateId) : null;
const session = {
id: uuidv4(),
title: params.title,
description: params.description,
type: params.type,
status: params.scheduled ? 'scheduled' : 'active',
created: new Date().toISOString(),
scheduled: params.scheduled,
participants: params.participants.map(p => ({
...p,
contributions: 0,
attendance: params.scheduled ? 'confirmed' : 'attended'
})),
moderator: params.moderator,
agenda: template ? this.createAgendaFromTemplate(template.agendaTemplate) : [],
sharedContext: {
businessGoals: params.sharedContext?.businessGoals || [],
milestones: params.sharedContext?.milestones || [],
recentInsights: params.sharedContext?.recentInsights || [],
competitiveIntel: params.sharedContext?.competitiveIntel,
marketTrends: params.sharedContext?.marketTrends || [],
constraints: params.sharedContext?.constraints || [],
assumptions: params.sharedContext?.assumptions || []
},
contributions: [],
decisions: [],
actionItems: []
};
this.sessions.set(session.id, session);
return session;
}
createAgendaFromTemplate(template) {
return template.map(item => ({
id: uuidv4(),
status: 'pending',
...item
}));
}
addContribution(sessionId, participantId, contribution) {
const session = this.sessions.get(sessionId);
if (!session || session.status !== 'active')
return null;
const newContribution = {
id: uuidv4(),
participantId,
timestamp: new Date().toISOString(),
...contribution
};
session.contributions.push(newContribution);
// Update participant contribution count
const participant = session.participants.find(p => p.id === participantId);
if (participant) {
participant.contributions++;
participant.lastActive = newContribution.timestamp;
}
// Handle high-importance contributions
if (contribution.metadata?.importance === 'critical') {
this.flagCriticalContribution(session, newContribution);
}
return newContribution;
}
flagCriticalContribution(session, contribution) {
// In a real implementation, this might trigger notifications
// For now, we'll just ensure it's tracked
if (contribution.metadata) {
contribution.metadata.requiresFollowUp = true;
}
}
recordDecision(sessionId, decision) {
const session = this.sessions.get(sessionId);
if (!session || session.status !== 'active')
return null;
const newDecision = {
id: uuidv4(),
timestamp: new Date().toISOString(),
...decision
};
session.decisions.push(newDecision);
// Auto-create action items for decision implementation
if (decision.implementation) {
this.createActionItem(sessionId, {
title: `Implement: ${decision.decision}`,
description: `Implementation of decision: ${decision.rationale}`,
owner: decision.implementation.owner,
assignedBy: session.moderator,
dueDate: decision.implementation.deadline,
priority: 'high',
relatedDecisions: [newDecision.id]
});
}
return newDecision;
}
createActionItem(sessionId, actionItem) {
const session = this.sessions.get(sessionId);
if (!session)
return null;
const newActionItem = {
id: uuidv4(),
assignedAt: new Date().toISOString(),
status: 'assigned',
...actionItem
};
session.actionItems.push(newActionItem);
return newActionItem;
}
updateActionItem(sessionId, actionItemId, update) {
const session = this.sessions.get(sessionId);
if (!session)
return false;
const actionItem = session.actionItems.find(ai => ai.id === actionItemId);
if (!actionItem)
return false;
if (!actionItem.updates) {
actionItem.updates = [];
}
actionItem.updates.push({
timestamp: new Date().toISOString(),
...update
});
if (update.newStatus) {
actionItem.status = update.newStatus;
}
return true;
}
completeSession(sessionId, summary) {
const session = this.sessions.get(sessionId);
if (!session || session.status !== 'active')
return null;
session.status = 'completed';
session.ended = new Date().toISOString();
session.followUp = summary.followUp;
// Mark all pending agenda items as deferred
session.agenda.forEach(item => {
if (item.status === 'pending') {
item.status = 'deferred';
}
});
return session;
}
getSession(sessionId) {
return this.sessions.get(sessionId) || null;
}
getSessions(filter) {
let sessions = Array.from(this.sessions.values());
if (filter) {
if (filter.type) {
sessions = sessions.filter(s => s.type === filter.type);
}
if (filter.status) {
sessions = sessions.filter(s => s.status === filter.status);
}
if (filter.participantId) {
sessions = sessions.filter(s => s.participants.some(p => p.id === filter.participantId));
}
}
return sessions.sort((a, b) => new Date(b.created).getTime() - new Date(a.created).getTime());
}
generateSessionSummary(sessionId) {
const session = this.sessions.get(sessionId);
if (!session)
return null;
const summary = {
sessionId,
title: session.title,
type: session.type,
duration: this.calculateDuration(session),
participation: {
total: session.participants.length,
attended: session.participants.filter(p => p.attendance === 'attended').length,
contributions: session.contributions.length,
avgContributionsPerPerson: session.contributions.length /
Math.max(1, session.participants.filter(p => p.attendance === 'attended').length)
},
outcomes: {
decisions: session.decisions.length,
actionItems: session.actionItems.length,
criticalInsights: session.contributions.filter(c => c.metadata?.importance === 'critical').length
},
keyContributions: this.extractKeyContributions(session),
decisionsTimeline: this.createDecisionsTimeline(session),
nextSteps: this.extractNextSteps(session)
};
return summary;
}
calculateDuration(session) {
if (!session.started || !session.ended)
return 0;
return (new Date(session.ended).getTime() - new Date(session.started).getTime()) / 60000; // minutes
}
extractKeyContributions(session) {
return session.contributions
.filter(c => c.metadata?.importance === 'high' || c.metadata?.importance === 'critical')
.map(c => ({
content: c.content,
contributor: session.participants.find(p => p.id === c.participantId)?.name,
type: c.type,
importance: c.metadata?.importance
}));
}
createDecisionsTimeline(session) {
return session.decisions.map(d => ({
decision: d.decision,
timestamp: d.timestamp,
implementation: d.implementation
}));
}
extractNextSteps(session) {
return session.actionItems
.filter(ai => ai.status !== 'cancelled')
.sort((a, b) => new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime())
.map(ai => ({
action: ai.title,
owner: ai.owner,
dueDate: ai.dueDate,
priority: ai.priority,
status: ai.status
}));
}
getTemplates() {
return Array.from(this.templates.values());
}
}
//# sourceMappingURL=strategicCollaboration.js.map