user-majico-mcp 0.7.5
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/README.md +144 -0
- package/dist/agent-bootstrap.d.ts +8 -0
- package/dist/agent-bootstrap.js +21 -0
- package/dist/auth-prompt.d.ts +13 -0
- package/dist/auth-prompt.js +15 -0
- package/dist/client-disconnect.d.ts +4 -0
- package/dist/client-disconnect.js +17 -0
- package/dist/credentials.d.ts +40 -0
- package/dist/credentials.js +60 -0
- package/dist/http-handler.d.ts +6 -0
- package/dist/http-handler.js +28 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +22 -0
- package/dist/present-interactive.d.ts +92 -0
- package/dist/present-interactive.js +479 -0
- package/dist/present-types.d.ts +17 -0
- package/dist/present-types.js +1 -0
- package/dist/project-relevance.d.ts +27 -0
- package/dist/project-relevance.js +95 -0
- package/dist/project-selection-hints.d.ts +16 -0
- package/dist/project-selection-hints.js +32 -0
- package/dist/project-selection.d.ts +25 -0
- package/dist/project-selection.js +42 -0
- package/dist/recommended-external-skills.d.ts +39 -0
- package/dist/recommended-external-skills.js +319 -0
- package/dist/sdk-surface.d.ts +10 -0
- package/dist/sdk-surface.js +24 -0
- package/dist/server-branding.d.ts +17 -0
- package/dist/server-branding.js +40 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +24 -0
- package/dist/svg-preview-block.d.ts +14 -0
- package/dist/svg-preview-block.js +82 -0
- package/dist/tools/constants.d.ts +47 -0
- package/dist/tools/constants.js +95 -0
- package/dist/tools/dispatch-branding-studio.d.ts +5 -0
- package/dist/tools/dispatch-branding-studio.js +197 -0
- package/dist/tools/dispatch-pulse-blog.d.ts +3 -0
- package/dist/tools/dispatch-pulse-blog.js +158 -0
- package/dist/tools/dispatch-research-assets.d.ts +3 -0
- package/dist/tools/dispatch-research-assets.js +132 -0
- package/dist/tools/handle-tool-call-pre.d.ts +4 -0
- package/dist/tools/handle-tool-call-pre.js +47 -0
- package/dist/tools/handle-tool-call.d.ts +3 -0
- package/dist/tools/handle-tool-call.js +56 -0
- package/dist/tools/tool-call-helpers.d.ts +22 -0
- package/dist/tools/tool-call-helpers.js +104 -0
- package/dist/tools/tool-catalog.d.ts +14 -0
- package/dist/tools/tool-catalog.js +54 -0
- package/dist/tools/tool-definitions-blog-git.d.ts +2 -0
- package/dist/tools/tool-definitions-blog-git.js +207 -0
- package/dist/tools/tool-definitions-branding.d.ts +2 -0
- package/dist/tools/tool-definitions-branding.js +197 -0
- package/dist/tools/tool-definitions-research-aliases.d.ts +2 -0
- package/dist/tools/tool-definitions-research-aliases.js +340 -0
- package/dist/tools/tool-definitions-studio-pulse.d.ts +2 -0
- package/dist/tools/tool-definitions-studio-pulse.js +235 -0
- package/dist/tools/tool-matrix.d.ts +12 -0
- package/dist/tools/tool-matrix.js +36 -0
- package/dist/tools.d.ts +5 -0
- package/dist/tools.js +3 -0
- package/dist/ui-ux-skills.d.ts +33 -0
- package/dist/ui-ux-skills.js +157 -0
- package/dist/user-pick-policy.d.ts +18 -0
- package/dist/user-pick-policy.js +21 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# user-majico MCP server
|
|
2
|
+
|
|
3
|
+
MCP server for [Majico.xyz](https://majico.xyz): read (and limited write) tools so coding agents can pull brand guidelines, design tokens, studio canvas, and export manifests.
|
|
4
|
+
|
|
5
|
+
**Requirements:** Majico account with tokens. Cursor humans connect via **OAuth** (no API key in `mcp.json`). API keys are for automation/stdio only.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y user-majico-mcp@0.4.1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Environment variables (v0.2+)
|
|
14
|
+
|
|
15
|
+
Set once in MCP config — tools do not require `projectId` / `apiKey` on every call:
|
|
16
|
+
|
|
17
|
+
| Variable | Description |
|
|
18
|
+
| ------------------- | ------------------------------------------------------------------------------- |
|
|
19
|
+
| `MAJICO_API_URL` | API base (default `http://localhost:3000`; production `https://api.majico.xyz`) |
|
|
20
|
+
| `MAJICO_PROJECT_ID` | Project UUID |
|
|
21
|
+
| `MAJICO_API_KEY` | Project API key |
|
|
22
|
+
|
|
23
|
+
Per-call overrides in tool arguments still work.
|
|
24
|
+
|
|
25
|
+
## Tools
|
|
26
|
+
|
|
27
|
+
| Tool | Description |
|
|
28
|
+
| -------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| `get_brand_profile` | Archetypes, niche intent |
|
|
30
|
+
| `get_design_tokens` | Palette and fonts |
|
|
31
|
+
| `get_logo_svg` | Selected logo SVG |
|
|
32
|
+
| `get_guidelines` | Markdown + LLM prompt |
|
|
33
|
+
| `get_design_md` | DESIGN.md markdown |
|
|
34
|
+
| `get_studio_canvas` | Studio canvas snapshot |
|
|
35
|
+
| `get_export_manifest` | Export file list |
|
|
36
|
+
| `download_export_zip` | Full BRAND.md / DESIGN.md / tokens ZIP (base64 in MCP response) |
|
|
37
|
+
| `submit_brief` | Submit product brief + enqueue niche research |
|
|
38
|
+
| `update_studio_html_frame` | Patch one `htmlFrame` (requires `elementId`, `html`) |
|
|
39
|
+
| `generate_asset` | Enqueue harness jobs (`landing-page`, `investor-pack`, `investor-one-pager`, `investor-data-room`, …) |
|
|
40
|
+
| `get_asset_status` | Poll harness job status |
|
|
41
|
+
|
|
42
|
+
### Cursor agent example: `generate_asset` for investor pack
|
|
43
|
+
|
|
44
|
+
After brand chain, palette, GTM, team, and traction are ready:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"tool": "generate_asset",
|
|
49
|
+
"arguments": {
|
|
50
|
+
"skillId": "investor-pack",
|
|
51
|
+
"params": {
|
|
52
|
+
"team": {
|
|
53
|
+
"members": [
|
|
54
|
+
{ "name": "Alex Kim", "role": "CEO", "bio": "ex-Stripe PM" }
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"traction": {
|
|
58
|
+
"metrics": [{ "label": "Waitlist", "value": "1,200" }]
|
|
59
|
+
},
|
|
60
|
+
"includeSlides": ["financials"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Poll with `get_asset_status({ jobId })`. Preflight failures return HTTP 422 with `code: "investor_pack_preflight_blocked"` and a `blocked` reason (`brand`, `gtm`, `team`, `traction`, …).
|
|
67
|
+
|
|
68
|
+
### Phase 2: one-pager and data room (after deck exists on canvas)
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"tool": "generate_asset",
|
|
73
|
+
"arguments": {
|
|
74
|
+
"skillId": "investor-one-pager"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"tool": "generate_asset",
|
|
82
|
+
"arguments": {
|
|
83
|
+
"skillId": "investor-data-room"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Both require a `harness-investor-pack` element on the Studio canvas (generate `investor-pack` first). Without a deck, jobs return a stub with `canvasUrl` pointing to finish the deck.
|
|
89
|
+
|
|
90
|
+
## Cursor `.cursor/mcp.json` (OAuth — preferred)
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"mcpServers": {
|
|
95
|
+
"majico": {
|
|
96
|
+
"url": "https://api.majico.xyz/mcp"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Complete **Connect** in Cursor Settings → MCP. Use `list_projects` and pass `projectId` on tool calls to switch scope.
|
|
103
|
+
|
|
104
|
+
## Cursor `.cursor/mcp.json` (stdio — automation / local)
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"mcpServers": {
|
|
109
|
+
"majico": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["-y", "user-majico-mcp@0.4.1"],
|
|
112
|
+
"env": {
|
|
113
|
+
"MAJICO_API_URL": "https://api.majico.xyz",
|
|
114
|
+
"MAJICO_PROJECT_ID": "<uuid>",
|
|
115
|
+
"MAJICO_API_KEY": "<key>"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## HTTP MCP (hosted)
|
|
123
|
+
|
|
124
|
+
**OAuth (Cursor humans):** `https://api.majico.xyz/mcp` — Connect in Cursor; no headers in `mcp.json`.
|
|
125
|
+
|
|
126
|
+
**API key (automation only):**
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
Authorization: Bearer <project_api_key>
|
|
130
|
+
X-Majico-Project-Id: <uuid>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
cd packages/user-majico-mcp
|
|
137
|
+
npm install
|
|
138
|
+
npm run build
|
|
139
|
+
npm test
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function readAgentEnv(): {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
agentSecret: string;
|
|
4
|
+
} | null;
|
|
5
|
+
export declare function bootstrapProjectViaAgent(name: string): Promise<{
|
|
6
|
+
project: Awaited<ReturnType<import("../../majico-sdk/dist/resources/agent-projects.js").AgentProjectsResource["bootstrap"]>>;
|
|
7
|
+
client: import("@majico/sdk").MajicoClient | null;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MajicoAgentClient } from "@majico/sdk";
|
|
2
|
+
export function readAgentEnv() {
|
|
3
|
+
const agentSecret = process.env.MAJICO_AGENT_API_SECRET?.trim();
|
|
4
|
+
const baseUrl = process.env.MAJICO_API_URL?.trim() ||
|
|
5
|
+
process.env.MAJICO_AGENT_API_URL?.trim() ||
|
|
6
|
+
"https://majico.d3bu7.com";
|
|
7
|
+
if (!agentSecret)
|
|
8
|
+
return null;
|
|
9
|
+
return { baseUrl: baseUrl.replace(/\/$/, ""), agentSecret };
|
|
10
|
+
}
|
|
11
|
+
export async function bootstrapProjectViaAgent(name) {
|
|
12
|
+
const env = readAgentEnv();
|
|
13
|
+
if (!env) {
|
|
14
|
+
throw new Error("MAJICO_AGENT_API_SECRET is required for bootstrap_project (set in MCP env).");
|
|
15
|
+
}
|
|
16
|
+
const agent = new MajicoAgentClient({
|
|
17
|
+
baseUrl: env.baseUrl,
|
|
18
|
+
agentSecret: env.agentSecret,
|
|
19
|
+
});
|
|
20
|
+
return agent.bootstrapProject(name);
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Agent-facing copy for Majico MCP OAuth connect and plan gates. */
|
|
2
|
+
export declare const MAJICO_MCP_CONNECT_PROMPT = "Majico is not connected. Ask the user to open Cursor Settings \u2192 MCP \u2192 majico \u2192 Connect and complete sign-in in the browser.";
|
|
3
|
+
export declare const MAJICO_MCP_PLAN_REQUIRED_PROMPT = "Majico is connected, but this action needs more tokens. Ask the user to add tokens at https://majico.xyz/account/billing (Pro one-time or Creator subscription).";
|
|
4
|
+
export declare const MAJICO_MCP_AUTH_AGENT_INSTRUCTIONS = "Display the message field verbatim to the user. Do not call other Majico tools until ping returns ok: true without authRequired.";
|
|
5
|
+
export declare const AUTH_FIRST_STEP = " First call ping to verify auth. If ping fails, returns authRequired, or tools are unavailable, stop and ask the user to Connect in Cursor Settings \u2192 MCP \u2192 majico (call mcp_auth for the exact prompt).";
|
|
6
|
+
export type McpAuthAction = "connect_oauth" | "upgrade_plan";
|
|
7
|
+
export type McpAuthRequiredPayload = {
|
|
8
|
+
authRequired: true;
|
|
9
|
+
action: McpAuthAction;
|
|
10
|
+
message: string;
|
|
11
|
+
agentInstructions: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function buildMcpAuthRequiredPayload(action: McpAuthAction, message?: string): McpAuthRequiredPayload;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Agent-facing copy for Majico MCP OAuth connect and plan gates. */
|
|
2
|
+
export const MAJICO_MCP_CONNECT_PROMPT = "Majico is not connected. Ask the user to open Cursor Settings → MCP → majico → Connect and complete sign-in in the browser.";
|
|
3
|
+
export const MAJICO_MCP_PLAN_REQUIRED_PROMPT = "Majico is connected, but this action needs more tokens. Ask the user to add tokens at https://majico.xyz/account/billing (Pro one-time or Creator subscription).";
|
|
4
|
+
export const MAJICO_MCP_AUTH_AGENT_INSTRUCTIONS = "Display the message field verbatim to the user. Do not call other Majico tools until ping returns ok: true without authRequired.";
|
|
5
|
+
export const AUTH_FIRST_STEP = " First call ping to verify auth. If ping fails, returns authRequired, or tools are unavailable, stop and ask the user to Connect in Cursor Settings → MCP → majico (call mcp_auth for the exact prompt).";
|
|
6
|
+
export function buildMcpAuthRequiredPayload(action, message = action === "upgrade_plan"
|
|
7
|
+
? MAJICO_MCP_PLAN_REQUIRED_PROMPT
|
|
8
|
+
: MAJICO_MCP_CONNECT_PROMPT) {
|
|
9
|
+
return {
|
|
10
|
+
authRequired: true,
|
|
11
|
+
action,
|
|
12
|
+
message,
|
|
13
|
+
agentInstructions: MAJICO_MCP_AUTH_AGENT_INSTRUCTIONS,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when the client closed the MCP HTTP connection mid-request.
|
|
3
|
+
*/
|
|
4
|
+
export function isMcpClientDisconnectError(error) {
|
|
5
|
+
if (!error || typeof error !== "object")
|
|
6
|
+
return false;
|
|
7
|
+
const err = error;
|
|
8
|
+
if (err.name === "AbortError")
|
|
9
|
+
return true;
|
|
10
|
+
if (err.code === "ECONNRESET" ||
|
|
11
|
+
err.code === "EPIPE" ||
|
|
12
|
+
err.code === "ERR_STREAM_PREMATURE_CLOSE") {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
const message = typeof err.message === "string" ? err.message : "";
|
|
16
|
+
return message === "aborted" || message === "The operation was aborted";
|
|
17
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { MajicoClient } from "@majico/sdk";
|
|
2
|
+
import { type McpAuthRequiredPayload } from "./auth-prompt.js";
|
|
3
|
+
export type ResolvedCredentials = {
|
|
4
|
+
projectId: string;
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
};
|
|
8
|
+
export type CredentialSource = {
|
|
9
|
+
projectId?: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/** Internal API base (e.g. http://127.0.0.1:3000) for server-side SDK calls */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
/** Public origin for browser + preview links in interactive MCP results */
|
|
14
|
+
publicBaseUrl?: string;
|
|
15
|
+
/** Origin for MCP serverInfo icon URLs (defaults to publicBaseUrl; prod uses app host). */
|
|
16
|
+
iconBaseUrl?: string;
|
|
17
|
+
/** How the MCP session authenticated (set by HTTP transport). */
|
|
18
|
+
auth?: "oauth" | "api_key";
|
|
19
|
+
/** Authenticated Supabase user id when available (OAuth or derived from API key). */
|
|
20
|
+
userId?: string;
|
|
21
|
+
/** Include admin-only bootstrap tools in tools/list (requires agent secret). */
|
|
22
|
+
includeAdminTools?: boolean;
|
|
23
|
+
/** OAuth-only: resolve delegated project scope server-side without exposing API keys. */
|
|
24
|
+
resolveOAuthProject?: (projectId: string) => Promise<{
|
|
25
|
+
projectId: string;
|
|
26
|
+
apiKey: string;
|
|
27
|
+
} | {
|
|
28
|
+
error: string;
|
|
29
|
+
}>;
|
|
30
|
+
/** OAuth session is valid but the bound project lacks Pro/Creator MCP access. */
|
|
31
|
+
planRequired?: boolean;
|
|
32
|
+
};
|
|
33
|
+
export declare function readEnvCredentials(): CredentialSource;
|
|
34
|
+
export type CredentialResolutionError = (McpAuthRequiredPayload & {
|
|
35
|
+
error: string;
|
|
36
|
+
}) | {
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function resolveCredentials(args?: CredentialSource, env?: CredentialSource): Promise<ResolvedCredentials | CredentialResolutionError>;
|
|
40
|
+
export declare function createClientFromCredentials(creds: ResolvedCredentials): MajicoClient;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { MajicoClient } from "@majico/sdk";
|
|
2
|
+
import { buildMcpAuthRequiredPayload, MAJICO_MCP_CONNECT_PROMPT, MAJICO_MCP_PLAN_REQUIRED_PROMPT, } from "./auth-prompt.js";
|
|
3
|
+
const ENV_PROJECT_ID = "MAJICO_PROJECT_ID";
|
|
4
|
+
const ENV_API_KEY = "MAJICO_API_KEY";
|
|
5
|
+
const ENV_API_URL = "MAJICO_API_URL";
|
|
6
|
+
export function readEnvCredentials() {
|
|
7
|
+
return {
|
|
8
|
+
projectId: process.env[ENV_PROJECT_ID]?.trim() || undefined,
|
|
9
|
+
apiKey: process.env[ENV_API_KEY]?.trim() || undefined,
|
|
10
|
+
baseUrl: process.env[ENV_API_URL]?.trim() || undefined,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export async function resolveCredentials(args, env = readEnvCredentials()) {
|
|
14
|
+
const requestedProjectId = args?.projectId?.trim() || env.projectId;
|
|
15
|
+
const apiKey = args?.apiKey?.trim() || env.apiKey;
|
|
16
|
+
const baseUrl = args?.baseUrl?.trim() || env.baseUrl;
|
|
17
|
+
if (env.planRequired) {
|
|
18
|
+
return {
|
|
19
|
+
...buildMcpAuthRequiredPayload("upgrade_plan"),
|
|
20
|
+
error: MAJICO_MCP_PLAN_REQUIRED_PROMPT,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (env.resolveOAuthProject &&
|
|
24
|
+
requestedProjectId &&
|
|
25
|
+
env.projectId &&
|
|
26
|
+
requestedProjectId !== env.projectId &&
|
|
27
|
+
!args?.apiKey) {
|
|
28
|
+
const delegated = await env.resolveOAuthProject(requestedProjectId);
|
|
29
|
+
if ("error" in delegated)
|
|
30
|
+
return delegated;
|
|
31
|
+
return {
|
|
32
|
+
projectId: delegated.projectId,
|
|
33
|
+
apiKey: delegated.apiKey,
|
|
34
|
+
baseUrl,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (!requestedProjectId || !apiKey) {
|
|
38
|
+
const oauthSession = env.auth === "oauth" || Boolean(env.resolveOAuthProject);
|
|
39
|
+
if (oauthSession) {
|
|
40
|
+
return {
|
|
41
|
+
...buildMcpAuthRequiredPayload("connect_oauth"),
|
|
42
|
+
error: MAJICO_MCP_CONNECT_PROMPT,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
...buildMcpAuthRequiredPayload("connect_oauth"),
|
|
47
|
+
error: MAJICO_MCP_CONNECT_PROMPT,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return { projectId: requestedProjectId, apiKey, baseUrl };
|
|
51
|
+
}
|
|
52
|
+
export function createClientFromCredentials(creds) {
|
|
53
|
+
const config = {
|
|
54
|
+
apiKey: creds.apiKey,
|
|
55
|
+
projectId: creds.projectId,
|
|
56
|
+
baseUrl: creds.baseUrl,
|
|
57
|
+
retry: { max: 2, retryOn: [429, 503] },
|
|
58
|
+
};
|
|
59
|
+
return new MajicoClient(config);
|
|
60
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CredentialSource } from "./credentials.js";
|
|
2
|
+
/**
|
|
3
|
+
* Stateless Streamable HTTP handler for Next.js / edge runtimes.
|
|
4
|
+
* Credentials from HTTP headers override env defaults for tool calls.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleMcpHttpRequest(request: Request, headerCredentials?: CredentialSource): Promise<Response>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
2
|
+
import { isMcpClientDisconnectError } from "./client-disconnect.js";
|
|
3
|
+
import { createMajicoMcpServer } from "./server.js";
|
|
4
|
+
/**
|
|
5
|
+
* Stateless Streamable HTTP handler for Next.js / edge runtimes.
|
|
6
|
+
* Credentials from HTTP headers override env defaults for tool calls.
|
|
7
|
+
*/
|
|
8
|
+
export async function handleMcpHttpRequest(request, headerCredentials) {
|
|
9
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
10
|
+
sessionIdGenerator: undefined,
|
|
11
|
+
enableJsonResponse: true,
|
|
12
|
+
});
|
|
13
|
+
const server = createMajicoMcpServer(headerCredentials);
|
|
14
|
+
await server.connect(transport);
|
|
15
|
+
try {
|
|
16
|
+
return await transport.handleRequest(request);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
if (isMcpClientDisconnectError(error) || request.signal.aborted) {
|
|
20
|
+
return new Response(null, { status: 499 });
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
await transport.close().catch(() => undefined);
|
|
26
|
+
await server.close().catch(() => undefined);
|
|
27
|
+
}
|
|
28
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* user-majico MCP server (stdio): brand profile, design tokens, logo, guidelines, studio.
|
|
4
|
+
* Set MAJICO_API_URL, MAJICO_PROJECT_ID, MAJICO_API_KEY once; per-call overrides still work.
|
|
5
|
+
*/
|
|
6
|
+
export { createMajicoMcpServer } from "./server.js";
|
|
7
|
+
export { handleMcpHttpRequest } from "./http-handler.js";
|
|
8
|
+
export { handleMajicoToolCall, listMcpTools, classifyMcpTool, MCP_LLM_TOOL_NAMES, partitionMcpToolNames, MAJICO_TOOLS, MAJICO_USER_TOOLS, MAJICO_ADMIN_BOOTSTRAP_TOOLS, MCP_SERVER_VERSION, } from "./tools.js";
|
|
9
|
+
export type { McpToolKind } from "./tools.js";
|
|
10
|
+
export { readEnvCredentials, resolveCredentials, createClientFromCredentials, } from "./credentials.js";
|
|
11
|
+
export { AUTH_FIRST_STEP, MAJICO_MCP_AUTH_AGENT_INSTRUCTIONS, MAJICO_MCP_CONNECT_PROMPT, MAJICO_MCP_PLAN_REQUIRED_PROMPT, buildMcpAuthRequiredPayload, } from "./auth-prompt.js";
|
|
12
|
+
export type { McpAuthAction, McpAuthRequiredPayload } from "./auth-prompt.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* user-majico MCP server (stdio): brand profile, design tokens, logo, guidelines, studio.
|
|
4
|
+
* Set MAJICO_API_URL, MAJICO_PROJECT_ID, MAJICO_API_KEY once; per-call overrides still work.
|
|
5
|
+
*/
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import { readEnvCredentials } from "./credentials.js";
|
|
8
|
+
import { createMajicoMcpServer } from "./server.js";
|
|
9
|
+
export { createMajicoMcpServer } from "./server.js";
|
|
10
|
+
export { handleMcpHttpRequest } from "./http-handler.js";
|
|
11
|
+
export { handleMajicoToolCall, listMcpTools, classifyMcpTool, MCP_LLM_TOOL_NAMES, partitionMcpToolNames, MAJICO_TOOLS, MAJICO_USER_TOOLS, MAJICO_ADMIN_BOOTSTRAP_TOOLS, MCP_SERVER_VERSION, } from "./tools.js";
|
|
12
|
+
export { readEnvCredentials, resolveCredentials, createClientFromCredentials, } from "./credentials.js";
|
|
13
|
+
export { AUTH_FIRST_STEP, MAJICO_MCP_AUTH_AGENT_INSTRUCTIONS, MAJICO_MCP_CONNECT_PROMPT, MAJICO_MCP_PLAN_REQUIRED_PROMPT, buildMcpAuthRequiredPayload, } from "./auth-prompt.js";
|
|
14
|
+
async function main() {
|
|
15
|
+
const transport = new StdioServerTransport();
|
|
16
|
+
const server = createMajicoMcpServer(readEnvCredentials());
|
|
17
|
+
await server.connect(transport);
|
|
18
|
+
}
|
|
19
|
+
main().catch((err) => {
|
|
20
|
+
console.error(err);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { McpContentBlock, PresentContext } from "./present-types.js";
|
|
2
|
+
export type { McpContentBlock, PresentContext } from "./present-types.js";
|
|
3
|
+
type PaletteOptionRow = {
|
|
4
|
+
optionId: string;
|
|
5
|
+
label: string;
|
|
6
|
+
isSelected: boolean;
|
|
7
|
+
swatches: {
|
|
8
|
+
light: string[];
|
|
9
|
+
dark: string[];
|
|
10
|
+
};
|
|
11
|
+
previewTokens?: {
|
|
12
|
+
light: Record<string, string>;
|
|
13
|
+
dark: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
type PaletteCandidatesPayload = {
|
|
17
|
+
options?: PaletteOptionRow[];
|
|
18
|
+
selectedOptionId: string | null;
|
|
19
|
+
paletteTokens: {
|
|
20
|
+
light: Record<string, string>;
|
|
21
|
+
dark: Record<string, string>;
|
|
22
|
+
} | null;
|
|
23
|
+
headingFont?: string | null;
|
|
24
|
+
bodyFont?: string | null;
|
|
25
|
+
agentInstructions?: string;
|
|
26
|
+
projectId?: string | null;
|
|
27
|
+
projectName?: string | null;
|
|
28
|
+
previewToken?: string | null;
|
|
29
|
+
previewPickerUrl?: string | null;
|
|
30
|
+
};
|
|
31
|
+
type LogoCandidateRow = {
|
|
32
|
+
id: string;
|
|
33
|
+
kind: string;
|
|
34
|
+
previewSvg: string;
|
|
35
|
+
templateId?: string | null;
|
|
36
|
+
userRating?: string | null;
|
|
37
|
+
};
|
|
38
|
+
type LogoCandidatesPayload = {
|
|
39
|
+
selectedLogoTemplateId: string | null;
|
|
40
|
+
logoSvg: string | null;
|
|
41
|
+
logoFavorites: unknown[];
|
|
42
|
+
shortlistCount: number;
|
|
43
|
+
candidates: LogoCandidateRow[];
|
|
44
|
+
emptyReason?: string | null;
|
|
45
|
+
guidance?: string | null;
|
|
46
|
+
projectId?: string | null;
|
|
47
|
+
projectName?: string | null;
|
|
48
|
+
previewToken?: string | null;
|
|
49
|
+
previewPickerUrl?: string | null;
|
|
50
|
+
};
|
|
51
|
+
type CursorHandoffPayload = {
|
|
52
|
+
event: string;
|
|
53
|
+
browserUrl: string;
|
|
54
|
+
chatPrompt: string;
|
|
55
|
+
};
|
|
56
|
+
type CursorHandoffPayloadResponse = {
|
|
57
|
+
pending: boolean;
|
|
58
|
+
handoff: CursorHandoffPayload | null;
|
|
59
|
+
};
|
|
60
|
+
type TweetDraftsPayload = {
|
|
61
|
+
drafts?: Array<{
|
|
62
|
+
draftId: string;
|
|
63
|
+
text: string;
|
|
64
|
+
}>;
|
|
65
|
+
agentInstructions?: string;
|
|
66
|
+
};
|
|
67
|
+
export declare function pickPaletteOptionsForDisplay<T extends PaletteOptionRow>(options: T[], max?: number): T[];
|
|
68
|
+
export declare function scoreReeldemoPaletteMatch(option: PaletteOptionRow): number;
|
|
69
|
+
export declare function isReeldemoPaletteContext(ctx: PresentContext): boolean;
|
|
70
|
+
export declare function buildPalettePreviewCardSvg(args: {
|
|
71
|
+
label: string;
|
|
72
|
+
index: number;
|
|
73
|
+
tokens: {
|
|
74
|
+
bg: string;
|
|
75
|
+
bgMuted: string;
|
|
76
|
+
text: string;
|
|
77
|
+
accent: string;
|
|
78
|
+
};
|
|
79
|
+
headingFont: string;
|
|
80
|
+
bodyFont: string;
|
|
81
|
+
width?: number;
|
|
82
|
+
height?: number;
|
|
83
|
+
}): string;
|
|
84
|
+
/**
|
|
85
|
+
* Rewrite absolute URLs whose host is bind-all onto the session public base,
|
|
86
|
+
* preserving path + query.
|
|
87
|
+
*/
|
|
88
|
+
export declare function rewritePreviewUrlOntoPublicBase(url: string, publicBaseUrl: string): string;
|
|
89
|
+
export declare function presentLogoCandidates(data: LogoCandidatesPayload, ctx: PresentContext): Promise<McpContentBlock[]>;
|
|
90
|
+
export declare function presentPaletteOptions(data: PaletteCandidatesPayload, ctx: PresentContext): Promise<McpContentBlock[]>;
|
|
91
|
+
export declare function presentTweetDrafts(data: TweetDraftsPayload): McpContentBlock[];
|
|
92
|
+
export declare function presentCursorHandoff(data: CursorHandoffPayloadResponse): McpContentBlock[];
|