@fridaplatform-stk/figma2frida-mcp 1.0.7 → 1.0.8
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 +19 -28
- package/dist/figma2frida.js +118 -115
- package/dist/figma2frida.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
Your AI assistant gets four specialized tools:
|
|
18
18
|
|
|
19
|
-
1. **`
|
|
20
|
-
2. **`
|
|
21
|
-
3. **`
|
|
22
|
-
4. **`
|
|
19
|
+
1. **`figma_get_design_context`** - Generate code from Figma with automatic component matching *(main tool)*
|
|
20
|
+
2. **`figma_suggest_components`** - Browse and discover design system components
|
|
21
|
+
3. **`figma_get_screenshot`** - Quick visual reference from Figma
|
|
22
|
+
4. **`figma_improve_layout`** - Fine-tune generated code to match Figma exactly
|
|
23
23
|
|
|
24
24
|
## 🔄 How It Works
|
|
25
25
|
|
|
@@ -37,7 +37,7 @@ Your AI assistant gets four specialized tools:
|
|
|
37
37
|
- Connects to Figma Desktop (local MCP server)
|
|
38
38
|
- Searches your component library in Pinecone
|
|
39
39
|
- Uses Frida AI for intelligent component matching
|
|
40
|
-
- Validates your
|
|
40
|
+
- Validates your session token via Firebase
|
|
41
41
|
|
|
42
42
|
## 📦 Installation
|
|
43
43
|
|
|
@@ -60,10 +60,8 @@ Add to your configuration file:
|
|
|
60
60
|
"command": "npx",
|
|
61
61
|
"args": [
|
|
62
62
|
"@fridaplatform-stk/figma2frida-mcp",
|
|
63
|
-
"--
|
|
64
|
-
"
|
|
65
|
-
"--frida-api-token",
|
|
66
|
-
"YOUR_API_TOKEN"
|
|
63
|
+
"--session-token",
|
|
64
|
+
"YOUR_SESSION_TOKEN"
|
|
67
65
|
]
|
|
68
66
|
}
|
|
69
67
|
}
|
|
@@ -79,10 +77,8 @@ Add to your configuration file:
|
|
|
79
77
|
"command": "npx",
|
|
80
78
|
"args": [
|
|
81
79
|
"@fridaplatform-stk/figma2frida-mcp",
|
|
82
|
-
"--
|
|
83
|
-
"
|
|
84
|
-
"--frida-api-token",
|
|
85
|
-
"YOUR_API_TOKEN"
|
|
80
|
+
"--session-token",
|
|
81
|
+
"YOUR_SESSION_TOKEN"
|
|
86
82
|
]
|
|
87
83
|
}
|
|
88
84
|
}
|
|
@@ -93,24 +89,19 @@ Add to your configuration file:
|
|
|
93
89
|
|
|
94
90
|
Restart Claude Desktop, Cursor, or your IDE to load the MCP server.
|
|
95
91
|
|
|
96
|
-
## 🔑 Getting
|
|
92
|
+
## 🔑 Getting Session Tokens
|
|
97
93
|
|
|
98
94
|
To use Figma2Frida, you need:
|
|
99
|
-
- **
|
|
100
|
-
- **Frida API Token** - Authentication token for Frida services
|
|
95
|
+
- **Session token** - Temporary authentication token used by the MCP server
|
|
101
96
|
|
|
102
|
-
### How to Get
|
|
97
|
+
### How to Get a Session Token
|
|
103
98
|
|
|
104
|
-
|
|
99
|
+
Use the **Frida Code Copilot extension** to create/select a project and connect.
|
|
100
|
+
The extension creates a session automatically and writes MCP settings for you.
|
|
105
101
|
|
|
106
|
-
|
|
102
|
+
For external agents (Cursor/Claude/Windsurf), copy the generated config from:
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
- Your organization name
|
|
110
|
-
- Intended use case
|
|
111
|
-
- Team/project information
|
|
112
|
-
|
|
113
|
-
The Frida team will provide your credentials securely.
|
|
104
|
+
`~/Library/Application Support/Code/User/globalStorage/fridaplatform.fridagpt/fridagpt_mcp_settings.json`
|
|
114
105
|
|
|
115
106
|
### 💡 Recommended: Frida Code Copilot Extension
|
|
116
107
|
|
|
@@ -125,7 +116,7 @@ For the best experience, also install the **[Frida Code Copilot VS Code Extensio
|
|
|
125
116
|
|
|
126
117
|
- **Node.js 18+**
|
|
127
118
|
- **Figma Desktop** with MCP enabled
|
|
128
|
-
- **
|
|
119
|
+
- **Valid session token** (generated by Frida Code Copilot extension)
|
|
129
120
|
|
|
130
121
|
## 🚀 Example Usage
|
|
131
122
|
|
|
@@ -148,13 +139,13 @@ The AI will automatically use the Figma2Frida tools to help you.
|
|
|
148
139
|
## 🐛 Troubleshooting
|
|
149
140
|
|
|
150
141
|
**"Authentication failed"**
|
|
151
|
-
→ Verify your
|
|
142
|
+
→ Verify your `--session-token` is valid and not expired
|
|
152
143
|
|
|
153
144
|
**"Not connected to Figma MCP"**
|
|
154
145
|
→ Make sure Figma Desktop is running with MCP enabled
|
|
155
146
|
|
|
156
147
|
**"Missing required argument"**
|
|
157
|
-
→ Check
|
|
148
|
+
→ Check `--session-token` is present in your config
|
|
158
149
|
|
|
159
150
|
**"Rate limit exceeded"**
|
|
160
151
|
→ Wait a few minutes before trying again
|
package/dist/figma2frida.js
CHANGED
|
@@ -28,16 +28,6 @@ var writeToLog = (level, message, ...args) => {
|
|
|
28
28
|
console.log(fullMessage);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
var PUBLIC_PREFIX = "FIGMA2FRIDA:";
|
|
32
|
-
var writePublic = (message) => {
|
|
33
|
-
const line = `${PUBLIC_PREFIX} ${message}
|
|
34
|
-
`;
|
|
35
|
-
if (isStdioMode) {
|
|
36
|
-
process.stderr.write(line);
|
|
37
|
-
} else {
|
|
38
|
-
console.error(line);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
31
|
var logger = {
|
|
42
32
|
debug: (message, ...args) => {
|
|
43
33
|
if (getLogLevel() <= 0 /* DEBUG */) {
|
|
@@ -58,10 +48,6 @@ var logger = {
|
|
|
58
48
|
if (getLogLevel() <= 3 /* ERROR */) {
|
|
59
49
|
writeToLog("ERROR", message, ...args);
|
|
60
50
|
}
|
|
61
|
-
},
|
|
62
|
-
/** User-facing message; always written to stderr with FIGMA2FRIDA: prefix. */
|
|
63
|
-
public: (message) => {
|
|
64
|
-
writePublic(message);
|
|
65
51
|
}
|
|
66
52
|
};
|
|
67
53
|
|
|
@@ -1638,7 +1624,7 @@ var PineconeSearchService = class {
|
|
|
1638
1624
|
input: text,
|
|
1639
1625
|
model: this.fridaEmbeddingModel,
|
|
1640
1626
|
user_id: "pinecone-search",
|
|
1641
|
-
email: "figma2frida_mcp@fridaplatform.com"
|
|
1627
|
+
email: process.env.MCP_USER_EMAIL || "figma2frida_mcp@fridaplatform.com"
|
|
1642
1628
|
})
|
|
1643
1629
|
});
|
|
1644
1630
|
logger.debug(`API response status: ${response.status}`);
|
|
@@ -1888,83 +1874,105 @@ ${match.technical || "No technical documentation available"}
|
|
|
1888
1874
|
};
|
|
1889
1875
|
|
|
1890
1876
|
// src/figma2frida/services/auth/token-validator.ts
|
|
1891
|
-
var VALIDATION_URL = "https://
|
|
1892
|
-
async function
|
|
1893
|
-
logger.info("\u{1F510}
|
|
1877
|
+
var VALIDATION_URL = "https://us-central1-figma2frida-mcp.cloudfunctions.net/validateSession";
|
|
1878
|
+
async function validateSession(sessionToken) {
|
|
1879
|
+
logger.info("\u{1F510} Validating session...");
|
|
1894
1880
|
try {
|
|
1895
1881
|
const response = await fetch(VALIDATION_URL, {
|
|
1896
1882
|
method: "POST",
|
|
1897
1883
|
headers: {
|
|
1898
1884
|
"Content-Type": "application/json"
|
|
1899
1885
|
},
|
|
1900
|
-
body: JSON.stringify({
|
|
1901
|
-
data: {
|
|
1902
|
-
llmopsApiKey,
|
|
1903
|
-
projectId
|
|
1904
|
-
}
|
|
1905
|
-
})
|
|
1886
|
+
body: JSON.stringify({ sessionToken })
|
|
1906
1887
|
});
|
|
1907
|
-
const
|
|
1908
|
-
if (response.ok &&
|
|
1909
|
-
logger.info(
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
const errorStatus = error.status || "UNKNOWN";
|
|
1918
|
-
logger.error(`\u274C MCP login authentication failed: ${errorMessage}`);
|
|
1919
|
-
logger.error(` Status: ${errorStatus}`);
|
|
1920
|
-
if (errorStatus === "RESOURCE_EXHAUSTED") {
|
|
1921
|
-
logger.error(" Rate limit exceeded. Please try again later.");
|
|
1922
|
-
} else if (errorStatus === "NOT_FOUND") {
|
|
1923
|
-
logger.error(" Project not found. Please check your project ID.");
|
|
1924
|
-
} else if (errorStatus === "PERMISSION_DENIED") {
|
|
1925
|
-
logger.error(
|
|
1926
|
-
" Invalid API token. Please check your token and try again."
|
|
1927
|
-
);
|
|
1928
|
-
}
|
|
1929
|
-
throw new Error(
|
|
1930
|
-
`Authentication failed: ${errorMessage} (${errorStatus})`
|
|
1931
|
-
);
|
|
1888
|
+
const data = await response.json();
|
|
1889
|
+
if (response.ok && data.valid === true) {
|
|
1890
|
+
logger.info(`\u2705 Session valid for ${data.email}`);
|
|
1891
|
+
return {
|
|
1892
|
+
valid: true,
|
|
1893
|
+
projectId: data.projectId,
|
|
1894
|
+
llmopsApiKey: data.llmopsApiKey,
|
|
1895
|
+
userId: data.userId,
|
|
1896
|
+
email: data.email
|
|
1897
|
+
};
|
|
1932
1898
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
);
|
|
1936
|
-
throw new Error("Unexpected authentication response format");
|
|
1899
|
+
const errorMessage = data.error || "Unknown error";
|
|
1900
|
+
logger.error(`\u274C Session validation failed: ${errorMessage}`);
|
|
1901
|
+
throw new Error(`Session validation failed: ${errorMessage}`);
|
|
1937
1902
|
} catch (error) {
|
|
1938
|
-
if (error instanceof Error && error.message.startsWith("
|
|
1903
|
+
if (error instanceof Error && error.message.startsWith("Session validation failed:")) {
|
|
1939
1904
|
throw error;
|
|
1940
1905
|
}
|
|
1941
|
-
logger.error(
|
|
1942
|
-
"\u274C Failed to authenticate MCP login:",
|
|
1943
|
-
error instanceof Error ? error.message : String(error)
|
|
1944
|
-
);
|
|
1906
|
+
logger.error("\u274C Failed to validate session:", error instanceof Error ? error.message : String(error));
|
|
1945
1907
|
if (error instanceof Error) {
|
|
1946
1908
|
if (error.message.includes("fetch failed") || error.message.includes("ECONNREFUSED")) {
|
|
1947
|
-
logger.error(" Network error: Could not reach validation service.");
|
|
1948
|
-
logger.error(" Please check your internet connection and try again.");
|
|
1949
1909
|
throw new Error("Network error: Could not reach validation service");
|
|
1950
1910
|
} else if (error.message.includes("timeout")) {
|
|
1951
|
-
|
|
1952
|
-
" Request timeout: Validation service did not respond in time."
|
|
1953
|
-
);
|
|
1954
|
-
logger.error(" Please try again later.");
|
|
1955
|
-
throw new Error(
|
|
1956
|
-
"Request timeout: Validation service did not respond in time"
|
|
1957
|
-
);
|
|
1911
|
+
throw new Error("Request timeout: Validation service did not respond in time");
|
|
1958
1912
|
}
|
|
1959
1913
|
}
|
|
1960
|
-
throw new Error(
|
|
1961
|
-
`Authentication failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1962
|
-
);
|
|
1914
|
+
throw new Error(`Session validation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1963
1915
|
}
|
|
1964
1916
|
}
|
|
1965
1917
|
|
|
1966
1918
|
// src/figma2frida/services/frida/frida-client.ts
|
|
1967
1919
|
import "dotenv/config";
|
|
1920
|
+
function extractFromResponsesApiOutput(data) {
|
|
1921
|
+
const output = data.output;
|
|
1922
|
+
if (!Array.isArray(output)) {
|
|
1923
|
+
return null;
|
|
1924
|
+
}
|
|
1925
|
+
const textParts = [];
|
|
1926
|
+
for (const item of output) {
|
|
1927
|
+
if (!item || typeof item !== "object") {
|
|
1928
|
+
continue;
|
|
1929
|
+
}
|
|
1930
|
+
const o = item;
|
|
1931
|
+
if (o.type !== "message") {
|
|
1932
|
+
continue;
|
|
1933
|
+
}
|
|
1934
|
+
const content = o.content;
|
|
1935
|
+
if (!Array.isArray(content)) {
|
|
1936
|
+
continue;
|
|
1937
|
+
}
|
|
1938
|
+
for (const block of content) {
|
|
1939
|
+
if (!block || typeof block !== "object") {
|
|
1940
|
+
continue;
|
|
1941
|
+
}
|
|
1942
|
+
const b = block;
|
|
1943
|
+
if (b.type === "output_text" && typeof b.text === "string" && b.text.length > 0) {
|
|
1944
|
+
textParts.push(b.text);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
const joined = textParts.join("\n").trim();
|
|
1949
|
+
if (!joined) {
|
|
1950
|
+
return null;
|
|
1951
|
+
}
|
|
1952
|
+
const parseSource = data.object === "response" ? "response.output[].message.output_text" : "output[].message.output_text";
|
|
1953
|
+
return { answer: joined, parseSource };
|
|
1954
|
+
}
|
|
1955
|
+
function parseFridaAnswer(data) {
|
|
1956
|
+
if (typeof data.response === "string" && data.response) {
|
|
1957
|
+
return { answer: data.response, parseSource: "response" };
|
|
1958
|
+
}
|
|
1959
|
+
const structured = extractFromResponsesApiOutput(data);
|
|
1960
|
+
if (structured) {
|
|
1961
|
+
return structured;
|
|
1962
|
+
}
|
|
1963
|
+
if (typeof data.output === "string" && data.output) {
|
|
1964
|
+
return { answer: data.output, parseSource: "output" };
|
|
1965
|
+
}
|
|
1966
|
+
const choices = data.choices;
|
|
1967
|
+
const msg = choices?.[0]?.message;
|
|
1968
|
+
if (msg && typeof msg.content === "string" && msg.content) {
|
|
1969
|
+
return { answer: msg.content, parseSource: "choices[0].message.content" };
|
|
1970
|
+
}
|
|
1971
|
+
if (typeof data.content === "string" && data.content) {
|
|
1972
|
+
return { answer: data.content, parseSource: "content" };
|
|
1973
|
+
}
|
|
1974
|
+
return { answer: JSON.stringify(data), parseSource: "fallback_json" };
|
|
1975
|
+
}
|
|
1968
1976
|
var FridaClient = class {
|
|
1969
1977
|
apiKey;
|
|
1970
1978
|
apiUrl;
|
|
@@ -2078,7 +2086,7 @@ Example format: tag1, tag2, tag3
|
|
|
2078
2086
|
input: prompt,
|
|
2079
2087
|
max_tokens: this.maxTokens,
|
|
2080
2088
|
stream: false,
|
|
2081
|
-
email: "
|
|
2089
|
+
email: process.env.MCP_USER_EMAIL || "figma2frida_mcp@fridaplatform.com"
|
|
2082
2090
|
})
|
|
2083
2091
|
});
|
|
2084
2092
|
const fetchTime = Date.now() - startTime;
|
|
@@ -2088,18 +2096,19 @@ Example format: tag1, tag2, tag3
|
|
|
2088
2096
|
throw new Error(`API Error: ${response.status} ${response.statusText}`);
|
|
2089
2097
|
}
|
|
2090
2098
|
const data = await response.json();
|
|
2091
|
-
|
|
2092
|
-
const answer = data.response || data.output || data.choices?.[0]?.message?.content || data.content || JSON.stringify(data);
|
|
2099
|
+
const { answer, parseSource } = parseFridaAnswer(data);
|
|
2093
2100
|
const tokensUsed = data.usage?.total_tokens || null;
|
|
2094
|
-
const
|
|
2095
|
-
logger.debug(
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
logger.debug(
|
|
2101
|
+
const answerPreview = answer.replace(/\s+/g, " ").slice(0, 200);
|
|
2102
|
+
logger.debug(
|
|
2103
|
+
`Frida answer preview (ask): "${answerPreview}" (from "${parseSource}")`
|
|
2104
|
+
);
|
|
2105
|
+
logger.debug(
|
|
2106
|
+
`Frida response OK (ask): HTTP ${response.status} in ${fetchTime}ms \u2014 parsed from "${parseSource}", ${answer.length} chars, tokens=${tokensUsed ?? "n/a"}`
|
|
2107
|
+
);
|
|
2099
2108
|
return {
|
|
2100
2109
|
success: true,
|
|
2101
2110
|
error: null,
|
|
2102
|
-
response:
|
|
2111
|
+
response: answer,
|
|
2103
2112
|
metadata: {
|
|
2104
2113
|
model: this.model,
|
|
2105
2114
|
tokensUsed
|
|
@@ -2156,7 +2165,7 @@ Example format: tag1, tag2, tag3
|
|
|
2156
2165
|
input: prompt,
|
|
2157
2166
|
max_tokens: this.maxTokens,
|
|
2158
2167
|
stream: false,
|
|
2159
|
-
email: "
|
|
2168
|
+
email: process.env.MCP_USER_EMAIL || "figma2frida_mcp@fridaplatform.com"
|
|
2160
2169
|
})
|
|
2161
2170
|
});
|
|
2162
2171
|
const fetchTime = Date.now() - startTime;
|
|
@@ -2166,18 +2175,19 @@ Example format: tag1, tag2, tag3
|
|
|
2166
2175
|
throw new Error(`API Error: ${response.status} ${response.statusText}`);
|
|
2167
2176
|
}
|
|
2168
2177
|
const data = await response.json();
|
|
2169
|
-
|
|
2170
|
-
const answer = data.response || data.output || data.choices?.[0]?.message?.content || data.content || JSON.stringify(data);
|
|
2178
|
+
const { answer, parseSource } = parseFridaAnswer(data);
|
|
2171
2179
|
const tokensUsed = data.usage?.total_tokens || null;
|
|
2172
|
-
const
|
|
2173
|
-
logger.debug(
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
logger.debug(
|
|
2180
|
+
const answerPreview = answer.replace(/\s+/g, " ").slice(0, 200);
|
|
2181
|
+
logger.debug(
|
|
2182
|
+
`Frida answer preview (filter): "${answerPreview}" (from "${parseSource}")`
|
|
2183
|
+
);
|
|
2184
|
+
logger.debug(
|
|
2185
|
+
`Frida response OK (filter): HTTP ${response.status} in ${fetchTime}ms \u2014 parsed from "${parseSource}", ${answer.length} chars, tokens=${tokensUsed ?? "n/a"}`
|
|
2186
|
+
);
|
|
2177
2187
|
return {
|
|
2178
2188
|
success: true,
|
|
2179
2189
|
error: null,
|
|
2180
|
-
response:
|
|
2190
|
+
response: answer,
|
|
2181
2191
|
metadata: {
|
|
2182
2192
|
model: this.model,
|
|
2183
2193
|
tokensUsed
|
|
@@ -2294,12 +2304,12 @@ logger.debug("Loading hardcoded configuration...");
|
|
|
2294
2304
|
process.env.PINECONE_INDEX = "figma2frida";
|
|
2295
2305
|
process.env.PINECONE_MIN_SCORE = "0.4";
|
|
2296
2306
|
process.env.PINECONE_TOP_K = "12";
|
|
2297
|
-
process.env.FRIDA_PINECONE_PROXY_URL = "https://frida
|
|
2298
|
-
process.env.FRIDA_API_URL = "https://frida
|
|
2299
|
-
process.env.FRIDA_EMBEDDING_URL = "https://frida
|
|
2307
|
+
process.env.FRIDA_PINECONE_PROXY_URL = "https://azf-frida-pinecone-proxy.azurewebsites.net";
|
|
2308
|
+
process.env.FRIDA_API_URL = "https://frida-llm-api-dev.azurewebsites.net/v1/responses";
|
|
2309
|
+
process.env.FRIDA_EMBEDDING_URL = "https://frida-llm-api.azurewebsites.net/v1/embeddings";
|
|
2300
2310
|
process.env.FRIDA_EMBEDDING_MODEL = "text-embedding-ada-002";
|
|
2301
2311
|
process.env.FRIDA_MODEL = "gpt-5.1-codex";
|
|
2302
|
-
process.env.FRIDA_MAX_TOKENS = "
|
|
2312
|
+
process.env.FRIDA_MAX_TOKENS = "12000";
|
|
2303
2313
|
process.env.HTTP_STREAM = "false";
|
|
2304
2314
|
process.env.PORT = "8080";
|
|
2305
2315
|
logger.debug(`PINECONE_INDEX: ${process.env.PINECONE_INDEX}`);
|
|
@@ -2314,35 +2324,28 @@ logger.debug(`FRIDA_MAX_TOKENS: ${process.env.FRIDA_MAX_TOKENS}`);
|
|
|
2314
2324
|
logger.debug(`HTTP_STREAM: ${process.env.HTTP_STREAM}`);
|
|
2315
2325
|
logger.debug(`PORT: ${process.env.PORT}`);
|
|
2316
2326
|
logger.info("Configuration loaded");
|
|
2317
|
-
var argv = yargs(hideBin(process.argv)).option("
|
|
2318
|
-
type: "string",
|
|
2319
|
-
description: "Pinecone namespace (required for component search)",
|
|
2320
|
-
demandOption: true
|
|
2321
|
-
}).option("frida-api-token", {
|
|
2327
|
+
var argv = yargs(hideBin(process.argv)).option("session-token", {
|
|
2322
2328
|
type: "string",
|
|
2323
|
-
description: "
|
|
2329
|
+
description: "Session token for authentication",
|
|
2324
2330
|
demandOption: true
|
|
2325
2331
|
}).parseSync();
|
|
2326
|
-
var
|
|
2327
|
-
if (!
|
|
2328
|
-
logger.error("\u274C SHUTDOWN: Invalid or missing --
|
|
2329
|
-
process.exit(1);
|
|
2330
|
-
}
|
|
2331
|
-
logger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE} (from CLI)`);
|
|
2332
|
-
var FRIDA_TOKEN = argv.fridaApiToken?.trim();
|
|
2333
|
-
if (!FRIDA_TOKEN || FRIDA_TOKEN === "" || FRIDA_TOKEN === "your_api_token_here") {
|
|
2334
|
-
logger.error("\u274C SHUTDOWN: Invalid or missing --frida-api-token. This token is required for authentication.");
|
|
2332
|
+
var SESSION_TOKEN = argv.sessionToken?.trim();
|
|
2333
|
+
if (!SESSION_TOKEN || SESSION_TOKEN === "") {
|
|
2334
|
+
logger.error("\u274C SHUTDOWN: Invalid or missing --session-token.");
|
|
2335
2335
|
process.exit(1);
|
|
2336
2336
|
}
|
|
2337
|
-
|
|
2338
|
-
logger.debug(`FRIDA_API_TOKEN: ${FRIDA_TOKEN.substring(0, 8)}... (hidden)`);
|
|
2337
|
+
var PINECONE_NAMESPACE = "";
|
|
2339
2338
|
try {
|
|
2340
|
-
await
|
|
2339
|
+
const session = await validateSession(SESSION_TOKEN);
|
|
2340
|
+
PINECONE_NAMESPACE = session.projectId;
|
|
2341
|
+
process.env.FRIDA_BEARER_TOKEN = session.llmopsApiKey;
|
|
2342
|
+
process.env.MCP_USER_EMAIL = session.email;
|
|
2343
|
+
process.env.MCP_USER_ID = session.userId;
|
|
2344
|
+
logger.info(`Authenticated as ${session.email}`);
|
|
2345
|
+
logger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE}`);
|
|
2346
|
+
logger.debug(`FRIDA_BEARER_TOKEN: ${session.llmopsApiKey.substring(0, 8)}... (hidden)`);
|
|
2341
2347
|
} catch (error) {
|
|
2342
|
-
logger.error("\u274C SHUTDOWN:
|
|
2343
|
-
logger.public(
|
|
2344
|
-
`\u274C ${error instanceof Error ? error.message : String(error)}`
|
|
2345
|
-
);
|
|
2348
|
+
logger.error("\u274C SHUTDOWN: Session validation failed. MCP server cannot start.");
|
|
2346
2349
|
process.exit(1);
|
|
2347
2350
|
}
|
|
2348
2351
|
var HTTP_STREAM = process.env.HTTP_STREAM === "true" || process.env.HTTP_STREAM === "1";
|
|
@@ -2670,7 +2673,7 @@ if (HTTP_STREAM) {
|
|
|
2670
2673
|
});
|
|
2671
2674
|
logger.info("Figma Proxy MCP Server running on HTTP Stream!");
|
|
2672
2675
|
logger.info(`Endpoint: http://localhost:${PORT}/mcp`);
|
|
2673
|
-
logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE
|
|
2676
|
+
logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE}`);
|
|
2674
2677
|
logger.debug(`
|
|
2675
2678
|
Test with curl:
|
|
2676
2679
|
curl -X POST http://localhost:${PORT}/mcp \\
|