@locofy/mcp 1.0.8 → 1.0.10

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,7 @@
1
+ const isDev = process.env.IS_DEV === 'true';
2
+ export const MIXPANEL_PROJECT_TOKEN = isDev
3
+ ? '77d8775b23ede44f6f58a6a0c677e881'
4
+ : '6ba4b43a52dcbc80ee759b59f2dc8c5f';
5
+ export const MIXPANEL_PROXY_DOMAIN = isDev
6
+ ? 'https://event-tracking.locofy.dev/events/mixpanel'
7
+ : 'https://events.locofy.ai/events/mixpanel';
@@ -3,6 +3,7 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import axios from 'axios';
5
5
  import { getProjectID } from '../helpers/helpers.js';
6
+ import { track } from '../utils/analytics.js';
6
7
  /**
7
8
  * PullComponents tool
8
9
  * - Returns a hardcoded representation of a directory structure
@@ -31,6 +32,7 @@ export async function runPullComponentsTool(args) {
31
32
  try {
32
33
  const result = await fetchDirectoryStructure(componentNames, projectID, personalAccessToken);
33
34
  if (result.success) {
35
+ const userID = result.user_id;
34
36
  // Prepend workspacePath to all filePath attributes
35
37
  prepareFilePaths(result.data, workspacePath);
36
38
  // Download and save any files referenced in the response
@@ -39,10 +41,12 @@ export async function runPullComponentsTool(args) {
39
41
  await checkForCodeChanges(result.data);
40
42
  // clean the directory structure
41
43
  const cleanedResult = processDirectoryStructure(result.data);
42
- // write resultJSON to a file
43
- if (process.env.DEBUG_MODE === 'true') {
44
- fs.writeFileSync('result.json', JSON.stringify(cleanedResult, null, 2));
45
- }
44
+ track('mcp_execute_tool_e', {
45
+ tool_name: pullComponentsToolName,
46
+ project_id: projectID,
47
+ user_id: userID,
48
+ source: 'cursor', // TODO: update it when we release vscode extension
49
+ });
46
50
  return {
47
51
  content: [
48
52
  {
@@ -81,11 +85,10 @@ export async function runPullComponentsTool(args) {
81
85
  }
82
86
  async function fetchDirectoryStructure(componentNames, projectID, personalAccessToken) {
83
87
  const encodedNames = componentNames.map(name => encodeURIComponent(name)).join(',');
84
- // let baseURL = 'https://codegen-api.locofy.ai/mcp/generators/';
85
- // if (process.env.IS_DEV === 'true') {
86
- // baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
87
- // }
88
- const baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
88
+ let baseURL = 'https://codegen-api.locofy.ai/mcp/generators/';
89
+ if (process.env.IS_DEV === 'true') {
90
+ baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
91
+ }
89
92
  const url = baseURL + projectID + '?name=' + encodedNames;
90
93
  const headers = {
91
94
  'Accept': '*/*',
@@ -112,7 +115,8 @@ async function fetchDirectoryStructure(componentNames, projectID, personalAccess
112
115
  }
113
116
  return {
114
117
  success: true,
115
- data: response.data.directoryTree
118
+ data: response.data.directoryTree,
119
+ user_id: response.data.user_id
116
120
  };
117
121
  }
