miadi 1.0.14 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/package.json +17 -48
  2. package/.env.example +0 -28
  3. package/ARCHITECTURE.md +0 -290
  4. package/CLAUDE.md +0 -269
  5. package/GEMINI.md +0 -80
  6. package/MCP_CONNECTOR_READY.md +0 -219
  7. package/MCP_LEARNING_NOTES.md +0 -178
  8. package/MCP_REBUILD_PLAN.md +0 -159
  9. package/MCP_REMOTE_SERVER_SPEC.md +0 -373
  10. package/MIA.md +0 -344
  11. package/MIETTE.md +0 -195
  12. package/README.md +0 -264
  13. package/REMOTE_MCP_TRANSFORMATION_GUIDE.md +0 -384
  14. package/STATUS.md +0 -191
  15. package/TOOL_SELECTION_PLAN.md +0 -340
  16. package/WAKE_UP_SUMMARY.md +0 -102
  17. package/__PUBLISH.sh +0 -1
  18. package/book/_/ledgers/ledger_miadi_mcp_analysis_250730.md +0 -0
  19. package/conversations/2507301433.claude.issue.11.2025-07-30-this-mcp-is-not-working-another-instance-of-yours.txt +0 -756
  20. package/conversations/2507301601.cursor.reverse_engineer_mcp_service_for.md +0 -808
  21. package/conversations/2508050125.llmcon.claude.MIADI_TOOLS-implement-what-is-in-toolselectionplanmd.txt +0 -1235
  22. package/conversations/2508051939.llmcon.claude.issue-14.TransitionToPlanningIT.implement-what-is-in-toolselectionplanmd.txt +0 -1424
  23. package/conversations/2508082352.llmcon.claude.MCP-Remote-Take-II.txt +0 -1658
  24. package/dist/index-remote.js +0 -54736
  25. package/dist/index.js +0 -32363
  26. package/mcp.sample.json +0 -14
  27. package/openapi.yml +0 -2161
  28. package/research/MCP_Research_Perplexity_2508060045.md +0 -410
  29. package/samples/README.md +0 -2
  30. package/scripts/ngrokserve.sh +0 -6
  31. package/scripts/start-remote.sh +0 -141
  32. package/scripts/start-with-ngrok.sh +0 -140
  33. package/src/api-client.ts +0 -254
  34. package/src/index-remote.ts +0 -406
  35. package/src/index-simple.ts +0 -232
  36. package/src/index.ts +0 -510
  37. package/src/tool-registry.ts +0 -223
  38. package/src/tools/ai-tools.ts +0 -69
  39. package/src/tools/capability-tools.ts +0 -79
  40. package/src/tools/forge-tools.ts +0 -51
  41. package/src/tools/memory-tools.ts +0 -137
  42. package/src/tools/session-tools.ts +0 -135
  43. package/src/tools/workflow-tools.ts +0 -65
  44. package/src/types.ts +0 -291
  45. package/src/utils.ts +0 -279
  46. package/tests/quick-test.sh +0 -116
  47. package/tests/run-all-tests.sh +0 -167
  48. package/tests/test-agent-capabilities.sh +0 -364
  49. package/tests/test-connectivity.sh +0 -90
  50. package/tests/test-memory-operations.sh +0 -236
  51. package/tests/test-session-management.sh +0 -320
  52. package/tests/test-tool-discovery.sh +0 -151
  53. package/tsconfig.json +0 -24
