chore: recovery checkpoint - v3.0 API successfully recovered

CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB

Recovery Status:
- Successfully recovered brainy.ts from compiled JavaScript
- All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.)
- Neural subsystem intact (562KB embedded patterns, NLP working)
- Augmentation pipeline operational (20+ augmentations)
- HNSW clustering system complete
- Triple Intelligence compiled (needs constructor fix)
- Test suite validates functionality

Changes preserved:
- 898 files with changes from last 3 days
- 144,475 insertions
- All augmentation improvements
- All test coverage enhancements
- Complete v3.0 feature set

This is a LOCAL checkpoint only - contains recovered work after corruption incident.
Created backup in .backups/brainy-full-20250910-151314.tar.gz

Branch: recovery-checkpoint-20250910-151433
Date: Wed Sep 10 03:18:04 PM PDT 2025
This commit is contained in:
David Snelling 2025-09-10 15:18:04 -07:00
parent f65455fb22
commit 8ff382ca3b
895 changed files with 143654 additions and 28268 deletions

View file

@ -0,0 +1,68 @@
/**
* BrainyMCPAdapter
*
* This class provides an adapter for accessing Brainy data through the Model Control Protocol (MCP).
* It wraps a Brainy instance and exposes methods for getting vectors, searching similar items,
* and getting relationships.
*/
import { BrainyInterface } from '../types/brainyDataInterface.js';
import { MCPResponse, MCPDataAccessRequest } from '../types/mcpTypes.js';
export declare class BrainyMCPAdapter {
private brainyData;
/**
* Creates a new BrainyMCPAdapter
* @param brainyData The Brainy instance to wrap
*/
constructor(brainyData: BrainyInterface);
/**
* Handles an MCP data access request
* @param request The MCP request
* @returns An MCP response
*/
handleRequest(request: MCPDataAccessRequest): Promise<MCPResponse>;
/**
* Handles a get request
* @param request The MCP request
* @returns An MCP response
*/
private handleGetRequest;
/**
* Handles a search request
* @param request The MCP request
* @returns An MCP response
*/
private handleSearchRequest;
/**
* Handles an add request
* @param request The MCP request
* @returns An MCP response
*/
private handleAddRequest;
/**
* Handles a getRelationships request
* @param request The MCP request
* @returns An MCP response
*/
private handleGetRelationshipsRequest;
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
private createSuccessResponse;
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
private createErrorResponse;
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId(): string;
}

View file

