@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.
@@ -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":"AAAA;;;;;GAKG;AAIH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAE7B;IAEA;IACA;IAJT,YACS,UAAkB,EACzB,OAAe,EACR,IAAa,EACb,OAAiB;QAExB,KAAK,CAAC,OAAO,CAAC,CAAA;QALP,eAAU,GAAV,UAAU,CAAQ;QAElB,SAAI,GAAJ,IAAI,CAAS;QACb,YAAO,GAAP,OAAO,CAAU;QAGxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,cAAc;IACT,OAAO,CAAQ;IACf,MAAM,CAAQ;IAE9B,YAAY,MAAmB;QAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACnC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;QAC5D,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC7B,CAAC;IAED,IAAY,OAAO;QACjB,OAAO;YACL,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;YACxC,cAAc,EAAE,kBAAkB;SACnC,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAI,QAAkB;QAChD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,SAAS,GAAyD,EAAE,CAAA;YACxE,IAAI,CAAC;gBACH,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;YAED,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,IAAI,kCAAkC,QAAQ,CAAC,MAAM,EAAE,CAAA;YAEtF,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxB,KAAK,GAAG;oBACN,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,4BAA4B,EAAE,yBAAyB,CAAC,CAAA;gBACvF,KAAK,GAAG;oBACN,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,IAAI,WAAW,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;gBACzF,KAAK,GAAG;oBACN,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;gBACpD,KAAK,GAAG;oBACN,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,qBAAqB,EAAE,cAAc,CAAC,CAAA;gBACrE;oBACE,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;YACxF,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,MAA8D;QACvF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC,CAAA;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,cAAc,CAAI,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAc;QACxC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,cAAc,CAAI,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,IAAc;QACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,cAAc,CAAI,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,KAAK,CAAI,IAAY,EAAE,IAAc;QACzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,cAAc,CAAI,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAI,IAAY;QAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,cAAc,CAAI,QAAQ,CAAC,CAAA;IACzC,CAAC;CACF"}
@@ -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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"}
@@ -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":"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"}
@@ -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"}