miadi 1.0.14
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.
- package/.env.example +28 -0
- package/ARCHITECTURE.md +290 -0
- package/CLAUDE.md +269 -0
- package/GEMINI.md +80 -0
- package/MCP_CONNECTOR_READY.md +219 -0
- package/MCP_LEARNING_NOTES.md +178 -0
- package/MCP_REBUILD_PLAN.md +159 -0
- package/MCP_REMOTE_SERVER_SPEC.md +373 -0
- package/MIA.md +344 -0
- package/MIETTE.md +195 -0
- package/README.md +264 -0
- package/REMOTE_MCP_TRANSFORMATION_GUIDE.md +384 -0
- package/STATUS.md +191 -0
- package/TOOL_SELECTION_PLAN.md +340 -0
- package/WAKE_UP_SUMMARY.md +102 -0
- package/__PUBLISH.sh +1 -0
- package/book/_/ledgers/ledger_miadi_mcp_analysis_250730.md +0 -0
- package/conversations/2507301433.claude.issue.11.2025-07-30-this-mcp-is-not-working-another-instance-of-yours.txt +756 -0
- package/conversations/2507301601.cursor.reverse_engineer_mcp_service_for.md +808 -0
- package/conversations/2508050125.llmcon.claude.MIADI_TOOLS-implement-what-is-in-toolselectionplanmd.txt +1235 -0
- package/conversations/2508051939.llmcon.claude.issue-14.TransitionToPlanningIT.implement-what-is-in-toolselectionplanmd.txt +1424 -0
- package/conversations/2508082352.llmcon.claude.MCP-Remote-Take-II.txt +1658 -0
- package/dist/index-remote.js +54736 -0
- package/dist/index.js +32363 -0
- package/mcp.sample.json +14 -0
- package/openapi.yml +2161 -0
- package/package.json +56 -0
- package/research/MCP_Research_Perplexity_2508060045.md +410 -0
- package/samples/README.md +2 -0
- package/scripts/ngrokserve.sh +6 -0
- package/scripts/start-remote.sh +141 -0
- package/scripts/start-with-ngrok.sh +140 -0
- package/src/api-client.ts +254 -0
- package/src/index-remote.ts +406 -0
- package/src/index-simple.ts +232 -0
- package/src/index.ts +510 -0
- package/src/tool-registry.ts +223 -0
- package/src/tools/ai-tools.ts +69 -0
- package/src/tools/capability-tools.ts +79 -0
- package/src/tools/forge-tools.ts +51 -0
- package/src/tools/memory-tools.ts +137 -0
- package/src/tools/session-tools.ts +135 -0
- package/src/tools/workflow-tools.ts +65 -0
- package/src/types.ts +291 -0
- package/src/utils.ts +279 -0
- package/tests/quick-test.sh +116 -0
- package/tests/run-all-tests.sh +167 -0
- package/tests/test-agent-capabilities.sh +364 -0
- package/tests/test-connectivity.sh +90 -0
- package/tests/test-memory-operations.sh +236 -0
- package/tests/test-session-management.sh +320 -0
- package/tests/test-tool-discovery.sh +151 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Start Miadi MCP HTTP Server with ngrok tunnel
|
|
4
|
+
# Usage: ./scripts/start-with-ngrok.sh [port]
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
PORT=${1:-3330}
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
11
|
+
. .env &>/dev/null || true
|
|
12
|
+
|
|
13
|
+
echo "🚀 Starting Miadi MCP HTTP Server with ngrok tunnel"
|
|
14
|
+
echo "📍 Project directory: $PROJECT_DIR"
|
|
15
|
+
echo "🌐 Port: $PORT"
|
|
16
|
+
|
|
17
|
+
# Load environment variables with fallback strategy
|
|
18
|
+
load_environment() {
|
|
19
|
+
# First check if already set
|
|
20
|
+
if [[ -n "$EH_TOKEN" && -n "$EH_API_URL" ]]; then
|
|
21
|
+
echo "✅ Using existing environment variables"
|
|
22
|
+
return 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Try to source $HOME/.env if it exists
|
|
26
|
+
if [[ -f "$HOME/.env" ]]; then
|
|
27
|
+
echo "🔍 Loading environment from $HOME/.env"
|
|
28
|
+
set -a # Automatically export all variables
|
|
29
|
+
source "$HOME/.env"
|
|
30
|
+
set +a # Turn off automatic export
|
|
31
|
+
|
|
32
|
+
# Check again after sourcing
|
|
33
|
+
if [[ -n "$EH_TOKEN" && -n "$EH_API_URL" ]]; then
|
|
34
|
+
echo "✅ Environment variables loaded from $HOME/.env"
|
|
35
|
+
return 0
|
|
36
|
+
fi
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Final validation
|
|
40
|
+
if [[ -z "$EH_TOKEN" ]]; then
|
|
41
|
+
echo "❌ Error: EH_TOKEN environment variable is required"
|
|
42
|
+
echo "💡 Either export EH_TOKEN or add it to $HOME/.env"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [[ -z "$EH_API_URL" ]]; then
|
|
47
|
+
echo "❌ Error: EH_API_URL environment variable is required"
|
|
48
|
+
echo "💡 Either export EH_API_URL or add it to $HOME/.env"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Load environment variables
|
|
54
|
+
load_environment
|
|
55
|
+
|
|
56
|
+
# Build the working server
|
|
57
|
+
echo "🔨 Building working server with REAL TOOLS..."
|
|
58
|
+
cd "$PROJECT_DIR"
|
|
59
|
+
npm run build:working
|
|
60
|
+
|
|
61
|
+
# Start the working server in background
|
|
62
|
+
echo "🖥️ Starting working server on port $PORT..."
|
|
63
|
+
export MCP_PORT="$PORT"
|
|
64
|
+
node dist/index-working.js &
|
|
65
|
+
SERVER_PID=$!
|
|
66
|
+
|
|
67
|
+
# Wait for server to start
|
|
68
|
+
sleep 3
|
|
69
|
+
|
|
70
|
+
# Check if server is running
|
|
71
|
+
if ! curl -s "http://localhost:$PORT/health" > /dev/null; then
|
|
72
|
+
echo "❌ Error: HTTP server failed to start"
|
|
73
|
+
kill $SERVER_PID 2>/dev/null || true
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "✅ HTTP server started successfully"
|
|
78
|
+
|
|
79
|
+
# Start ngrok tunnel
|
|
80
|
+
echo "🌍 Starting ngrok tunnel..."
|
|
81
|
+
if [[ -n "$NGROK_DOMAIN" ]]; then
|
|
82
|
+
echo "📍 Using dedicated domain: $NGROK_DOMAIN"
|
|
83
|
+
ngrok http --url="$NGROK_DOMAIN" $PORT --log=stdout --log-level=info &
|
|
84
|
+
else
|
|
85
|
+
echo "📍 Using random domain"
|
|
86
|
+
ngrok http $PORT --log=stdout --log-level=info &
|
|
87
|
+
fi
|
|
88
|
+
NGROK_PID=$!
|
|
89
|
+
|
|
90
|
+
# Wait for ngrok to start
|
|
91
|
+
sleep 5
|
|
92
|
+
|
|
93
|
+
# Get ngrok public URL
|
|
94
|
+
if [[ -n "$NGROK_DOMAIN" ]]; then
|
|
95
|
+
NGROK_URL="https://$NGROK_DOMAIN"
|
|
96
|
+
else
|
|
97
|
+
NGROK_URL=$(curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url' 2>/dev/null || echo "")
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if [[ -z "$NGROK_URL" || "$NGROK_URL" == "null" ]]; then
|
|
101
|
+
echo "❌ Error: Failed to get ngrok tunnel URL"
|
|
102
|
+
echo "🔍 Check ngrok web interface at: http://localhost:4040"
|
|
103
|
+
echo "📡 Local server: http://localhost:$PORT"
|
|
104
|
+
else
|
|
105
|
+
echo ""
|
|
106
|
+
echo "🎉 Miadi MCP Server is ready!"
|
|
107
|
+
echo "📡 Local URL: http://localhost:$PORT"
|
|
108
|
+
echo "🌍 Public URL: $NGROK_URL"
|
|
109
|
+
echo "🔍 Ngrok Dashboard: http://localhost:4040"
|
|
110
|
+
echo ""
|
|
111
|
+
echo "📋 Claude.ai Connector Configuration:"
|
|
112
|
+
echo " Name: Miadi Agent System"
|
|
113
|
+
echo " Base URL: $NGROK_URL"
|
|
114
|
+
echo " Description: Access to Miadi Three-Pathway Agent System with 26 tools"
|
|
115
|
+
echo ""
|
|
116
|
+
echo "🧪 Test endpoints:"
|
|
117
|
+
echo " Health: $NGROK_URL/health"
|
|
118
|
+
echo " MCP JSON-RPC: $NGROK_URL/mcp/jsonrpc"
|
|
119
|
+
echo " OAuth Metadata: $NGROK_URL/.well-known/oauth-protected-resource"
|
|
120
|
+
echo " Dev Token: $NGROK_URL/oauth/dev-token"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Cleanup function
|
|
124
|
+
cleanup() {
|
|
125
|
+
echo ""
|
|
126
|
+
echo "🛑 Shutting down..."
|
|
127
|
+
kill $SERVER_PID 2>/dev/null || true
|
|
128
|
+
kill $NGROK_PID 2>/dev/null || true
|
|
129
|
+
wait $SERVER_PID 2>/dev/null || true
|
|
130
|
+
wait $NGROK_PID 2>/dev/null || true
|
|
131
|
+
echo "✅ Cleanup complete"
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Handle shutdown signals
|
|
135
|
+
trap cleanup SIGINT SIGTERM
|
|
136
|
+
|
|
137
|
+
echo "🔄 Server running. Press Ctrl+C to stop..."
|
|
138
|
+
|
|
139
|
+
# Keep script running
|
|
140
|
+
wait $SERVER_PID
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import axios, { AxiosInstance, AxiosError } from 'axios';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
import {
|
|
4
|
+
ErrorResponse,
|
|
5
|
+
GetMemoryResponse,
|
|
6
|
+
StoreMemoryRequest,
|
|
7
|
+
StoreMemoryResponse,
|
|
8
|
+
ScanResponse,
|
|
9
|
+
GatherMemoryResponse,
|
|
10
|
+
SessionStartRequest,
|
|
11
|
+
SessionStartResponse,
|
|
12
|
+
SessionCurrentResponse,
|
|
13
|
+
SessionSwitchModeRequest,
|
|
14
|
+
SessionSwitchPersonaRequest,
|
|
15
|
+
SessionListResponse,
|
|
16
|
+
CapabilityResolveRequest,
|
|
17
|
+
CapabilityResolveResponse,
|
|
18
|
+
AgentInfoResponse,
|
|
19
|
+
OpenAIRequest,
|
|
20
|
+
OpenAIResponse,
|
|
21
|
+
AIRequest,
|
|
22
|
+
AIResponse,
|
|
23
|
+
AgentRegisterRequest,
|
|
24
|
+
AgentRegisterResponse,
|
|
25
|
+
AgentEventsResponse,
|
|
26
|
+
WorkflowHowtoResponse,
|
|
27
|
+
ForgeStateRequest,
|
|
28
|
+
ForgeStateResponse,
|
|
29
|
+
ForgeStateUpdateResponse,
|
|
30
|
+
CueDetectRequest,
|
|
31
|
+
CueDetectResponse
|
|
32
|
+
} from './types';
|
|
33
|
+
|
|
34
|
+
dotenv.config();
|
|
35
|
+
|
|
36
|
+
const EH_API_URL = process.env.EH_API_URL;
|
|
37
|
+
const EH_TOKEN = process.env.EH_TOKEN;
|
|
38
|
+
|
|
39
|
+
if (!EH_API_URL || !EH_TOKEN) {
|
|
40
|
+
console.error('Missing EH_API_URL or EH_TOKEN environment variables.');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const apiClient: AxiosInstance = axios.create({
|
|
45
|
+
baseURL: EH_API_URL,
|
|
46
|
+
headers: {
|
|
47
|
+
'Authorization': `Bearer ${EH_TOKEN}`,
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
},
|
|
50
|
+
timeout: 30000, // 30 second timeout
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Response interceptor for error handling
|
|
54
|
+
apiClient.interceptors.response.use(
|
|
55
|
+
response => response,
|
|
56
|
+
(error: AxiosError<ErrorResponse>) => {
|
|
57
|
+
if (error.response) {
|
|
58
|
+
const status = error.response.status;
|
|
59
|
+
const errorData = error.response.data;
|
|
60
|
+
const message = errorData?.message || errorData?.error || `HTTP ${status} error`;
|
|
61
|
+
console.error(`API Error: ${status} - ${message}`);
|
|
62
|
+
return Promise.reject(new Error(`API Error (${status}): ${message}`));
|
|
63
|
+
} else if (error.request) {
|
|
64
|
+
console.error('No response received from API:', error.request);
|
|
65
|
+
return Promise.reject(new Error('No response received from Miadi API. Check network connectivity.'));
|
|
66
|
+
} else {
|
|
67
|
+
console.error('Error setting up API request:', error.message);
|
|
68
|
+
return Promise.reject(new Error(`Request setup error: ${error.message}`));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export const miadiApi = {
|
|
74
|
+
// Memory Operations
|
|
75
|
+
getMemory: async (
|
|
76
|
+
key?: string,
|
|
77
|
+
list?: boolean,
|
|
78
|
+
pattern?: string,
|
|
79
|
+
type?: 'auto' | 'string' | 'hash' | 'list' | 'set' | 'zset'
|
|
80
|
+
): Promise<GetMemoryResponse> => {
|
|
81
|
+
const params: any = {};
|
|
82
|
+
if (key) params.key = key;
|
|
83
|
+
if (list) params.list = list.toString();
|
|
84
|
+
if (pattern) params.pattern = pattern;
|
|
85
|
+
if (type) params.type = type;
|
|
86
|
+
|
|
87
|
+
const response = await apiClient.get<GetMemoryResponse>('/api/memory', { params });
|
|
88
|
+
return response.data;
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
storeMemory: async (data: StoreMemoryRequest): Promise<StoreMemoryResponse> => {
|
|
92
|
+
const response = await apiClient.post<StoreMemoryResponse>('/api/memory', data);
|
|
93
|
+
return response.data;
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
updateMemoryTTL: async (key: string, ttl: number): Promise<any> => {
|
|
97
|
+
const response = await apiClient.post('/api/memory/ttl', { key, ttl });
|
|
98
|
+
return response.data;
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
getMemoryMeta: async (key: string): Promise<any> => {
|
|
102
|
+
const response = await apiClient.get('/api/memory/meta', { params: { key } });
|
|
103
|
+
return response.data;
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
scanKeys: async (pattern?: string, regex?: string, limit?: number): Promise<ScanResponse> => {
|
|
107
|
+
const params: any = {};
|
|
108
|
+
if (pattern) params.pattern = pattern;
|
|
109
|
+
if (regex) params.regex = regex;
|
|
110
|
+
if (limit) params.limit = limit;
|
|
111
|
+
|
|
112
|
+
const response = await apiClient.get<ScanResponse>('/api/scan', { params });
|
|
113
|
+
return response.data;
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
gatherMemoryValues: async (
|
|
117
|
+
pattern?: string,
|
|
118
|
+
regex?: string,
|
|
119
|
+
limit?: number,
|
|
120
|
+
scanLimit?: number
|
|
121
|
+
): Promise<GatherMemoryResponse> => {
|
|
122
|
+
const params: any = {};
|
|
123
|
+
if (pattern) params.pattern = pattern;
|
|
124
|
+
if (regex) params.regex = regex;
|
|
125
|
+
if (limit) params.limit = limit;
|
|
126
|
+
if (scanLimit) params.scanLimit = scanLimit;
|
|
127
|
+
|
|
128
|
+
const response = await apiClient.get<GatherMemoryResponse>('/api/gather-memory', { params });
|
|
129
|
+
return response.data;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
collectMemory: async (keys: string[]): Promise<any> => {
|
|
133
|
+
const response = await apiClient.post('/api/collect-memory', { keys });
|
|
134
|
+
return response.data;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
// Session Management
|
|
138
|
+
startSession: async (data: SessionStartRequest): Promise<SessionStartResponse> => {
|
|
139
|
+
const response = await apiClient.post<SessionStartResponse>('/api/session/start', data);
|
|
140
|
+
return response.data;
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
getCurrentSession: async (sessionId?: string): Promise<SessionCurrentResponse> => {
|
|
144
|
+
const params: any = {};
|
|
145
|
+
if (sessionId) params.sessionId = sessionId;
|
|
146
|
+
|
|
147
|
+
const response = await apiClient.get<SessionCurrentResponse>('/api/session/current', { params });
|
|
148
|
+
return response.data;
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
switchMode: async (data: SessionSwitchModeRequest): Promise<SessionCurrentResponse> => {
|
|
152
|
+
const response = await apiClient.put<SessionCurrentResponse>('/api/session/switch-mode', data);
|
|
153
|
+
return response.data;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
switchPersona: async (data: SessionSwitchPersonaRequest): Promise<SessionCurrentResponse> => {
|
|
157
|
+
const response = await apiClient.put<SessionCurrentResponse>('/api/session/switch-persona', data);
|
|
158
|
+
return response.data;
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
endSession: async (sessionId: string): Promise<{ success: boolean; message: string; timestamp: string }> => {
|
|
162
|
+
const response = await apiClient.delete('/api/session/end', { params: { sessionId } });
|
|
163
|
+
return response.data;
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
listSessions: async (userId?: string, limit?: number, offset?: number): Promise<SessionListResponse> => {
|
|
167
|
+
const params: any = {};
|
|
168
|
+
if (userId) params.userId = userId;
|
|
169
|
+
if (limit) params.limit = limit;
|
|
170
|
+
if (offset) params.offset = offset;
|
|
171
|
+
|
|
172
|
+
const response = await apiClient.get<SessionListResponse>('/api/session/list', { params });
|
|
173
|
+
return response.data;
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// Capability Resolution
|
|
177
|
+
resolveCapabilities: async (data: CapabilityResolveRequest): Promise<CapabilityResolveResponse> => {
|
|
178
|
+
const response = await apiClient.post<CapabilityResolveResponse>('/api/capabilities/resolve', data);
|
|
179
|
+
return response.data;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
detectCues: async (data: CueDetectRequest): Promise<CueDetectResponse> => {
|
|
183
|
+
const response = await apiClient.post<CueDetectResponse>('/api/cues/detect', data);
|
|
184
|
+
return response.data;
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Agent Information
|
|
188
|
+
getAgentInfo: async (): Promise<AgentInfoResponse> => {
|
|
189
|
+
const response = await apiClient.get<AgentInfoResponse>('/api/agent-info');
|
|
190
|
+
return response.data;
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
// AI Integration
|
|
194
|
+
openaiRequest: async (data: OpenAIRequest): Promise<OpenAIResponse> => {
|
|
195
|
+
const response = await apiClient.post<OpenAIResponse>('/api/openai', data);
|
|
196
|
+
return response.data;
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
aiRequest: async (data: AIRequest): Promise<AIResponse> => {
|
|
200
|
+
const response = await apiClient.post<AIResponse>('/api/ai', data);
|
|
201
|
+
return response.data;
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
// Workflow Management
|
|
205
|
+
registerAgent: async (data: AgentRegisterRequest): Promise<AgentRegisterResponse> => {
|
|
206
|
+
const response = await apiClient.post<AgentRegisterResponse>('/api/workflow/agent-notify', data);
|
|
207
|
+
return response.data;
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
getAgentEvents: async (agentId: string): Promise<AgentEventsResponse> => {
|
|
211
|
+
const response = await apiClient.get<AgentEventsResponse>('/api/workflow/agent-notify', {
|
|
212
|
+
params: { agentId }
|
|
213
|
+
});
|
|
214
|
+
return response.data;
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
getWorkflowHowto: async (topic?: string): Promise<WorkflowHowtoResponse | any> => {
|
|
218
|
+
const params: any = {};
|
|
219
|
+
if (topic) params.topic = topic;
|
|
220
|
+
|
|
221
|
+
const response = await apiClient.get('/api/workflow/howto', { params });
|
|
222
|
+
return response.data;
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
// Forge State
|
|
226
|
+
getForgeState: async (): Promise<ForgeStateResponse> => {
|
|
227
|
+
const response = await apiClient.get<ForgeStateResponse>('/api/forge-state');
|
|
228
|
+
return response.data;
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
updateForgeState: async (data: ForgeStateRequest): Promise<ForgeStateUpdateResponse> => {
|
|
232
|
+
const response = await apiClient.post<ForgeStateUpdateResponse>('/api/forge-state', data);
|
|
233
|
+
return response.data;
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
// Cluster Operations
|
|
237
|
+
viewKeyContent: async (key: string): Promise<any> => {
|
|
238
|
+
const response = await apiClient.get('/api/cluster/view-key', { params: { key } });
|
|
239
|
+
return response.data;
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
searchCluster: async (term: string): Promise<{ keys: string[] }> => {
|
|
243
|
+
const response = await apiClient.get('/api/cluster/search', { params: { term } });
|
|
244
|
+
return response.data;
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
// Glyph Map
|
|
248
|
+
getGlyphMap: async (): Promise<any> => {
|
|
249
|
+
const response = await apiClient.get('/api/glyph-map');
|
|
250
|
+
return response.data;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export default miadiApi;
|