118
122
  catch (error) {
@@ -3,6 +3,7 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import axios from 'axios';
5
5
  import { getProjectID } from '../helpers/helpers.js';
6
+ import { track } from '../utils/analytics.js';
6
7
  /**
7
8
  * PullFiles tool
8
9
  * - Returns a hardcoded representation of a directory structure
@@ -31,6 +32,7 @@ export async function runPullFilesTool(args) {
31
32
  try {
32
33
  const result = await fetchDirectoryStructure(fileNames, projectID, personalAccessToken);
33
34
  if (result.success) {
35
+ const userID = result.user_id;
34
36
  // Prepend workspacePath to all filePath attributes
35
37
  prepareFilePaths(result.data, workspacePath);
36
38
  // Download and save any files referenced in the response
@@ -39,10 +41,12 @@ export async function runPullFilesTool(args) {
39
41
  await checkForCodeChanges(result.data);
40
42
  // clean the directory structure
41
43
  const cleanedResult = processDirectoryStructure(result.data);
42
- // write resultJSON to a file
43
- if (process.env.DEBUG_MODE === 'true') {
44
- fs.writeFileSync('result.json', JSON.stringify(cleanedResult, null, 2));
45
- }
44
+ track('mcp_execute_tool_e', {
45
+ tool_name: pullFilesToolDescription,
46
+ project_id: projectID,
47
+ user_id: userID,
48
+ source: 'cursor', // TODO: update it when we release vscode extension
49
+ });
46
50
  return {
47
51
  content: [
48
52
  {
@@ -81,11 +85,10 @@ export async function runPullFilesTool(args) {
81
85
  }
82
86
  async function fetchDirectoryStructure(fileNames, projectID, personalAccessToken) {
83
87
  const encodedNames = fileNames.map(name => encodeURIComponent(name)).join(',');
84
- // let baseURL = 'https://codegen-api.locofy.ai/mcp/generators/';
85
- // if (process.env.IS_DEV === 'true') {
86
- // baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
87
- // }
88
- const baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
88
+ let baseURL = 'https://codegen-api.locofy.ai/mcp/generators/';
89
+ if (process.env.IS_DEV === 'true') {
90
+ baseURL = 'https://codegen-api.locofy.dev/mcp/generators/';
91
+ }
89
92
  const url = baseURL + projectID + '?name=' + encodedNames;
90
93
  const headers = {
91
94
  'Accept': '*/*',
@@ -112,7 +115,8 @@ async function fetchDirectoryStructure(fileNames, projectID, personalAccessToken
112
115
  }
113
116
  return {
114
117
  success: true,
115
- data: response.data.directoryTree
118
+ data: response.data.directoryTree,
119
+ user_id: response.data.user_id
116
120
  };
117
121
  }
118
122
  catch (error) {
@@ -0,0 +1,47 @@
1
+ import { MIXPANEL_PROJECT_TOKEN, MIXPANEL_PROXY_DOMAIN } from '../constants.js';
2
+ export function track(event, props = {}) {
3
+ if (process.env.NODE_ENV === 'test' || process.env.IS_TEST === 'true') {
4
+ console.log('Analytics disabled: NODE_ENV is test or IS_TEST is true');
5
+ return;
6
+ }
7
+ if (!MIXPANEL_PROJECT_TOKEN || !MIXPANEL_PROXY_DOMAIN) {
8
+ console.log('Analytics disabled: MIXPANEL_PROJECT_TOKEN or MIXPANEL_PROXY_DOMAIN not set');
9
+ return;
10
+ }
11
+ try {
12
+ // Create the Mixpanel-compatible event object
13
+ const eventObject = {
14
+ event: event,
15
+ properties: {
16
+ ...props,
17
+ token: MIXPANEL_PROJECT_TOKEN,
18
+ time: Math.floor(Date.now() / 1000),
19
+ distinct_id: props.user_id || 'anonymous',
20
+ }
21
+ };
22
+ const encodedData = Buffer.from(JSON.stringify([eventObject])).toString('base64');
23
+ console.log(`Analytics: tracking event '${event}'`);
24
+ fetch(MIXPANEL_PROXY_DOMAIN + '/track/?data=' + encodedData, {
25
+ method: 'GET',
26
+ headers: {
27
+ 'Accept': 'text/plain'
28
+ }
29
+ })
30
+ .then(response => {
31
+ if (response.ok) { // Status code in the range 200-299
32
+ if (process.env.IS_DEV === 'true') {
33
+ console.log(`Analytics: successfully sent event '${event}' with status ${response.status}`);
34
+ }
35
+ }
36
+ else {
37
+ console.error(`Error sending event '${event}' to Mixpanel:`, response.statusText);
38
+ }
39
+ })
40
+ .catch(error => {
41
+ console.error(`Error sending event '${event}' to Mixpanel:`, error);
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error(`Error preparing event '${event}' for tracking:`, error);
46
+ }
47
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locofy/mcp",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Locofy MCP Server with Cursor",
5
5
  "keywords": [
6
6
  "figma",