@ -0,0 +1,143 @@
/**
* BrainyMCPAdapter
*
* This class provides an adapter for accessing Brainy data through the Model Control Protocol (MCP).
* It wraps a Brainy instance and exposes methods for getting vectors, searching similar items,
* and getting relationships.
*/
import { v4 as uuidv4 } from '../universal/uuid.js';
import { MCP_VERSION } from '../types/mcpTypes.js';
export class BrainyMCPAdapter {
/**
* Creates a new BrainyMCPAdapter
* @param brainyData The Brainy instance to wrap
*/
constructor(brainyData) {
this.brainyData = brainyData;
}
/**
* Handles an MCP data access request
* @param request The MCP request
* @returns An MCP response
*/
async handleRequest(request) {
try {
switch (request.operation) {
case 'get':
return await this.handleGetRequest(request);
case 'search':
return await this.handleSearchRequest(request);
case 'add':
return await this.handleAddRequest(request);
case 'getRelationships':
return await this.handleGetRelationshipsRequest(request);
default:
return this.createErrorResponse(request.requestId, 'UNSUPPORTED_OPERATION', `Operation ${request.operation} is not supported`);
}
}
catch (error) {
return this.createErrorResponse(request.requestId, 'INTERNAL_ERROR', error instanceof Error ? error.message : String(error));
}
}
/**
* Handles a get request
* @param request The MCP request
* @returns An MCP response
*/
async handleGetRequest(request) {
const { id } = request.parameters;
if (!id) {
return this.createErrorResponse(request.requestId, 'MISSING_PARAMETER', 'Parameter "id" is required');
}
const noun = await this.brainyData.getNoun(id);
if (!noun) {
return this.createErrorResponse(request.requestId, 'NOT_FOUND', `No noun found with id ${id}`);
}
return this.createSuccessResponse(request.requestId, noun);
}
/**
* Handles a search request
* @param request The MCP request
* @returns An MCP response
*/
async handleSearchRequest(request) {
const { query, k = 10 } = request.parameters;
if (!query) {
return this.createErrorResponse(request.requestId, 'MISSING_PARAMETER', 'Parameter "query" is required');
}
const results = await this.brainyData.searchText(query, k);
return this.createSuccessResponse(request.requestId, results);
}
/**
* Handles an add request
* @param request The MCP request
* @returns An MCP response
*/
async handleAddRequest(request) {
const { text, metadata } = request.parameters;
if (!text) {
return this.createErrorResponse(request.requestId, 'MISSING_PARAMETER', 'Parameter "text" is required');
}
// Add data directly using addNoun
const id = await this.brainyData.addNoun(text, 'document', metadata);
return this.createSuccessResponse(request.requestId, { id });
}
/**
* Handles a getRelationships request
* @param request The MCP request
* @returns An MCP response
*/
async handleGetRelationshipsRequest(request) {
const { id } = request.parameters;
if (!id) {
return this.createErrorResponse(request.requestId, 'MISSING_PARAMETER', 'Parameter "id" is required');
}
// This is a simplified implementation - in a real implementation, we would
// need to check if these methods exist on the BrainyInterface
const outgoing = await this.brainyData.getVerbsBySource?.(id) || [];
const incoming = await this.brainyData.getVerbsByTarget?.(id) || [];
return this.createSuccessResponse(request.requestId, { outgoing, incoming });
}
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
createSuccessResponse(requestId, data) {
return {
success: true,
requestId,
version: MCP_VERSION,
data
};
}
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
createErrorResponse(requestId, code, message, details) {
return {
success: false,
requestId,
version: MCP_VERSION,
error: {
code,
message,
details
}
};
}
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId() {
return uuidv4();
}
}
//# sourceMappingURL=brainyMCPAdapter.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"brainyMCPAdapter.js","sourceRoot":"","sources":["../../src/mcp/brainyMCPAdapter.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,82 @@
/**
* BrainyMCPBroadcast
*
* Enhanced MCP service with real-time WebSocket broadcasting capabilities
* for multi-agent coordination (Jarvis Picasso communication)
*
* Features:
* - WebSocket server for real-time push notifications
* - Subscription management for multiple Claude instances
* - Message broadcasting to all connected agents
* - Works both locally and with cloud deployment
*/
import { BrainyMCPService } from './brainyMCPService.js';
import { BrainyDataInterface } from '../types/brainyDataInterface.js';
import { MCPServiceOptions } from '../types/mcpTypes.js';
interface BroadcastMessage {
id: string;
from: string;
to?: string | string[];
type: 'message' | 'notification' | 'sync' | 'heartbeat' | 'identify';
event?: string;
data: any;
timestamp: number;
}
export declare class BrainyMCPBroadcast extends BrainyMCPService {
private wsServer?;
private httpServer?;
private agents;
private messageHistory;
private maxHistorySize;
constructor(brainyData: BrainyDataInterface, options?: MCPServiceOptions & {
broadcastPort?: number;
cloudUrl?: string;
});
/**
* Start the WebSocket broadcast server
* @param port Port to listen on (default: 8765)
* @param isCloud Whether this is a cloud deployment
*/
startBroadcastServer(port?: number, isCloud?: boolean): Promise<void>;
/**
* Handle new WebSocket connection
*/
private handleNewConnection;
/**
* Handle message from an agent
*/
private handleAgentMessage;
/**
* Broadcast message to all connected agents
*/
broadcast(message: BroadcastMessage, excludeId?: string): void;
/**
* Send message to specific agent
*/
private sendToAgent;
/**
* Remove agent from connected list
*/
private removeAgent;
/**
* Add message to history
*/
private addToHistory;
/**
* Stop the broadcast server
*/
stopBroadcastServer(): Promise<void>;
/**
* Get connected agents
*/
getConnectedAgents(): Array<{
id: string;
name: string;
role: string;
}>;
/**
* Get message history
*/
getMessageHistory(): BroadcastMessage[];
}
export default BrainyMCPBroadcast;

View file

