Initial commit: Brainy - Multi-Dimensional AI Database
Open source vector database with HNSW indexing, graph relationships, and metadata facets. Features CLI with professional augmentation registry integration for discovering extensions and capabilities.
This commit is contained in:
commit
f8c45f2d8d
448 changed files with 103294 additions and 0 deletions
68
dist/mcp/brainyMCPAdapter.d.ts
vendored
Normal file
68
dist/mcp/brainyMCPAdapter.d.ts
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* BrainyMCPAdapter
|
||||
*
|
||||
* This class provides an adapter for accessing Brainy data through the Model Control Protocol (MCP).
|
||||
* It wraps a BrainyData instance and exposes methods for getting vectors, searching similar items,
|
||||
* and getting relationships.
|
||||
*/
|
||||
import { BrainyDataInterface } from '../types/brainyDataInterface.js';
|
||||
import { MCPResponse, MCPDataAccessRequest } from '../types/mcpTypes.js';
|
||||
export declare class BrainyMCPAdapter {
|
||||
private brainyData;
|
||||
/**
|
||||
* Creates a new BrainyMCPAdapter
|
||||
* @param brainyData The BrainyData instance to wrap
|
||||
*/
|
||||
constructor(brainyData: BrainyDataInterface);
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
142
dist/mcp/brainyMCPAdapter.js
vendored
Normal file
142
dist/mcp/brainyMCPAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* BrainyMCPAdapter
|
||||
*
|
||||
* This class provides an adapter for accessing Brainy data through the Model Control Protocol (MCP).
|
||||
* It wraps a BrainyData 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 BrainyData 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.get(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');
|
||||
}
|
||||
const id = await this.brainyData.add(text, 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 BrainyDataInterface
|
||||
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
|
||||
1
dist/mcp/brainyMCPAdapter.js.map
vendored
Normal file
1
dist/mcp/brainyMCPAdapter.js.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"brainyMCPAdapter.js","sourceRoot":"","sources":["../../src/mcp/brainyMCPAdapter.ts"],"names":[],"mappings":"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"}
|
||||
82
dist/mcp/brainyMCPBroadcast.d.ts
vendored
Normal file
82
dist/mcp/brainyMCPBroadcast.d.ts
vendored
Normal 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;
|
||||
303
dist/mcp/brainyMCPBroadcast.js
vendored
Normal file
303
dist/mcp/brainyMCPBroadcast.js
vendored
Normal 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
|
||||
1
dist/mcp/brainyMCPBroadcast.js.map
vendored
Normal file
1
dist/mcp/brainyMCPBroadcast.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
92
dist/mcp/brainyMCPClient.d.ts
vendored
Normal file
92
dist/mcp/brainyMCPClient.d.ts
vendored
Normal 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;
|
||||
254
dist/mcp/brainyMCPClient.js
vendored
Normal file
254
dist/mcp/brainyMCPClient.js
vendored
Normal 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
|
||||
1
dist/mcp/brainyMCPClient.js.map
vendored
Normal file
1
dist/mcp/brainyMCPClient.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
98
dist/mcp/brainyMCPService.d.ts
vendored
Normal file
98
dist/mcp/brainyMCPService.d.ts
vendored
Normal 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 { BrainyDataInterface } 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 BrainyData instance to wrap
|
||||
* @param options Configuration options for the service
|
||||
*/
|
||||
constructor(brainyData: BrainyDataInterface, 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>;
|
||||
}
|
||||
248
dist/mcp/brainyMCPService.js
vendored
Normal file
248
dist/mcp/brainyMCPService.js
vendored
Normal 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 BrainyData 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
|
||||
1
dist/mcp/brainyMCPService.js.map
vendored
Normal file
1
dist/mcp/brainyMCPService.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
13
dist/mcp/index.d.ts
vendored
Normal file
13
dist/mcp/index.d.ts
vendored
Normal 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';
|
||||
17
dist/mcp/index.js
vendored
Normal file
17
dist/mcp/index.js
vendored
Normal 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
|
||||
1
dist/mcp/index.js.map
vendored
Normal file
1
dist/mcp/index.js.map
vendored
Normal 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"}
|
||||
67
dist/mcp/mcpAugmentationToolset.d.ts
vendored
Normal file
67
dist/mcp/mcpAugmentationToolset.d.ts
vendored
Normal 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;
|
||||
}
|
||||
180
dist/mcp/mcpAugmentationToolset.js
vendored
Normal file
180
dist/mcp/mcpAugmentationToolset.js
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* 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';
|
||||
// Import the augmentation pipeline
|
||||
import { augmentationPipeline } from '../augmentationPipeline.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 augmentation types
|
||||
const augmentationTypes = augmentationPipeline.getAvailableAugmentationTypes();
|
||||
for (const type of augmentationTypes) {
|
||||
// Get all augmentations of this type
|
||||
const augmentations = augmentationPipeline.getAugmentationsByType(type);
|
||||
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(type, 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) {
|
||||
const { args = [], options = {} } = parameters;
|
||||
switch (type) {
|
||||
case AugmentationType.SENSE:
|
||||
return await augmentationPipeline.executeSensePipeline(method, args, options);
|
||||
case AugmentationType.CONDUIT:
|
||||
return await augmentationPipeline.executeConduitPipeline(method, args, options);
|
||||
case AugmentationType.COGNITION:
|
||||
return await augmentationPipeline.executeCognitionPipeline(method, args, options);
|
||||
case AugmentationType.MEMORY:
|
||||
return await augmentationPipeline.executeMemoryPipeline(method, args, options);
|
||||
case AugmentationType.PERCEPTION:
|
||||
return await augmentationPipeline.executePerceptionPipeline(method, args, options);
|
||||
case AugmentationType.DIALOG:
|
||||
return await augmentationPipeline.executeDialogPipeline(method, args, options);
|
||||
case AugmentationType.ACTIVATION:
|
||||
return await augmentationPipeline.executeActivationPipeline(method, args, options);
|
||||
default:
|
||||
throw new Error(`Unsupported augmentation type: ${type}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
1
dist/mcp/mcpAugmentationToolset.js.map
vendored
Normal file
1
dist/mcp/mcpAugmentationToolset.js.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"mcpAugmentationToolset.js","sourceRoot":"","sources":["../../src/mcp/mcpAugmentationToolset.ts"],"names":[],"mappings":"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"}
|
||||
Loading…
Add table
Add a link
Reference in a new issue