@mirrai/mcp-server 0.1.0
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/dist/client/api-client.d.ts +26 -0
- package/dist/client/api-client.d.ts.map +1 -0
- package/dist/client/api-client.js +108 -0
- package/dist/client/api-client.js.map +1 -0
- package/dist/client/sse-client.d.ts +38 -0
- package/dist/client/sse-client.d.ts.map +1 -0
- package/dist/client/sse-client.js +126 -0
- package/dist/client/sse-client.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analytics.d.ts +9 -0
- package/dist/tools/analytics.d.ts.map +1 -0
- package/dist/tools/analytics.js +85 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/carousel.d.ts +10 -0
- package/dist/tools/carousel.d.ts.map +1 -0
- package/dist/tools/carousel.js +176 -0
- package/dist/tools/carousel.js.map +1 -0
- package/dist/tools/publishing.d.ts +9 -0
- package/dist/tools/publishing.d.ts.map +1 -0
- package/dist/tools/publishing.js +224 -0
- package/dist/tools/publishing.js.map +1 -0
- package/dist/tools/shorts.d.ts +9 -0
- package/dist/tools/shorts.d.ts.map +1 -0
- package/dist/tools/shorts.js +191 -0
- package/dist/tools/shorts.js.map +1 -0
- package/dist/types/index.d.ts +112 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirra API HTTP Client
|
|
3
|
+
*
|
|
4
|
+
* Fetch-based HTTP client with API key authentication.
|
|
5
|
+
* Handles JSON requests/responses and error mapping.
|
|
6
|
+
*/
|
|
7
|
+
import type { MirraConfig } from '../types/index.js';
|
|
8
|
+
export declare class MirraApiError extends Error {
|
|
9
|
+
statusCode: number;
|
|
10
|
+
code?: string | undefined;
|
|
11
|
+
details?: unknown | undefined;
|
|
12
|
+
constructor(statusCode: number, message: string, code?: string | undefined, details?: unknown | undefined);
|
|
13
|
+
}
|
|
14
|
+
export declare class MirraApiClient {
|
|
15
|
+
readonly baseUrl: string;
|
|
16
|
+
readonly apiKey: string;
|
|
17
|
+
constructor(config: MirraConfig);
|
|
18
|
+
private get headers();
|
|
19
|
+
private handleResponse;
|
|
20
|
+
get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
21
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
22
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
23
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
24
|
+
delete<T>(path: string): Promise<T>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/client/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,qBAAa,aAAc,SAAQ,KAAK;IAE7B,UAAU,EAAE,MAAM;IAElB,IAAI,CAAC,EAAE,MAAM;IACb,OAAO,CAAC,EAAE,OAAO;gBAHjB,UAAU,EAAE,MAAM,EACzB,OAAO,EAAE,MAAM,EACR,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,cAAc;IACzB,SAAgB,OAAO,EAAE,MAAM,CAAA;IAC/B,SAAgB,MAAM,EAAE,MAAM,CAAA;gBAElB,MAAM,EAAE,WAAW;IAS/B,OAAO,KAAK,OAAO,GAKlB;YAEa,cAAc;IA4BtB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBhG,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAUjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAUhD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAUlD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAQ1C"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirra API HTTP Client
|
|
3
|
+
*
|
|
4
|
+
* Fetch-based HTTP client with API key authentication.
|
|
5
|
+
* Handles JSON requests/responses and error mapping.
|
|
6
|
+
*/
|
|
7
|
+
export class MirraApiError extends Error {
|
|
8
|
+
statusCode;
|
|
9
|
+
code;
|
|
10
|
+
details;
|
|
11
|
+
constructor(statusCode, message, code, details) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.statusCode = statusCode;
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.details = details;
|
|
16
|
+
this.name = 'MirraApiError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class MirraApiClient {
|
|
20
|
+
baseUrl;
|
|
21
|
+
apiKey;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
const url = new URL(config.baseUrl);
|
|
24
|
+
if (!['https:', 'http:'].includes(url.protocol)) {
|
|
25
|
+
throw new Error('baseUrl must use http or https protocol');
|
|
26
|
+
}
|
|
27
|
+
this.baseUrl = url.origin;
|
|
28
|
+
this.apiKey = config.apiKey;
|
|
29
|
+
}
|
|
30
|
+
get headers() {
|
|
31
|
+
return {
|
|
32
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async handleResponse(response) {
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
let errorBody = {};
|
|
39
|
+
try {
|
|
40
|
+
errorBody = await response.json();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore parse errors
|
|
44
|
+
}
|
|
45
|
+
const message = errorBody.error || `API request failed with status ${response.status}`;
|
|
46
|
+
switch (response.status) {
|
|
47
|
+
case 401:
|
|
48
|
+
throw new MirraApiError(401, 'Invalid or expired API key', 'AUTHENTICATION_REQUIRED');
|
|
49
|
+
case 403:
|
|
50
|
+
throw new MirraApiError(403, message, errorBody.code || 'FORBIDDEN', errorBody.details);
|
|
51
|
+
case 404:
|
|
52
|
+
throw new MirraApiError(404, message, 'NOT_FOUND');
|
|
53
|
+
case 429:
|
|
54
|
+
throw new MirraApiError(429, 'Rate limit exceeded', 'RATE_LIMITED');
|
|
55
|
+
default:
|
|
56
|
+
throw new MirraApiError(response.status, message, errorBody.code, errorBody.details);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return response.json();
|
|
60
|
+
}
|
|
61
|
+
async get(path, params) {
|
|
62
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
63
|
+
if (params) {
|
|
64
|
+
for (const [key, value] of Object.entries(params)) {
|
|
65
|
+
if (value !== undefined) {
|
|
66
|
+
url.searchParams.set(key, String(value));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const response = await fetch(url.toString(), {
|
|
71
|
+
method: 'GET',
|
|
72
|
+
headers: this.headers,
|
|
73
|
+
});
|
|
74
|
+
return this.handleResponse(response);
|
|
75
|
+
}
|
|
76
|
+
async post(path, body) {
|
|
77
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: this.headers,
|
|
80
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
81
|
+
});
|
|
82
|
+
return this.handleResponse(response);
|
|
83
|
+
}
|
|
84
|
+
async put(path, body) {
|
|
85
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
86
|
+
method: 'PUT',
|
|
87
|
+
headers: this.headers,
|
|
88
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
89
|
+
});
|
|
90
|
+
return this.handleResponse(response);
|
|
91
|
+
}
|
|
92
|
+
async patch(path, body) {
|
|
93
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
94
|
+
method: 'PATCH',
|
|
95
|
+
headers: this.headers,
|
|
96
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
97
|
+
});
|
|
98
|
+
return this.handleResponse(response);
|
|
99
|
+
}
|
|
100
|
+
async delete(path) {
|
|
101
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
102
|
+
method: 'DELETE',
|
|
103
|
+
headers: this.headers,
|
|
104
|
+
});
|
|
105
|
+
return this.handleResponse(response);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/client/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE Stream Consumer
|
|
3
|
+
*
|
|
4
|
+
* Consumes Server-Sent Events from Mirra's streaming endpoints
|
|
5
|
+
* and accumulates the final result. MCP tools are request-response,
|
|
6
|
+
* so this fully consumes the stream before returning.
|
|
7
|
+
*/
|
|
8
|
+
import type { MirraConfig } from '../types/index.js';
|
|
9
|
+
interface SSEEvent {
|
|
10
|
+
event: string;
|
|
11
|
+
data: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class SSEClient {
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private apiKey;
|
|
16
|
+
constructor(config: MirraConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Consume an SSE stream from a POST endpoint.
|
|
19
|
+
* Returns accumulated events categorized by event type.
|
|
20
|
+
*/
|
|
21
|
+
consumeStream(path: string, body: unknown, options?: {
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
onEvent?: (event: SSEEvent) => void;
|
|
24
|
+
}): Promise<SSEEvent[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Consume a carousel generation stream and return the final result
|
|
27
|
+
*/
|
|
28
|
+
consumeCarouselGeneration(body: unknown): Promise<{
|
|
29
|
+
generationId: string | null;
|
|
30
|
+
pages: Array<{
|
|
31
|
+
pageNumber: number;
|
|
32
|
+
title: string;
|
|
33
|
+
html: string;
|
|
34
|
+
}>;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=sse-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-client.d.ts","sourceRoot":"","sources":["../../src/client/sse-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAQ;gBAEV,MAAM,EAAE,WAAW;IAS/B;;;OAGG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;KAC/B,GACL,OAAO,CAAC,QAAQ,EAAE,CAAC;IAyEtB;;OAEG;IACG,yBAAyB,CAC7B,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;QACT,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;QAC3B,KAAK,EAAE,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAClE,CAAC;CAmCH"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE Stream Consumer
|
|
3
|
+
*
|
|
4
|
+
* Consumes Server-Sent Events from Mirra's streaming endpoints
|
|
5
|
+
* and accumulates the final result. MCP tools are request-response,
|
|
6
|
+
* so this fully consumes the stream before returning.
|
|
7
|
+
*/
|
|
8
|
+
export class SSEClient {
|
|
9
|
+
baseUrl;
|
|
10
|
+
apiKey;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
const url = new URL(config.baseUrl);
|
|
13
|
+
if (!['https:', 'http:'].includes(url.protocol)) {
|
|
14
|
+
throw new Error('baseUrl must use http or https protocol');
|
|
15
|
+
}
|
|
16
|
+
this.baseUrl = url.origin;
|
|
17
|
+
this.apiKey = config.apiKey;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Consume an SSE stream from a POST endpoint.
|
|
21
|
+
* Returns accumulated events categorized by event type.
|
|
22
|
+
*/
|
|
23
|
+
async consumeStream(path, body, options = {}) {
|
|
24
|
+
const { timeoutMs = 120_000 } = options;
|
|
25
|
+
const controller = new AbortController();
|
|
26
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
'Accept': 'text/event-stream',
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify(body),
|
|
36
|
+
signal: controller.signal,
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
let errorMsg = `SSE request failed with status ${response.status}`;
|
|
40
|
+
try {
|
|
41
|
+
const errBody = await response.json();
|
|
42
|
+
errorMsg = errBody.error || errorMsg;
|
|
43
|
+
}
|
|
44
|
+
catch { /* ignore */ }
|
|
45
|
+
throw new Error(errorMsg);
|
|
46
|
+
}
|
|
47
|
+
if (!response.body) {
|
|
48
|
+
throw new Error('No response body for SSE stream');
|
|
49
|
+
}
|
|
50
|
+
const events = [];
|
|
51
|
+
const reader = response.body.getReader();
|
|
52
|
+
const decoder = new TextDecoder();
|
|
53
|
+
let buffer = '';
|
|
54
|
+
while (true) {
|
|
55
|
+
const { done, value } = await reader.read();
|
|
56
|
+
if (done)
|
|
57
|
+
break;
|
|
58
|
+
buffer += decoder.decode(value, { stream: true });
|
|
59
|
+
// Parse SSE events from buffer
|
|
60
|
+
const lines = buffer.split('\n');
|
|
61
|
+
buffer = lines.pop() || ''; // Keep incomplete line in buffer
|
|
62
|
+
let currentEvent = '';
|
|
63
|
+
let currentData = '';
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
if (line.startsWith('event:')) {
|
|
66
|
+
currentEvent = line.slice(6).trim();
|
|
67
|
+
}
|
|
68
|
+
else if (line.startsWith('data:')) {
|
|
69
|
+
// SSE spec: multiple data lines are concatenated with newlines
|
|
70
|
+
currentData += (currentData ? '\n' : '') + line.slice(5).trim();
|
|
71
|
+
}
|
|
72
|
+
else if (line === '' && (currentEvent || currentData)) {
|
|
73
|
+
const event = {
|
|
74
|
+
event: currentEvent || 'message',
|
|
75
|
+
data: currentData,
|
|
76
|
+
};
|
|
77
|
+
events.push(event);
|
|
78
|
+
options.onEvent?.(event);
|
|
79
|
+
currentEvent = '';
|
|
80
|
+
currentData = '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return events;
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
clearTimeout(timeout);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Consume a carousel generation stream and return the final result
|
|
92
|
+
*/
|
|
93
|
+
async consumeCarouselGeneration(body) {
|
|
94
|
+
const pages = [];
|
|
95
|
+
let generationId = null;
|
|
96
|
+
const events = await this.consumeStream('/api/v1/carousel-lab/generate-content-stream', body, { timeoutMs: 120_000 });
|
|
97
|
+
for (const event of events) {
|
|
98
|
+
try {
|
|
99
|
+
const data = JSON.parse(event.data);
|
|
100
|
+
if (event.event === 'page') {
|
|
101
|
+
const page = data.page;
|
|
102
|
+
if (page?.pageNumber != null && page?.html) {
|
|
103
|
+
pages.push({
|
|
104
|
+
pageNumber: page.pageNumber,
|
|
105
|
+
title: page.title || '',
|
|
106
|
+
html: page.html,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (event.event === 'complete') {
|
|
111
|
+
generationId = data.generationId || null;
|
|
112
|
+
}
|
|
113
|
+
else if (event.event === 'error') {
|
|
114
|
+
throw new Error(data.message || data.error || 'Generation failed');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
if (e instanceof SyntaxError)
|
|
119
|
+
continue; // Skip non-JSON data events
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { generationId, pages };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=sse-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-client.js","sourceRoot":"","sources":["../../src/client/sse-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Mirra MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Supports stdio (default) and SSE transports.
|
|
6
|
+
*
|
|
7
|
+
* Environment variables:
|
|
8
|
+
* MIRRA_API_KEY - API key for authentication (required)
|
|
9
|
+
* MIRRA_BASE_URL - Mirra API base URL (default: https://mirra.my)
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* # stdio (for Claude Desktop)
|
|
13
|
+
* npx @mirra/mcp-server
|
|
14
|
+
*
|
|
15
|
+
* # SSE (for remote clients)
|
|
16
|
+
* npx @mirra/mcp-server --transport sse --port 3100
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;GAeG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Mirra MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Supports stdio (default) and SSE transports.
|
|
6
|
+
*
|
|
7
|
+
* Environment variables:
|
|
8
|
+
* MIRRA_API_KEY - API key for authentication (required)
|
|
9
|
+
* MIRRA_BASE_URL - Mirra API base URL (default: https://mirra.my)
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* # stdio (for Claude Desktop)
|
|
13
|
+
* npx @mirra/mcp-server
|
|
14
|
+
*
|
|
15
|
+
* # SSE (for remote clients)
|
|
16
|
+
* npx @mirra/mcp-server --transport sse --port 3100
|
|
17
|
+
*/
|
|
18
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
19
|
+
import { createMirraServer } from './server.js';
|
|
20
|
+
function parseArgs() {
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
let transport = 'stdio';
|
|
23
|
+
let port = 3100;
|
|
24
|
+
for (let i = 0; i < args.length; i++) {
|
|
25
|
+
if (args[i] === '--transport' && args[i + 1]) {
|
|
26
|
+
const val = args[i + 1];
|
|
27
|
+
if (val === 'stdio' || val === 'sse') {
|
|
28
|
+
transport = val;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.error(`Unknown transport: ${val}. Supported: stdio, sse`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
else if (args[i] === '--port' && args[i + 1]) {
|
|
37
|
+
port = parseInt(args[i + 1], 10);
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { transport, port };
|
|
42
|
+
}
|
|
43
|
+
async function main() {
|
|
44
|
+
const apiKey = process.env.MIRRA_API_KEY;
|
|
45
|
+
if (!apiKey) {
|
|
46
|
+
console.error('Error: MIRRA_API_KEY environment variable is required');
|
|
47
|
+
console.error('Get your API key from Mirra workspace settings.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const baseUrl = process.env.MIRRA_BASE_URL || 'https://mirra.my';
|
|
51
|
+
const { transport } = parseArgs();
|
|
52
|
+
const server = createMirraServer({ apiKey, baseUrl });
|
|
53
|
+
if (transport === 'stdio') {
|
|
54
|
+
const stdioTransport = new StdioServerTransport();
|
|
55
|
+
await server.connect(stdioTransport);
|
|
56
|
+
console.error('Mirra MCP server running on stdio');
|
|
57
|
+
}
|
|
58
|
+
else if (transport === 'sse') {
|
|
59
|
+
// Streamable HTTP transport can be added with Express/Hono adapter
|
|
60
|
+
console.error('SSE transport is not yet implemented. Use stdio transport.');
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.error(`Unknown transport: ${transport}. Supported: stdio, sse`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
main().catch((error) => {
|
|
69
|
+
console.error('Fatal error:', error);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClC,IAAI,SAAS,GAAoB,OAAO,CAAA;IACxC,IAAI,IAAI,GAAG,IAAI,CAAA;IAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACvB,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;gBACrC,SAAS,GAAG,GAAG,CAAA;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,yBAAyB,CAAC,CAAA;gBACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,CAAC,EAAE,CAAA;QACL,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/C,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YAChC,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAC5B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAA;QACtE,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,kBAAkB,CAAA;IAChE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAAA;IAEjC,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;IAErD,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QAC1B,MAAM,cAAc,GAAG,IAAI,oBAAoB,EAAE,CAAA;QACjD,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;QACpC,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;IACpD,CAAC;SAAM,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;QAC/B,mEAAmE;QACnE,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAA;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,yBAAyB,CAAC,CAAA;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirra MCP Server Definition
|
|
3
|
+
*
|
|
4
|
+
* Registers all tools organized by feature area:
|
|
5
|
+
* - Carousel (카드뉴스): 8 tools
|
|
6
|
+
* - Shorts (숏츠): 9 tools
|
|
7
|
+
* - Publishing (예약발행): 6 tools
|
|
8
|
+
* - Analytics (데이터분석): 5 tools
|
|
9
|
+
*/
|
|
10
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import type { MirraConfig } from './types/index.js';
|
|
12
|
+
export declare function createMirraServer(config: MirraConfig): McpServer;
|
|
13
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAOnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAgBhE"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirra MCP Server Definition
|
|
3
|
+
*
|
|
4
|
+
* Registers all tools organized by feature area:
|
|
5
|
+
* - Carousel (카드뉴스): 8 tools
|
|
6
|
+
* - Shorts (숏츠): 9 tools
|
|
7
|
+
* - Publishing (예약발행): 6 tools
|
|
8
|
+
* - Analytics (데이터분석): 5 tools
|
|
9
|
+
*/
|
|
10
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import { MirraApiClient } from './client/api-client.js';
|
|
12
|
+
import { SSEClient } from './client/sse-client.js';
|
|
13
|
+
import { registerCarouselTools } from './tools/carousel.js';
|
|
14
|
+
import { registerShortsTools } from './tools/shorts.js';
|
|
15
|
+
import { registerPublishingTools } from './tools/publishing.js';
|
|
16
|
+
import { registerAnalyticsTools } from './tools/analytics.js';
|
|
17
|
+
export function createMirraServer(config) {
|
|
18
|
+
const server = new McpServer({
|
|
19
|
+
name: 'mirra',
|
|
20
|
+
version: '0.1.0',
|
|
21
|
+
});
|
|
22
|
+
const api = new MirraApiClient(config);
|
|
23
|
+
const sse = new SSEClient(config);
|
|
24
|
+
// Register all tools
|
|
25
|
+
registerCarouselTools(server, api, sse);
|
|
26
|
+
registerShortsTools(server, api);
|
|
27
|
+
registerPublishingTools(server, api);
|
|
28
|
+
registerAnalyticsTools(server, api);
|
|
29
|
+
return server;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAG7D,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAA;IAEjC,qBAAqB;IACrB,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACvC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAChC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnC,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics (데이터분석) Tools - 3 tools
|
|
3
|
+
*
|
|
4
|
+
* Core tools for social media performance data and AI-powered analytics.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
import type { MirraApiClient } from '../client/api-client.js';
|
|
8
|
+
export declare function registerAnalyticsTools(server: McpServer, api: MirraApiClient): void;
|
|
9
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/tools/analytics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,cAAc,QAqGpB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics (데이터분석) Tools - 3 tools
|
|
3
|
+
*
|
|
4
|
+
* Core tools for social media performance data and AI-powered analytics.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export function registerAnalyticsTools(server, api) {
|
|
8
|
+
// 1. Posts performance
|
|
9
|
+
server.tool('analytics_posts_performance', 'Get posts performance metrics with optional period comparison (views, likes, replies, reposts, etc.).', {
|
|
10
|
+
startDate: z.string().optional().describe('Start date (YYYY-MM-DD)'),
|
|
11
|
+
endDate: z.string().optional().describe('End date (YYYY-MM-DD)'),
|
|
12
|
+
socialAccountId: z.string().optional().describe('Filter by social account'),
|
|
13
|
+
comparisonType: z.enum(['previous', 'yoy', 'mom', 'wow']).optional().describe('Comparison period type'),
|
|
14
|
+
}, async (params) => {
|
|
15
|
+
try {
|
|
16
|
+
const result = await api.get('/api/v1/analytics/posts-performance', {
|
|
17
|
+
startDate: params.startDate,
|
|
18
|
+
endDate: params.endDate,
|
|
19
|
+
socialAccountId: params.socialAccountId,
|
|
20
|
+
comparisonType: params.comparisonType,
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
content: [{
|
|
24
|
+
type: 'text',
|
|
25
|
+
text: JSON.stringify(result, null, 2),
|
|
26
|
+
}],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
// 2. Account insights
|
|
37
|
+
server.tool('analytics_account_insights', 'Get account-level insights including demographics, follower count, and engagement metrics.', {
|
|
38
|
+
socialAccountId: z.string().optional().describe('Social account ID. If omitted, returns all accounts.'),
|
|
39
|
+
}, async (params) => {
|
|
40
|
+
try {
|
|
41
|
+
const result = await api.get('/api/v1/analytics/account-insights', { socialAccountId: params.socialAccountId });
|
|
42
|
+
return {
|
|
43
|
+
content: [{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: JSON.stringify(result, null, 2),
|
|
46
|
+
}],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
52
|
+
isError: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// 3. AI analytics chat
|
|
57
|
+
server.tool('analytics_chat', 'Ask AI-powered questions about your social media analytics. Uses LLM to analyze your data and provide insights.', {
|
|
58
|
+
question: z.string().describe('Question about your analytics (e.g., "What was my best performing post this week?")'),
|
|
59
|
+
startDate: z.string().optional().describe('Analysis start date (YYYY-MM-DD)'),
|
|
60
|
+
endDate: z.string().optional().describe('Analysis end date (YYYY-MM-DD)'),
|
|
61
|
+
socialAccountId: z.string().optional().describe('Focus on specific account'),
|
|
62
|
+
}, async (params) => {
|
|
63
|
+
try {
|
|
64
|
+
const result = await api.post('/api/v1/analytics/chat', {
|
|
65
|
+
message: params.question,
|
|
66
|
+
startDate: params.startDate,
|
|
67
|
+
endDate: params.endDate,
|
|
68
|
+
accountId: params.socialAccountId,
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
content: [{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
74
|
+
}],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
80
|
+
isError: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/tools/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carousel (카드뉴스) Tools - 6 tools
|
|
3
|
+
*
|
|
4
|
+
* Core tools for generating, rendering, and editing carousel content.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
import type { MirraApiClient } from '../client/api-client.js';
|
|
8
|
+
import type { SSEClient } from '../client/sse-client.js';
|
|
9
|
+
export declare function registerCarouselTools(server: McpServer, api: MirraApiClient, sse: SSEClient): void;
|
|
10
|
+
//# sourceMappingURL=carousel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../src/tools/carousel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGxD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,SAAS,QAyNf"}
|