@ -0,0 +1,303 @@
/**
* BrainyMCPBroadcast
*
* Enhanced MCP service with real-time WebSocket broadcasting capabilities
* for multi-agent coordination (Jarvis Picasso communication)
*
* Features:
* - WebSocket server for real-time push notifications
* - Subscription management for multiple Claude instances
* - Message broadcasting to all connected agents
* - Works both locally and with cloud deployment
*/
import { WebSocketServer, WebSocket } from 'ws';
import { createServer } from 'http';
import { BrainyMCPService } from './brainyMCPService.js';
import { v4 as uuidv4 } from '../universal/uuid.js';
export class BrainyMCPBroadcast extends BrainyMCPService {
constructor(brainyData, options = {}) {
super(brainyData, options);
this.agents = new Map();
this.messageHistory = [];
this.maxHistorySize = 100;
}
/**
* Start the WebSocket broadcast server
* @param port Port to listen on (default: 8765)
* @param isCloud Whether this is a cloud deployment
*/
async startBroadcastServer(port = 8765, isCloud = false) {
return new Promise((resolve, reject) => {
try {
// Create HTTP server
this.httpServer = createServer((req, res) => {
// Health check endpoint
if (req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
status: 'healthy',
agents: Array.from(this.agents.values()).map(a => ({
id: a.id,
name: a.name,
role: a.role,
connected: true
})),
uptime: process.uptime()
}));
}
else {
res.writeHead(404);
res.end('Not found');
}
});
// Create WebSocket server
this.wsServer = new WebSocketServer({
server: this.httpServer,
perMessageDeflate: false // Better performance
});
this.wsServer.on('connection', (socket, request) => {
this.handleNewConnection(socket, request);
});
// Start listening
this.httpServer.listen(port, () => {
console.log(`🧠 Brain Jar Broadcast Server running on ${isCloud ? 'cloud' : 'local'} port ${port}`);
console.log(`📡 WebSocket: ws://localhost:${port}`);
console.log(`🔍 Health: http://localhost:${port}/health`);
resolve();
});
// Heartbeat to keep connections alive
setInterval(() => {
this.agents.forEach((agent) => {
if (Date.now() - agent.lastSeen > 30000) {
// Remove inactive agents
this.removeAgent(agent.id);
}
else {
// Send heartbeat
this.sendToAgent(agent.id, {
id: uuidv4(),
from: 'server',
type: 'heartbeat',
data: { timestamp: Date.now() },
timestamp: Date.now()
});
}
});
}, 15000);
}
catch (error) {
reject(error);
}
});
}
/**
* Handle new WebSocket connection
*/
handleNewConnection(socket, request) {
const agentId = uuidv4();
// Send welcome message
socket.send(JSON.stringify({
id: uuidv4(),
from: 'server',
type: 'notification',
event: 'welcome',
data: {
agentId,
message: 'Connected to Brain Jar Broadcast Server',
agents: Array.from(this.agents.values()).map(a => ({
id: a.id,
name: a.name,
role: a.role
}))
},
timestamp: Date.now()
}));
// Handle messages from this agent
socket.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
this.handleAgentMessage(agentId, message);
}
catch (error) {
console.error('Invalid message from agent:', error);
}
});
// Handle disconnection
socket.on('close', () => {
this.removeAgent(agentId);
});
// Handle errors
socket.on('error', (error) => {
console.error(`Agent ${agentId} error:`, error);
});
// Store temporary connection until identified
this.agents.set(agentId, {
id: agentId,
name: 'Unknown',
role: 'Unknown',
socket,
lastSeen: Date.now()
});
}
/**
* Handle message from an agent
*/
handleAgentMessage(agentId, message) {
const agent = this.agents.get(agentId);
if (!agent)
return;
// Update last seen
agent.lastSeen = Date.now();
// Handle identification
if (message.type === 'identify') {
agent.name = message.name || agent.name;
agent.role = message.role || agent.role;
// Notify all agents about new member
this.broadcast({
id: uuidv4(),
from: 'server',
type: 'notification',
event: 'agent_joined',
data: {
agent: {
id: agent.id,
name: agent.name,
role: agent.role
}
},
timestamp: Date.now()
}, agentId); // Exclude the joining agent
// Send recent history to new agent
if (this.messageHistory.length > 0) {
this.sendToAgent(agentId, {
id: uuidv4(),
from: 'server',
type: 'sync',
data: {
history: this.messageHistory.slice(-20) // Last 20 messages
},
timestamp: Date.now()
});
}
return;
}
// Create broadcast message
const broadcastMsg = {
id: message.id || uuidv4(),
from: agent.name,
to: message.to,
type: message.type || 'message',
event: message.event,
data: message.data,
timestamp: Date.now()
};
// Store in history
this.addToHistory(broadcastMsg);
// Broadcast based on recipient
if (message.to) {
// Send to specific agent(s)
const recipients = Array.isArray(message.to) ? message.to : [message.to];
recipients.forEach((recipientName) => {
const recipient = Array.from(this.agents.values()).find(a => a.name === recipientName);
if (recipient) {
this.sendToAgent(recipient.id, broadcastMsg);
}
});
}
else {
// Broadcast to all agents except sender
this.broadcast(broadcastMsg, agentId);
}
}
/**
* Broadcast message to all connected agents
*/
broadcast(message, excludeId) {
const messageStr = JSON.stringify(message);
this.agents.forEach((agent) => {
if (agent.id !== excludeId && agent.socket.readyState === WebSocket.OPEN) {
agent.socket.send(messageStr);
}
});
}
/**
* Send message to specific agent
*/
sendToAgent(agentId, message) {
const agent = this.agents.get(agentId);
if (agent && agent.socket.readyState === WebSocket.OPEN) {
agent.socket.send(JSON.stringify(message));
}
}
/**
* Remove agent from connected list
*/
removeAgent(agentId) {
const agent = this.agents.get(agentId);
if (agent) {
// Notify others about disconnection
this.broadcast({
id: uuidv4(),
from: 'server',
type: 'notification',
event: 'agent_left',
data: {
agent: {
id: agent.id,
name: agent.name,
role: agent.role
}
},
timestamp: Date.now()
});
this.agents.delete(agentId);
}
}
/**
* Add message to history
*/
addToHistory(message) {
this.messageHistory.push(message);
// Trim history if too large
if (this.messageHistory.length > this.maxHistorySize) {
this.messageHistory = this.messageHistory.slice(-this.maxHistorySize);
}
}
/**
* Stop the broadcast server
*/
async stopBroadcastServer() {
// Close all agent connections
this.agents.forEach(agent => {
agent.socket.close(1000, 'Server shutting down');
});
this.agents.clear();
// Close WebSocket server
if (this.wsServer) {
this.wsServer.close();
}
// Close HTTP server
if (this.httpServer) {
this.httpServer.close();
}
}
/**
* Get connected agents
*/
getConnectedAgents() {
return Array.from(this.agents.values()).map(a => ({
id: a.id,
name: a.name,
role: a.role
}));
}
/**
* Get message history
*/
getMessageHistory() {
return [...this.messageHistory];
}
}
// Export for both environments
export default BrainyMCPBroadcast;
//# sourceMappingURL=brainyMCPBroadcast.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,92 @@
/**
* BrainyMCPClient
*
* Client for connecting Claude instances to the Brain Jar Broadcast Server
* Utilizes Brainy for persistent memory and vector search capabilities
*/
interface ClientOptions {
name: string;
role: string;
serverUrl?: string;
autoReconnect?: boolean;
useBrainyMemory?: boolean;
}
interface Message {
id: string;
from: string;
to?: string | string[];
type: 'message' | 'notification' | 'sync' | 'heartbeat' | 'identify';
event?: string;
data: any;
timestamp: number;
}
export declare class BrainyMCPClient {
private socket?;
private options;
private brainy?;
private messageHandlers;
private reconnectTimeout?;
private isConnected;
constructor(options: ClientOptions);
/**
* Initialize Brainy for persistent memory
*/
private initBrainy;
/**
* Connect to the broadcast server
*/
connect(): Promise<void>;
/**
* Handle incoming message
*/
private handleMessage;
/**
* Send a message
*/
send(message: Partial<Message>): void;
/**
* Send a message to specific agent(s)
*/
sendTo(recipient: string | string[], data: any): void;
/**
* Broadcast to all agents
*/
broadcast(data: any): void;
/**
* Register a message handler
*/
on(type: string, handler: (message: Message) => void): void;
/**
* Remove a message handler
*/
off(type: string): void;
/**
* Search historical messages using Brainy's vector search
*/
searchMemory(query: string, limit?: number): Promise<any[]>;
/**
* Get recent messages from Brainy memory
*/
getRecentMessages(limit?: number): Promise<any[]>;
/**
* Schedule reconnection attempt
*/
private scheduleReconnect;
/**
* Disconnect from server
*/
disconnect(): void;
/**
* Check if connected
*/
getIsConnected(): boolean;
/**
* Get agent info
*/
getAgentInfo(): {
name: string;
role: string;
connected: boolean;
};
}
export default BrainyMCPClient;

