Files
ruvnet--RuView/vendor/midstream/npm/src/mcp-server.ts
T
ruv e91bb8a1d5 feat: vendor midstream and sublinear-time-solver libraries
Add ruvnet/midstream (AIMDS real-time inference) and
ruvnet/sublinear-time-solver (sublinear optimization algorithms)
as vendored dependencies under vendor/.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-02 23:32:45 -05:00

411 lines
9.9 KiB
JavaScript

#!/usr/bin/env node
/**
* MidStream MCP (Model Context Protocol) Server
*
* Provides MCP interface for the Lean Agentic Learning System
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
Tool,
} from '@modelcontextprotocol/sdk/types.js';
import { MidStreamAgent } from './agent.js';
import { WebSocketStreamServer, SSEStreamServer } from './streaming.js';
interface MCPConfig {
port?: number;
wsPort?: number;
ssePort?: number;
maxHistory?: number;
}
class MidStreamMCPServer {
private server: Server;
private agent: MidStreamAgent;
private wsServer?: WebSocketStreamServer;
private sseServer?: SSEStreamServer;
private config: MCPConfig;
constructor(config: MCPConfig = {}) {
this.config = {
port: config.port || 3000,
wsPort: config.wsPort || 3001,
ssePort: config.ssePort || 3002,
maxHistory: config.maxHistory || 1000,
};
this.server = new Server(
{
name: 'midstream-server',
version: '0.1.0',
},
{
capabilities: {
tools: {},
},
}
);
this.agent = new MidStreamAgent({
maxHistory: this.config.maxHistory,
});
this.setupHandlers();
}
private setupHandlers(): void {
// List available tools
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: this.getTools(),
};
});
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'analyze_conversation':
return await this.analyzeConversation(args);
case 'compare_sequences':
return await this.compareSequences(args);
case 'detect_patterns':
return await this.detectPatterns(args);
case 'analyze_behavior':
return await this.analyzeBehavior(args);
case 'meta_learn':
return await this.metaLearn(args);
case 'get_status':
return await this.getStatus();
case 'stream_websocket':
return await this.setupWebSocket(args);
case 'stream_sse':
return await this.setupSSE(args);
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text' as const,
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
});
}
private getTools(): Tool[] {
return [
{
name: 'analyze_conversation',
description: 'Analyze a conversation thread using temporal analysis and meta-learning',
inputSchema: {
type: 'object' as const,
properties: {
messages: {
type: 'array',
items: { type: 'string' },
description: 'Array of conversation messages',
},
},
required: ['messages'],
},
},
{
name: 'compare_sequences',
description: 'Compare two sequences using DTW, LCS, or edit distance',
inputSchema: {
type: 'object' as const,
properties: {
sequence1: {
type: 'array',
items: { type: 'string' },
description: 'First sequence',
},
sequence2: {
type: 'array',
items: { type: 'string' },
description: 'Second sequence',
},
algorithm: {
type: 'string',
enum: ['dtw', 'lcs', 'edit', 'correlation'],
description: 'Comparison algorithm',
},
},
required: ['sequence1', 'sequence2', 'algorithm'],
},
},
{
name: 'detect_patterns',
description: 'Detect pattern occurrences in a sequence',
inputSchema: {
type: 'object' as const,
properties: {
sequence: {
type: 'array',
items: { type: 'string' },
description: 'Sequence to search',
},
pattern: {
type: 'array',
items: { type: 'string' },
description: 'Pattern to find',
},
},
required: ['sequence', 'pattern'],
},
},
{
name: 'analyze_behavior',
description: 'Analyze agent behavior for chaos/stability using attractor analysis',
inputSchema: {
type: 'object' as const,
properties: {
rewards: {
type: 'array',
items: { type: 'number' },
description: 'Reward history',
},
},
required: ['rewards'],
},
},
{
name: 'meta_learn',
description: 'Perform meta-learning on a learning event',
inputSchema: {
type: 'object' as const,
properties: {
content: {
type: 'string',
description: 'Learning content',
},
reward: {
type: 'number',
description: 'Reward value',
},
},
required: ['content', 'reward'],
},
},
{
name: 'get_status',
description: 'Get current agent status and configuration',
inputSchema: {
type: 'object' as const,
properties: {},
},
},
{
name: 'stream_websocket',
description: 'Start WebSocket streaming server',
inputSchema: {
type: 'object' as const,
properties: {
port: {
type: 'number',
description: 'WebSocket port',
},
},
},
},
{
name: 'stream_sse',
description: 'Start SSE streaming server',
inputSchema: {
type: 'object' as const,
properties: {
port: {
type: 'number',
description: 'SSE port',
},
},
},
},
];
}
private async analyzeConversation(args: any) {
const { messages } = args;
const result = this.agent.analyzeConversation(messages);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(result, null, 2),
},
],
};
}
private async compareSequences(args: any) {
const { sequence1, sequence2, algorithm } = args;
const similarity = this.agent.compareSequences(sequence1, sequence2, algorithm);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify({
algorithm,
similarity,
interpretation: similarity > 0.8 ? 'Very similar' :
similarity > 0.6 ? 'Moderately similar' :
similarity > 0.4 ? 'Somewhat similar' : 'Different',
}, null, 2),
},
],
};
}
private async detectPatterns(args: any) {
const { sequence, pattern } = args;
const positions = this.agent.detectPattern(sequence, pattern);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify({
pattern_found: positions.length > 0,
occurrences: positions.length,
positions,
}, null, 2),
},
],
};
}
private async analyzeBehavior(args: any) {
const { rewards } = args;
const analysis = this.agent.analyzeBehavior(rewards);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(analysis, null, 2),
},
],
};
}
private async metaLearn(args: any) {
const { content, reward } = args;
this.agent.learn(content, reward);
const summary = this.agent.getMetaLearningSummary();
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(summary, null, 2),
},
],
};
}
private async getStatus() {
const status = this.agent.getStatus();
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(status, null, 2),
},
],
};
}
private async setupWebSocket(args: any) {
const port = args?.port || this.config.wsPort;
if (!this.wsServer) {
this.wsServer = new WebSocketStreamServer(port);
await this.wsServer.start();
}
return {
content: [
{
type: 'text' as const,
text: `WebSocket server started on port ${port}`,
},
],
};
}
private async setupSSE(args: any) {
const port = args?.port || this.config.ssePort;
if (!this.sseServer) {
this.sseServer = new SSEStreamServer(port);
await this.sseServer.start();
}
return {
content: [
{
type: 'text' as const,
text: `SSE server started on port ${port}`,
},
],
};
}
async start(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('MidStream MCP Server started');
console.error('Available tools:');
this.getTools().forEach(tool => {
console.error(` - ${tool.name}: ${tool.description}`);
});
}
async stop(): Promise<void> {
if (this.wsServer) {
await this.wsServer.stop();
}
if (this.sseServer) {
await this.sseServer.stop();
}
await this.server.close();
}
}
// Start server if run directly
if (require.main === module) {
const server = new MidStreamMCPServer();
process.on('SIGINT', async () => {
await server.stop();
process.exit(0);
});
server.start().catch(console.error);
}
export { MidStreamMCPServer };