@@ -1,65 +0,0 @@
1
- import { miadiApi } from '../api-client';
2
- import {
3
- AgentRegisterRequest,
4
- AgentRegisterResponse,
5
- AgentEventsResponse,
6
- WorkflowHowtoResponse
7
- } from '../types';
8
-
9
- export const workflowTools = {
10
- /**
11
- * Register an agent for GitHub event notifications
12
- */
13
- registerAgent: async (
14
- agentId: string,
15
- eventTypes: string[],
16
- callbackUrl?: string
17
- ): Promise<AgentRegisterResponse> => {
18
- try {
19
- if (!agentId || !eventTypes || eventTypes.length === 0) {
20
- throw new Error('Agent ID and event types are required');
21
- }
22
-
23
- const requestBody: AgentRegisterRequest = {
24
- agentId,
25
- eventTypes
26
- };
27
-
28
- if (callbackUrl) requestBody.callbackUrl = callbackUrl;
29
-
30
- return await miadiApi.registerAgent(requestBody);
31
- } catch (error: any) {
32
- throw new Error(`Failed to register agent: ${error.message}`);
33
- }
34
- },
35
-
36
- /**
37
- * Check for GitHub events for an agent
38
- */
39
- getAgentEvents: async (agentId: string): Promise<AgentEventsResponse> => {
40
- try {
41
- if (!agentId) {
42
- throw new Error('Agent ID is required');
43
- }
44
-
45
- return await miadiApi.getAgentEvents(agentId);
46
- } catch (error: any) {
47
- throw new Error(`Failed to get agent events: ${error.message}`);
48
- }
49
- },
50
-
51
- /**
52
- * Get workflow setup guides and HOWTO information
53
- */
54
- getWorkflowHowto: async (
55
- topic?: 'github-webhook-setup' | 'agent-registration' | 'agent-event-polling' | 'inter-agent-communication' | 'workflow-management' | 'authentication' | 'troubleshooting'
56
- ): Promise<WorkflowHowtoResponse | any> => {
57
- try {
58
- return await miadiApi.getWorkflowHowto(topic);
59
- } catch (error: any) {
60
- throw new Error(`Failed to get workflow howto: ${error.message}`);
61
- }
62
- }
63
- };
64
-
65
- export default workflowTools;
package/src/types.ts DELETED
@@ -1,291 +0,0 @@
1
- // TypeScript interfaces based on Miadi Three-Pathway Agent System OpenAPI specification
2
-
3
- export interface ErrorResponse {
4
- error: string;
5
- message: string;
6
- code?: number;
7
- }
8
-
9
- // Memory Management Types
10
- export interface GetMemoryResponse {
11
- key?: string;
12
- type?: 'string' | 'hash' | 'list' | 'set' | 'zset';
13
- value?: any;
14
- timestamp: string;
15
- keys?: string[]; // For list=true
16
- count?: number; // For list=true
17
- }
18
-
19
- export interface StoreMemoryRequest {
20
- key: string;
21
- value: string;
22
- ttl?: number;
23
- type?: 'string' | 'hash' | 'list';
24
- }
25
-
26
- export interface StoreMemoryResponse {
27
- key: string;
28
- value: string;
29
- ttl?: number;
30
- timestamp: string;
31
- message: string;
32
- }
33
-
34
- export interface ScanResponse {
35
- keys: string[];
36
- count: number;
37
- timestamp: string;
38
- }
39
-
40
- export interface GatherMemoryResponse {
41
- items: Array<{
42
- key: string;
43
- value: any;
44
- }>;
45
- count: number;
46
- timestamp: string;
47
- }
48
-
49
- // Session Management Types
50
- export interface ContextVariable {
51
- name: string;
52
- type: 'location' | 'device' | 'activity' | 'time' | 'custom';
53
- value: any;
54
- description?: string;
55
- }
56
-
57
- export interface SessionStartRequest {
58
- persona: string;
59
- mode: string;
60
- contextOverrides?: ContextVariable[];
61
- userId?: string;
62
- }
63
-
64
- export interface AgentSession {
65
- id: string;
66
- userId?: string;
67
- activePersona: string;
68
- currentMode: string;
69
- resolvedCapabilities: ResolvedCapability[];
70
- contextOverrides?: ContextVariable[];
71
- startTime: number;
72
- lastActivity: number;
73
- metadata?: any;
74
- }
75
-
76
- export interface SessionStartResponse {
77
- session: AgentSession;
78
- availableCapabilities: ResolvedCapability[];
79
- currentContext: ContextVariable[];
80
- timestamp: string;
81
- }
82
-
83
- export interface SessionCurrentResponse {
84
- session: AgentSession | null;
85
- availableCapabilities: ResolvedCapability[];
86
- currentContext: ContextVariable[];
87
- timestamp: string;
88
- }
89
-
90
- export interface SessionSwitchModeRequest {
91
- sessionId: string;
92
- newMode: string;
93
- contextOverrides?: ContextVariable[];
94
- }
95
-
96
- export interface SessionSwitchPersonaRequest {
97
- sessionId: string;
98
- newPersona: string;
99
- preserveMode?: boolean;
100
- }
101
-
102
- export interface SessionListResponse {
103
- sessions: AgentSession[];
104
- count: number;
105
- limit: number;
106
- offset: number;
107
- timestamp: string;
108
- }
109
-
110
- // Capability Types
111
- export interface Capability {
112
- id: string;
113
- description: string;
114
- category?: 'communication' | 'analysis' | 'creation' | 'navigation' | 'wellness' | 'system';
115
- permissions?: string[];
116
- }
117
-
118
- export interface ResolvedCapability extends Capability {
119
- source: 'persona' | 'mode' | 'global' | 'context';
120
- priority: number;
121
- }
122
-
123
- export interface CapabilityResolveRequest {
124
- persona: string;
125
- mode: string;
126
- context?: ContextVariable[];
127
- }
128
-
129
- export interface CapabilityResolveResponse {
130
- capabilities: ResolvedCapability[];
131
- timestamp: string;
132
- }
133
-
134
- // Agent Info Types
135
- export interface AgentInfoResponse {
136
- personas: Array<{
137
- id: string;
138
- name: string;
139
- agentId: string;
140
- description: string;
141
- capabilities: string[];
142
- defaultMode: string;
143
- }>;
144
- modes: Array<{
145
- id: string;
146
- name: string;
147
- description: string;
148
- defaultCapabilities: string[];
149
- triggers: Array<{
150
- phrase: string;
151
- confidence: number;
152
- autoSwitch: boolean;
153
- }>;
154
- }>;
155
- capabilities: Capability[];
156
- examples: Record<string, {
157
- method: string;
158
- url: string;
159
- body: any;
160
- }>;
161
- }
162
-
163
- // AI Integration Types
164
- export interface OpenAIRequest {
165
- prompt: string;
166
- modelId?: string;
167
- maxTokens?: number;
168
- temperature?: number;
169
- stream?: boolean;
170
- }
171
-
172
- export interface OpenAIResponse {
173
- id: string;
174
- model: string;
175
- choices: Array<{
176
- text: string;
177
- index: number;
178
- finish_reason: string;
179
- }>;
180
- usage: {
181
- prompt_tokens: number;
182
- completion_tokens: number;
183
- total_tokens: number;
184
- };
185
- }
186
-
187
- export interface AIRequest {
188
- prompt: string;
189
- modelId?: string;
190
- maxTokens?: number;
191
- temperature?: number;
192
- }
193
-
194
- export interface AIResponse {
195
- id: string;
196
- model: string;
197
- choices: Array<{
198
- text: string;
199
- index: number;
200
- finish_reason: string;
201
- }>;
202
- usage: {
203
- prompt_tokens: number;
204
- completion_tokens: number;
205
- total_tokens: number;
206
- };
207
- }
208
-
209
- // Workflow Types
210
- export interface AgentRegisterRequest {
211
- agentId: string;
212
- eventTypes: string[];
213
- callbackUrl?: string;
214
- }
215
-
216
- export interface AgentRegisterResponse {
217
- message: string;
218
- agentId: string;
219
- eventTypes: string[];
220
- timestamp: string;
221
- }
222
-
223
- export interface AgentEventsResponse {
224
- agentId: string;
225
- events: Array<{
226
- eventId: string;
227
- type: string;
228
- payload: any;
229
- timestamp: string;
230
- }>;
231
- count: number;
232
- timestamp: string;
233
- }
234
-
235
- export interface WorkflowHowtoResponse {
236
- topic: string;
237
- guide: {
238
- title: string;
239
- steps: string[];
240
- };
241
- timestamp: string;
242
- }
243
-
244
- // Forge State Types
245
- export interface ForgeStateRequest {
246
- state: boolean;
247
- }
248
-
249
- export interface ForgeStateResponse {
250
- isOpen: boolean;
251
- timestamp: string;
252
- }
253
-
254
- export interface ForgeStateUpdateResponse {
255
- isOpen: boolean;
256
- timestamp: string;
257
- message: string;
258
- }
259
-
260
- // Cue Detection Types
261
- export interface CueTrigger {
262
- phrase: string;
263
- confidence: number;
264
- autoSwitch: boolean;
265
- }
266
-
267
- export interface CueDetection {
268
- targetId: string;
269
- type: 'mode' | 'persona';
270
- confidence: number;
271
- autoSwitch: boolean;
272
- trigger: CueTrigger;
273
- }
274
-
275
- export interface CueDetectRequest {
276
- text: string;
277
- currentSession?: AgentSession;
278
- availableModes?: string[];
279
- availablePersonas?: string[];
280
- }
281
-
282
- export interface CueDetectResponse {
283
- detections: CueDetection[];
284
- suggestedAction?: {
285
- type: 'mode' | 'persona';
286
- targetId: string;
287
- confidence: number;
288
- autoSwitch: boolean;
289
- };
290
- timestamp: string;
291
- }
package/src/utils.ts DELETED
@@ -1,279 +0,0 @@
1
- import { ErrorResponse } from './types';
2
- import * as fs from 'fs';
3
- import * as path from 'path';
4
- import * as os from 'os';
5
-
6
- /**
7
- * Utility functions for the Miadi MCP Server
8
- */
9
-
10
- /**
11
- * Standardized error handler for MCP tools
12
- */
13
- export function handleMCPError(error: any, operation: string): never {
14
- const message = error.message || error.toString();
15
- console.error(`MCP Tool Error [${operation}]:`, message);
16
- throw new Error(`${operation} failed: ${message}`);
17
- }
18
-
19
- /**
20
- * Validate required parameters for MCP tools
21
- */
22
- export function validateRequired(params: Record<string, any>, requiredFields: string[]): void {
23
- const missing = requiredFields.filter(field => !params[field]);
24
- if (missing.length > 0) {
25
- throw new Error(`Required parameters missing: ${missing.join(', ')}`);
26
- }
27
- }
28
-
29
- /**
30
- * Sanitize input parameters to prevent injection
31
- */
32
- export function sanitizeInput(input: string): string {
33
- if (typeof input !== 'string') return input;
34
-
35
- // Basic sanitization - remove potentially dangerous characters
36
- return input
37
- .replace(/[<>]/g, '') // Remove HTML tags
38
- .replace(/['"]/g, '') // Remove quotes
39
- .trim();
40
- }
41
-
42
- /**
43
- * Format timestamp for consistent output
44
- */
45
- export function formatTimestamp(date?: Date): string {
46
- return (date || new Date()).toISOString();
47
- }
48
-
49
- /**
50
- * Check if a value is a valid UUID
51
- */
52
- export function isValidUUID(uuid: string): boolean {
53
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
54
- return uuidRegex.test(uuid);
55
- }
56
-
57
- /**
58
- * Validate session ID format
59
- */
60
- export function validateSessionId(sessionId: string): void {
61
- if (!sessionId) {
62
- throw new Error('Session ID is required');
63
- }
64
- if (!isValidUUID(sessionId)) {
65
- throw new Error('Session ID must be a valid UUID');
66
- }
67
- }
68
-
69
- /**
70
- * Enhanced environment loading that supports:
71
- * 1. MCP configuration environment variables (highest priority)
72
- * 2. Current process environment variables
73
- * 3. $HOME/.env file as fallback (lowest priority)
74
- */
75
- export function loadEnvironmentVariables(): void {
76
- // First, try to load from $HOME/.env as fallback
77
- const homeEnvPath = path.join(os.homedir(), '.env');
78
-
79
- if (fs.existsSync(homeEnvPath)) {
80
- try {
81
- const homeEnvContent = fs.readFileSync(homeEnvPath, 'utf8');
82
- const homeEnvVars = parseEnvFile(homeEnvContent);
83
-
84
- // Only set variables that don't already exist in process.env
85
- Object.entries(homeEnvVars).forEach(([key, value]) => {
86
- if (!process.env[key]) {
87
- process.env[key] = value;
88
- }
89
- });
90
-
91
- console.error(`✅ Loaded fallback environment variables from ${homeEnvPath}`);
92
- } catch (error) {
93
- console.error(`⚠️ Failed to load ${homeEnvPath}:`, error);
94
- }
95
- }
96
- }
97
-
98
- /**
99
- * Parse .env file content into key-value pairs
100
- */
101
- function parseEnvFile(content: string): Record<string, string> {
102
- const result: Record<string, string> = {};
103
-
104
- const lines = content.split('\n');
105
-
106
- for (const line of lines) {
107
- const trimmedLine = line.trim();
108
-
109
- // Skip empty lines and comments
110
- if (!trimmedLine || trimmedLine.startsWith('#')) {
111
- continue;
112
- }
113
-
114
- // Parse KEY=VALUE format
115
- const equalIndex = trimmedLine.indexOf('=');
116
- if (equalIndex === -1) {
117
- continue;
118
- }
119
-
120
- const key = trimmedLine.substring(0, equalIndex).trim();
121
- let value = trimmedLine.substring(equalIndex + 1).trim();
122
-
123
- // Remove surrounding quotes if present
124
- if ((value.startsWith('"') && value.endsWith('"')) ||
125
- (value.startsWith("'") && value.endsWith("'"))) {
126
- value = value.slice(1, -1);
127
- }
128
-
129
- if (key) {
130
- result[key] = value;
131
- }
132
- }
133
-
134
- return result;
135
- }
136
-
137
- /**
138
- * Parse environment variables with defaults
139
- * This function now relies on the enhanced environment loading
140
- */
141
- export function getEnvVar(name: string, defaultValue?: string): string {
142
- const value = process.env[name];
143
- if (!value && !defaultValue) {
144
- throw new Error(`Environment variable ${name} is required`);
145
- }
146
- return value || defaultValue!;
147
- }
148
-
149
- /**
150
- * Safe JSON parsing with error handling
151
- */
152
- export function safeJsonParse(jsonString: string): any {
153
- try {
154
- return JSON.parse(jsonString);
155
- } catch (error) {
156
- throw new Error(`Invalid JSON format: ${error}`);
157
- }
158
- }
159
-
160
- /**
161
- * Format API error response for MCP tools
162
- */
163
- export function formatApiError(error: any): ErrorResponse {
164
- return {
165
- error: error.name || 'API Error',
166
- message: error.message || 'Unknown error occurred',
167
- code: error.status || error.code || 500
168
- };
169
- }
170
-
171
- /**
172
- * Validate context variables array
173
- */
174
- export function validateContextVariables(contextOverrides?: any[]): void {
175
- if (!contextOverrides) return;
176
-
177
- if (!Array.isArray(contextOverrides)) {
178
- throw new Error('contextOverrides must be an array');
179
- }
180
-
181
- const validTypes = ['location', 'device', 'activity', 'time', 'custom'];
182
-
183
- contextOverrides.forEach((context, index) => {
184
- if (!context.name || !context.type) {
185
- throw new Error(`Context variable at index ${index} must have 'name' and 'type' properties`);
186
- }
187
-
188
- if (!validTypes.includes(context.type)) {
189
- throw new Error(`Context variable '${context.name}' has invalid type. Must be one of: ${validTypes.join(', ')}`);
190
- }
191
- });
192
- }
193
-
194
- /**
195
- * Log tool usage for debugging
196
- */
197
- export function logToolUsage(toolName: string, parameters: any): void {
198
- const logLevel = process.env.LOG_LEVEL || 'info';
199
-
200
- if (logLevel === 'debug') {
201
- console.log(`[MCP Tool] ${toolName}:`, JSON.stringify(parameters, null, 2));
202
- } else if (logLevel === 'info') {
203
- console.log(`[MCP Tool] ${toolName} called`);
204
- }
205
- }
206
-
207
- /**
208
- * Create consistent response format for MCP tools
209
- */
210
- export function createMCPResponse<T>(data: T, toolName: string): { content: Array<{ type: "text"; text: string }>; _meta?: { tool: string; timestamp: string } } {
211
- return {
212
- content: [
213
- {
214
- type: "text",
215
- text: JSON.stringify(data, null, 2)
216
- }
217
- ],
218
- _meta: {
219
- tool: toolName,
220
- timestamp: formatTimestamp()
221
- }
222
- };
223
- }
224
-
225
- /**
226
- * Parse tool selection configuration from environment variables
227
- */
228
- export function parseToolSelection(): import('./tool-registry').ToolRegistryConfig {
229
- const enabled = process.env.MIADI_TOOLS_ENABLED;
230
- const disabled = process.env.MIADI_TOOLS_DISABLED;
231
- const defaultEnabled = process.env.MIADI_TOOLS_DEFAULT_ENABLED !== 'false';
232
-
233
- const config: import('./tool-registry').ToolRegistryConfig = { defaultEnabled };
234
-
235
- if (enabled) {
236
- const items = enabled.split(',').map(s => s.trim()).filter(s => s.length > 0);
237
- const categories = items.filter(item => !item.startsWith('miadi-') && !item.startsWith('-'));
238
- const tools = items.filter(item => item.startsWith('miadi-'));
239
- const excludedTools = items.filter(item => item.startsWith('-')).map(item => item.substring(1));
240
-
241
- if (categories.length > 0) config.enabledCategories = categories;
242
- if (tools.length > 0) config.enabledTools = tools;
243
- if (excludedTools.length > 0) config.disabledTools = excludedTools;
244
- }
245
-
246
- if (disabled) {
247
- const items = disabled.split(',').map(s => s.trim()).filter(s => s.length > 0);
248
- const categories = items.filter(item => !item.startsWith('miadi-'));
249
- const tools = items.filter(item => item.startsWith('miadi-'));
250
-
251
- if (categories.length > 0) config.disabledCategories = categories;
252
- if (tools.length > 0) {
253
- config.disabledTools = [...(config.disabledTools || []), ...tools];
254
- }
255
- }
256
-
257
- return config;
258
- }
259
-
260
- /**
261
- * Rate limiting helper (simple in-memory implementation)
262
- */
263
- const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
264
-
265
- export function checkRateLimit(identifier: string, maxRequests: number = 100, windowMs: number = 60000): void {
266
- const now = Date.now();
267
- const entry = rateLimitMap.get(identifier);
268
-
269
- if (!entry || now > entry.resetTime) {
270
- rateLimitMap.set(identifier, { count: 1, resetTime: now + windowMs });
271
- return;
272
- }
273
-
274
- if (entry.count >= maxRequests) {
275
- throw new Error(`Rate limit exceeded for ${identifier}. Try again later.`);
276
- }
277
-
278
- entry.count++;
279
- }