View file

@ -0,0 +1,254 @@
/**
* BrainyMCPClient
*
* Client for connecting Claude instances to the Brain Jar Broadcast Server
* Utilizes Brainy for persistent memory and vector search capabilities
*/
import WebSocket from 'ws';
import { BrainyData } from '../brainyData.js';
import { v4 as uuidv4 } from '../universal/uuid.js';
export class BrainyMCPClient {
constructor(options) {
this.messageHandlers = new Map();
this.isConnected = false;
this.options = {
serverUrl: 'ws://localhost:8765',
autoReconnect: true,
useBrainyMemory: true,
...options
};
}
/**
* Initialize Brainy for persistent memory
*/
async initBrainy() {
if (this.options.useBrainyMemory && !this.brainy) {
this.brainy = new BrainyData({
storage: {
requestPersistentStorage: true
}
});
await this.brainy.init();
console.log(`🧠 Brainy memory initialized for ${this.options.name}`);
}
}
/**
* Connect to the broadcast server
*/
async connect() {
// Initialize Brainy first
await this.initBrainy();
return new Promise((resolve, reject) => {
try {
this.socket = new WebSocket(this.options.serverUrl);
this.socket.on('open', () => {
console.log(`${this.options.name} connected to Brain Jar Broadcast`);
this.isConnected = true;
// Identify ourselves
this.send({
type: 'identify',
data: {
name: this.options.name,
role: this.options.role
}
});
resolve();
});
this.socket.on('message', async (data) => {
try {
const message = JSON.parse(data.toString());
await this.handleMessage(message);
}
catch (error) {
console.error('Error parsing message:', error);
}
});
this.socket.on('close', () => {
console.log(`${this.options.name} disconnected from Brain Jar`);
this.isConnected = false;
if (this.options.autoReconnect) {
this.scheduleReconnect();
}
});
this.socket.on('error', (error) => {
console.error(`Connection error for ${this.options.name}:`, error);
reject(error);
});
}
catch (error) {
reject(error);
}
});
}
/**
* Handle incoming message
*/
async handleMessage(message) {
// Store in Brainy for persistent memory
if (this.brainy && message.type === 'message') {
try {
await this.brainy.add({
text: `${message.from}: ${JSON.stringify(message.data)}`,
metadata: {
messageId: message.id,
from: message.from,
to: message.to,
timestamp: message.timestamp,
type: message.type,
event: message.event
}
});
}
catch (error) {
console.error('Error storing message in Brainy:', error);
}
}
// Handle sync messages (receive history)
if (message.type === 'sync' && message.data.history) {
console.log(`📜 ${this.options.name} received ${message.data.history.length} historical messages`);
// Store history in Brainy
if (this.brainy) {
for (const histMsg of message.data.history) {
await this.brainy.add({
text: `${histMsg.from}: ${JSON.stringify(histMsg.data)}`,
metadata: histMsg
});
}
}
}
// Call registered handlers
const handler = this.messageHandlers.get(message.type);
if (handler) {
handler(message);
}
// Call universal handler
const universalHandler = this.messageHandlers.get('*');
if (universalHandler) {
universalHandler(message);
}
}
/**
* Send a message
*/
send(message) {
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
console.error(`${this.options.name} is not connected`);
return;
}
const fullMessage = {
id: message.id || uuidv4(),
from: this.options.name,
type: message.type || 'message',
data: message.data || {},
timestamp: Date.now(),
...message
};
this.socket.send(JSON.stringify(fullMessage));
}
/**
* Send a message to specific agent(s)
*/
sendTo(recipient, data) {
this.send({
to: recipient,
type: 'message',
data
});
}
/**
* Broadcast to all agents
*/
broadcast(data) {
this.send({
type: 'message',
data
});
}
/**
* Register a message handler
*/
on(type, handler) {
this.messageHandlers.set(type, handler);
}
/**
* Remove a message handler
*/
off(type) {
this.messageHandlers.delete(type);
}
/**
* Search historical messages using Brainy's vector search
*/
async searchMemory(query, limit = 10) {
if (!this.brainy) {
console.warn('Brainy memory not initialized');
return [];
}
const results = await this.brainy.search(query, limit);
return results.map(r => ({
...r.metadata,
relevance: r.score
}));
}
/**
* Get recent messages from Brainy memory
*/
async getRecentMessages(limit = 20) {
if (!this.brainy) {
console.warn('Brainy memory not initialized');
return [];
}
// Search for recent activity
const results = await this.brainy.search('recent messages communication', limit);
return results
.map(r => r.metadata)
.sort((a, b) => b.timestamp - a.timestamp);
}
/**
* Schedule reconnection attempt
*/
scheduleReconnect() {
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
}
this.reconnectTimeout = setTimeout(() => {
console.log(`🔄 ${this.options.name} attempting to reconnect...`);
this.connect().catch(error => {
console.error('Reconnection failed:', error);
this.scheduleReconnect();
});
}, 5000);
}
/**
* Disconnect from server
*/
disconnect() {
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
}
if (this.socket) {
this.socket.close(1000, 'Client disconnecting');
this.socket = undefined;
}
this.isConnected = false;
}
/**
* Check if connected
*/
getIsConnected() {
return this.isConnected;
}
/**
* Get agent info
*/
getAgentInfo() {
return {
name: this.options.name,
role: this.options.role,
connected: this.isConnected
};
}
}
// Export for both environments
export default BrainyMCPClient;
//# sourceMappingURL=brainyMCPClient.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,98 @@
/**
* BrainyMCPService
*
* This class provides a unified service for accessing Brainy data and augmentations
* through the Model Control Protocol (MCP). It integrates the BrainyMCPAdapter and
* MCPAugmentationToolset classes and provides WebSocket and REST server implementations
* for external model access.
*/
import { BrainyInterface } from '../types/brainyDataInterface.js';
import { MCPRequest, MCPResponse, MCPServiceOptions } from '../types/mcpTypes.js';
export declare class BrainyMCPService {
private dataAdapter;
private toolset;
private options;
private authTokens;
private rateLimits;
/**
* Creates a new BrainyMCPService
* @param brainyData The Brainy instance to wrap
* @param options Configuration options for the service
*/
constructor(brainyData: BrainyInterface, options?: MCPServiceOptions);
/**
* Handles an MCP request
* @param request The MCP request
* @returns An MCP response
*/
handleRequest(request: MCPRequest): Promise<MCPResponse>;
/**
* Handles a system info request
* @param request The MCP request
* @returns An MCP response
*/
private handleSystemInfoRequest;
/**
* Handles an authentication request
* @param request The MCP request
* @returns An MCP response
*/
private handleAuthenticationRequest;
/**
* Checks if a request is valid
* @param request The request to check
* @returns Whether the request is valid
*/
private isValidRequest;
/**
* Checks if a request is authenticated
* @param request The request to check
* @returns Whether the request is authenticated
*/
private isAuthenticated;
/**
* Checks if a token is valid
* @param token The token to check
* @returns Whether the token is valid
*/
private isValidToken;
/**
* Generates an authentication token
* @param userId The user ID to associate with the token
* @returns The generated token
*/
private generateAuthToken;
/**
* Checks if a client has exceeded the rate limit
* @param clientId The client ID to check
* @returns Whether the client is within the rate limit
*/
private checkRateLimit;
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
private createSuccessResponse;
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
private createErrorResponse;
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId(): string;
/**
* Handles an MCP request directly (for in-process models)
* @param request The MCP request
* @returns An MCP response
*/
handleMCPRequest(request: MCPRequest): Promise<MCPResponse>;
}

View file

@ -0,0 +1,248 @@
/**
* BrainyMCPService
*
* This class provides a unified service for accessing Brainy data and augmentations
* through the Model Control Protocol (MCP). It integrates the BrainyMCPAdapter and
* MCPAugmentationToolset classes and provides WebSocket and REST server implementations
* for external model access.
*/
import { v4 as uuidv4 } from '../universal/uuid.js';
import { MCPRequestType, MCP_VERSION } from '../types/mcpTypes.js';
import { BrainyMCPAdapter } from './brainyMCPAdapter.js';
import { MCPAugmentationToolset } from './mcpAugmentationToolset.js';
import { isBrowser, isNode } from '../utils/environment.js';
export class BrainyMCPService {
/**
* Creates a new BrainyMCPService
* @param brainyData The Brainy instance to wrap
* @param options Configuration options for the service
*/
constructor(brainyData, options = {}) {
this.dataAdapter = new BrainyMCPAdapter(brainyData);
this.toolset = new MCPAugmentationToolset();
this.options = options;
this.authTokens = new Map();
this.rateLimits = new Map();
}
/**
* Handles an MCP request
* @param request The MCP request
* @returns An MCP response
*/
async handleRequest(request) {
try {
switch (request.type) {
case MCPRequestType.DATA_ACCESS:
return await this.dataAdapter.handleRequest(request);
case MCPRequestType.TOOL_EXECUTION:
return await this.toolset.handleRequest(request);
case MCPRequestType.SYSTEM_INFO:
return await this.handleSystemInfoRequest(request);
case MCPRequestType.AUTHENTICATION:
return await this.handleAuthenticationRequest(request);
default:
return this.createErrorResponse(request.requestId, 'UNSUPPORTED_REQUEST_TYPE', `Request type ${request.type} is not supported`);
}
}
catch (error) {
return this.createErrorResponse(request.requestId, 'INTERNAL_ERROR', error instanceof Error ? error.message : String(error));
}
}
/**
* Handles a system info request
* @param request The MCP request
* @returns An MCP response
*/
async handleSystemInfoRequest(request) {
try {
switch (request.infoType) {
case 'status':
return this.createSuccessResponse(request.requestId, {
status: 'active',
version: MCP_VERSION,
environment: isBrowser() ? 'browser' : isNode() ? 'node' : 'unknown'
});
case 'availableTools':
const tools = await this.toolset.getAvailableTools();
return this.createSuccessResponse(request.requestId, tools);
case 'version':
return this.createSuccessResponse(request.requestId, {
version: MCP_VERSION
});
default:
return this.createErrorResponse(request.requestId, 'UNSUPPORTED_INFO_TYPE', `Info type ${request.infoType} is not supported`);
}
}
catch (error) {
return this.createErrorResponse(request.requestId, 'INTERNAL_ERROR', error instanceof Error ? error.message : String(error));
}
}
/**
* Handles an authentication request
* @param request The MCP request
* @returns An MCP response
*/
async handleAuthenticationRequest(request) {
try {
if (!this.options.enableAuth) {
return this.createSuccessResponse(request.requestId, {
authenticated: true,
message: 'Authentication is not enabled'
});
}
const { credentials } = request;
// Check API key authentication
if (credentials.apiKey &&
this.options.apiKeys?.includes(credentials.apiKey)) {
const token = this.generateAuthToken('api-user');
return this.createSuccessResponse(request.requestId, {
authenticated: true,
token
});
}
// Check username/password authentication
// This is a placeholder - in a real implementation, you would check against a database
if (credentials.username === 'admin' &&
credentials.password === 'password') {
const token = this.generateAuthToken(credentials.username);
return this.createSuccessResponse(request.requestId, {
authenticated: true,
token
});
}
return this.createErrorResponse(request.requestId, 'INVALID_CREDENTIALS', 'Invalid credentials');
}
catch (error) {
return this.createErrorResponse(request.requestId, 'INTERNAL_ERROR', error instanceof Error ? error.message : String(error));
}
}
/**
* Checks if a request is valid
* @param request The request to check
* @returns Whether the request is valid
*/
isValidRequest(request) {
return (request &&
typeof request === 'object' &&
request.type &&
request.requestId &&
request.version);
}
/**
* Checks if a request is authenticated
* @param request The request to check
* @returns Whether the request is authenticated
*/
isAuthenticated(request) {
if (!this.options.enableAuth) {
return true;
}
return request.authToken ? this.isValidToken(request.authToken) : false;
}
/**
* Checks if a token is valid
* @param token The token to check
* @returns Whether the token is valid
*/
isValidToken(token) {
const tokenInfo = this.authTokens.get(token);
if (!tokenInfo) {
return false;
}
if (tokenInfo.expires < Date.now()) {
this.authTokens.delete(token);
return false;
}
return true;
}
/**
* Generates an authentication token
* @param userId The user ID to associate with the token
* @returns The generated token
*/
generateAuthToken(userId) {
const token = uuidv4();
const expires = Date.now() + 24 * 60 * 60 * 1000; // 24 hours
this.authTokens.set(token, { userId, expires });
return token;
}
/**
* Checks if a client has exceeded the rate limit
* @param clientId The client ID to check
* @returns Whether the client is within the rate limit
*/
checkRateLimit(clientId) {
if (!this.options.rateLimit) {
return true;
}
const now = Date.now();
const limit = this.rateLimits.get(clientId);
if (!limit) {
this.rateLimits.set(clientId, {
count: 1,
resetTime: now + this.options.rateLimit.windowMs
});
return true;
}
if (limit.resetTime < now) {
limit.count = 1;
limit.resetTime = now + this.options.rateLimit.windowMs;
return true;
}
if (limit.count >= this.options.rateLimit.maxRequests) {
return false;
}
limit.count++;
return true;
}
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
createSuccessResponse(requestId, data) {
return {
success: true,
requestId,
version: MCP_VERSION,
data
};
}
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
createErrorResponse(requestId, code, message, details) {
return {
success: false,
requestId,
version: MCP_VERSION,
error: {
code,
message,
details
}
};
}
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId() {
return uuidv4();
}
/**
* Handles an MCP request directly (for in-process models)
* @param request The MCP request
* @returns An MCP response
*/
async handleMCPRequest(request) {
return await this.handleRequest(request);
}
}
//# sourceMappingURL=brainyMCPService.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
/**
* Model Control Protocol (MCP) for Brainy
*
* This module provides a Model Control Protocol (MCP) implementation for Brainy,
* allowing external models to access Brainy data and use the augmentation pipeline as tools.
*/
import { BrainyMCPAdapter } from './brainyMCPAdapter.js';
import { MCPAugmentationToolset } from './mcpAugmentationToolset.js';
import { BrainyMCPService } from './brainyMCPService.js';
export { BrainyMCPAdapter };
export { MCPAugmentationToolset };
export { BrainyMCPService };
export * from '../types/mcpTypes.js';

View file

@ -0,0 +1,17 @@
/**
* Model Control Protocol (MCP) for Brainy
*
* This module provides a Model Control Protocol (MCP) implementation for Brainy,
* allowing external models to access Brainy data and use the augmentation pipeline as tools.
*/
// Import and re-export the MCP components
import { BrainyMCPAdapter } from './brainyMCPAdapter.js';
import { MCPAugmentationToolset } from './mcpAugmentationToolset.js';
import { BrainyMCPService } from './brainyMCPService.js';
// Export the MCP components
export { BrainyMCPAdapter };
export { MCPAugmentationToolset };
export { BrainyMCPService };
// Export the MCP types
export * from '../types/mcpTypes.js';
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0CAA0C;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAC3B,OAAO,EAAE,sBAAsB,EAAE,CAAA;AACjC,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAE3B,uBAAuB;AACvB,cAAc,sBAAsB,CAAA"}

View file

@ -0,0 +1,67 @@
/**
* MCPAugmentationToolset
*
* This class exposes the Brainy augmentation pipeline as tools through the Model Control Protocol (MCP).
* It provides methods for getting available tools and executing tools.
*/
import { MCPResponse, MCPToolExecutionRequest, MCPTool } from '../types/mcpTypes.js';
export declare class MCPAugmentationToolset {
/**
* Creates a new MCPAugmentationToolset
*/
constructor();
/**
* Handles an MCP tool execution request
* @param request The MCP request
* @returns An MCP response
*/
handleRequest(request: MCPToolExecutionRequest): Promise<MCPResponse>;
/**
* Gets all available tools
* @returns An array of MCP tools
*/
getAvailableTools(): Promise<MCPTool[]>;
/**
* Creates a tool definition
* @param type The augmentation type
* @param augmentationName The augmentation name
* @param method The method name
* @returns An MCP tool definition
*/
private createToolDefinition;
/**
* Executes the appropriate pipeline based on the augmentation type
* @param type The augmentation type
* @param method The method to execute
* @param parameters The parameters for the method
* @returns The result of the pipeline execution
*/
private executePipeline;
/**
* Checks if an augmentation type is valid
* @param type The augmentation type to check
* @returns Whether the augmentation type is valid
*/
private isValidAugmentationType;
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
private createSuccessResponse;
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
private createErrorResponse;
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId(): string;
}

View file

@ -0,0 +1,164 @@
/**
* MCPAugmentationToolset
*
* This class exposes the Brainy augmentation pipeline as tools through the Model Control Protocol (MCP).
* It provides methods for getting available tools and executing tools.
*/
import { v4 as uuidv4 } from '../universal/uuid.js';
import { MCP_VERSION } from '../types/mcpTypes.js';
import { AugmentationType } from '../types/augmentations.js';
export class MCPAugmentationToolset {
/**
* Creates a new MCPAugmentationToolset
*/
constructor() {
// No initialization needed
}
/**
* Handles an MCP tool execution request
* @param request The MCP request
* @returns An MCP response
*/
async handleRequest(request) {
try {
const { toolName, parameters } = request;
// Extract the augmentation type and method from the tool name
// Tool names are in the format: brainy_{augmentationType}_{method}
const parts = toolName.split('_');
if (parts.length < 3 || parts[0] !== 'brainy') {
return this.createErrorResponse(request.requestId, 'INVALID_TOOL', `Invalid tool name: ${toolName}. Tool names should be in the format: brainy_{augmentationType}_{method}`);
}
const augmentationType = parts[1];
const method = parts.slice(2).join('_');
// Validate the augmentation type
if (!this.isValidAugmentationType(augmentationType)) {
return this.createErrorResponse(request.requestId, 'INVALID_AUGMENTATION_TYPE', `Invalid augmentation type: ${augmentationType}`);
}
// Execute the appropriate pipeline based on the augmentation type
const result = await this.executePipeline(augmentationType, method, parameters);
return this.createSuccessResponse(request.requestId, result);
}
catch (error) {
return this.createErrorResponse(request.requestId, 'INTERNAL_ERROR', error instanceof Error ? error.message : String(error));
}
}
/**
* Gets all available tools
* @returns An array of MCP tools
*/
async getAvailableTools() {
const tools = [];
// Get all available augmentations from the new API
// Note: We need access to the brain instance to get augmentations
// For now, return empty array to remove deprecation warning
// This MCP toolset would need brain instance access for full functionality
const augmentations = [];
for (const augmentation of augmentations) {
// Get all methods of this augmentation (excluding private methods and base methods)
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(augmentation))
.filter(method => !method.startsWith('_') &&
method !== 'constructor' &&
method !== 'initialize' &&
method !== 'shutDown' &&
method !== 'getStatus' &&
typeof augmentation[method] === 'function');
// Create a tool for each method
for (const method of methods) {
tools.push(this.createToolDefinition('augmentation', augmentation.name, method));
}
}
return tools;
}
/**
* Creates a tool definition
* @param type The augmentation type
* @param augmentationName The augmentation name
* @param method The method name
* @returns An MCP tool definition
*/
createToolDefinition(type, augmentationName, method) {
return {
name: `brainy_${type}_${method}`,
description: `Access to Brainy's ${type} augmentation '${augmentationName}' method '${method}'`,
parameters: {
type: 'object',
properties: {
args: {
type: 'array',
description: `Arguments for the ${method} method`
},
options: {
type: 'object',
description: 'Optional execution options'
}
},
required: ['args']
}
};
}
/**
* Executes the appropriate pipeline based on the augmentation type
* @param type The augmentation type
* @param method The method to execute
* @param parameters The parameters for the method
* @returns The result of the pipeline execution
*/
async executePipeline(type, method, parameters) {
// In Brainy 2.0, we directly call methods on augmentation instances
// instead of using the old typed pipeline system
const { args = [], options = {} } = parameters;
// Note: This MCP toolset needs to be updated to use the new brain.augmentations API
// For now, return a placeholder response to fix compilation
throw new Error(`MCP toolset requires update to use brain.augmentations API. Method '${method}' not available.`);
}
/**
* Checks if an augmentation type is valid
* @param type The augmentation type to check
* @returns Whether the augmentation type is valid
*/
isValidAugmentationType(type) {
return Object.values(AugmentationType).includes(type);
}
/**
* Creates a success response
* @param requestId The request ID
* @param data The response data
* @returns An MCP response
*/
createSuccessResponse(requestId, data) {
return {
success: true,
requestId,
version: MCP_VERSION,
data
};
}
/**
* Creates an error response
* @param requestId The request ID
* @param code The error code
* @param message The error message
* @param details Optional error details
* @returns An MCP response
*/
createErrorResponse(requestId, code, message, details) {
return {
success: false,
requestId,
version: MCP_VERSION,
error: {
code,
message,
details
}
};
}
/**
* Creates a new request ID
* @returns A new UUID
*/
generateRequestId() {
return uuidv4();
}
}
//# sourceMappingURL=mcpAugmentationToolset.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"mcpAugmentationToolset.js","sourceRoot":"","sources":["../../src/mcp/mcpAugmentationToolset.ts"],"names":[],"mappings":"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"}