@tmhs/mobile-mcp 0.2.0 → 0.4.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/index.js CHANGED
@@ -7,9 +7,15 @@ import { register as registerRunOnDevice } from "./tools/runOnDevice.js";
7
7
  import { register as registerGenerateScreen } from "./tools/generateScreen.js";
8
8
  import { register as registerGenerateComponent } from "./tools/generateComponent.js";
9
9
  import { register as registerInstallDependency } from "./tools/installDependency.js";
10
+ import { register as registerAddPermission } from "./tools/addPermission.js";
11
+ import { register as registerIntegrateAI } from "./tools/integrateAI.js";
12
+ import { register as registerCheckBuildHealth } from "./tools/checkBuildHealth.js";
13
+ import { register as registerAddPushNotifications } from "./tools/addPushNotifications.js";
14
+ import { register as registerConfigureDeepLinks } from "./tools/configureDeepLinks.js";
15
+ import { register as registerResetDevEnvironment } from "./tools/resetDevEnvironment.js";
10
16
  const server = new McpServer({
11
17
  name: "mobile-mcp",
12
- version: "0.2.0",
18
+ version: "0.4.0",
13
19
  });
14
20
  registerCheckDevEnvironment(server);
15
21
  registerScaffoldProject(server);
@@ -17,6 +23,12 @@ registerRunOnDevice(server);
17
23
  registerGenerateScreen(server);
18
24
  registerGenerateComponent(server);
19
25
  registerInstallDependency(server);
26
+ registerAddPermission(server);
27
+ registerIntegrateAI(server);
28
+ registerCheckBuildHealth(server);
29
+ registerAddPushNotifications(server);
30
+ registerConfigureDeepLinks(server);
31
+ registerResetDevEnvironment(server);
20
32
  async function main() {
21
33
  const transport = new StdioServerTransport();
22
34
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAErF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,2BAA2B,CAAC,MAAM,CAAC,CAAC;AACpC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,QAAQ,IAAI,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAEzF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,2BAA2B,CAAC,MAAM,CAAC,CAAC;AACpC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,4BAA4B,CAAC,MAAM,CAAC,CAAC;AACrC,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACnC,2BAA2B,CAAC,MAAM,CAAC,CAAC;AAEpC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=addPermission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addPermission.d.ts","sourceRoot":"","sources":["../../src/tools/addPermission.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4EzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8EhD"}
@@ -0,0 +1,124 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { textResponse, errorResponse } from "../types.js";
5
+ const PERMISSION_CONFIGS = {
6
+ camera: {
7
+ package: "expo-camera",
8
+ plugin: "expo-camera",
9
+ keys: {
10
+ cameraPermission: "This app uses the camera to take photos and videos.",
11
+ },
12
+ },
13
+ location: {
14
+ package: "expo-location",
15
+ plugin: "expo-location",
16
+ keys: {
17
+ locationWhenInUsePermission: "This app uses your location to provide location-based features.",
18
+ },
19
+ },
20
+ contacts: {
21
+ package: "expo-contacts",
22
+ plugin: "expo-contacts",
23
+ keys: {
24
+ contactsPermission: "This app accesses your contacts to help you connect with friends.",
25
+ },
26
+ },
27
+ "media-library": {
28
+ package: "expo-media-library",
29
+ plugin: "expo-media-library",
30
+ keys: {
31
+ photosPermission: "This app accesses your photo library to select photos.",
32
+ savePhotosPermission: "This app saves photos to your library.",
33
+ },
34
+ },
35
+ notifications: {
36
+ package: "expo-notifications",
37
+ plugin: "expo-notifications",
38
+ keys: {},
39
+ },
40
+ microphone: {
41
+ package: "expo-av",
42
+ plugin: "expo-av",
43
+ keys: {
44
+ microphonePermission: "This app uses the microphone for audio recording.",
45
+ },
46
+ },
47
+ };
48
+ const inputSchema = {
49
+ permission_type: z
50
+ .enum([
51
+ "camera",
52
+ "location",
53
+ "contacts",
54
+ "media-library",
55
+ "notifications",
56
+ "microphone",
57
+ ])
58
+ .describe("Type of permission to add"),
59
+ rationale: z
60
+ .string()
61
+ .optional()
62
+ .describe("Custom iOS usage description string. If not provided, a sensible default is used."),
63
+ project_path: z
64
+ .string()
65
+ .optional()
66
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
67
+ };
68
+ export function register(server) {
69
+ server.tool("mobile_addPermission", "Add a platform permission to an Expo project with iOS rationale string in app.json.", inputSchema, async (args) => {
70
+ try {
71
+ const root = args.project_path || process.cwd();
72
+ const appJsonPath = join(root, "app.json");
73
+ if (!existsSync(appJsonPath)) {
74
+ return errorResponse(new Error(`No app.json found at ${root}. Is this an Expo project root?`));
75
+ }
76
+ const config = PERMISSION_CONFIGS[args.permission_type];
77
+ if (!config) {
78
+ return errorResponse(new Error(`Unknown permission type: ${args.permission_type}`));
79
+ }
80
+ const appJson = JSON.parse(readFileSync(appJsonPath, "utf-8"));
81
+ if (!appJson.expo) {
82
+ appJson.expo = {};
83
+ }
84
+ if (!appJson.expo.plugins) {
85
+ appJson.expo.plugins = [];
86
+ }
87
+ const existingIndex = appJson.expo.plugins.findIndex((p) => (Array.isArray(p) && p[0] === config.plugin) || p === config.plugin);
88
+ const pluginKeys = { ...config.keys };
89
+ if (args.rationale) {
90
+ const firstKey = Object.keys(pluginKeys)[0];
91
+ if (firstKey) {
92
+ pluginKeys[firstKey] = args.rationale;
93
+ }
94
+ }
95
+ const pluginEntry = Object.keys(pluginKeys).length > 0
96
+ ? [config.plugin, pluginKeys]
97
+ : config.plugin;
98
+ if (existingIndex >= 0) {
99
+ appJson.expo.plugins[existingIndex] = pluginEntry;
100
+ }
101
+ else {
102
+ appJson.expo.plugins.push(pluginEntry);
103
+ }
104
+ writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + "\n");
105
+ const result = {
106
+ success: true,
107
+ permission_type: args.permission_type,
108
+ package: config.package,
109
+ plugin_added: pluginEntry,
110
+ app_json_updated: appJsonPath,
111
+ next_steps: [
112
+ `Install the package: npx expo install ${config.package}`,
113
+ "Run npx expo prebuild to regenerate native projects",
114
+ "Test on a physical device (permissions behave differently on simulators)",
115
+ ],
116
+ };
117
+ return textResponse(JSON.stringify(result, null, 2));
118
+ }
119
+ catch (err) {
120
+ return errorResponse(err);
121
+ }
122
+ });
123
+ }
124
+ //# sourceMappingURL=addPermission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addPermission.js","sourceRoot":"","sources":["../../src/tools/addPermission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=addPushNotifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addPushNotifications.d.ts","sourceRoot":"","sources":["../../src/tools/addPushNotifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4DzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2EhD"}
@@ -0,0 +1,120 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { textResponse, errorResponse } from "../types.js";
5
+ const inputSchema = {
6
+ project_path: z
7
+ .string()
8
+ .optional()
9
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
10
+ channel_name: z
11
+ .string()
12
+ .optional()
13
+ .default("default")
14
+ .describe("Android notification channel name"),
15
+ };
16
+ const NOTIFICATION_HANDLER_CODE = `import * as Notifications from "expo-notifications";
17
+ import * as Device from "expo-device";
18
+ import Constants from "expo-constants";
19
+ import { Platform } from "react-native";
20
+
21
+ Notifications.setNotificationHandler({
22
+ handleNotification: async () => ({
23
+ shouldShowAlert: true,
24
+ shouldPlaySound: true,
25
+ shouldSetBadge: true,
26
+ }),
27
+ });
28
+
29
+ export async function registerForPushNotifications(): Promise<string | null> {
30
+ if (!Device.isDevice) {
31
+ console.warn("Push notifications require a physical device");
32
+ return null;
33
+ }
34
+
35
+ const { status: existing } = await Notifications.getPermissionsAsync();
36
+ let finalStatus = existing;
37
+
38
+ if (existing !== "granted") {
39
+ const { status } = await Notifications.requestPermissionsAsync();
40
+ finalStatus = status;
41
+ }
42
+
43
+ if (finalStatus !== "granted") {
44
+ return null;
45
+ }
46
+
47
+ if (Platform.OS === "android") {
48
+ await Notifications.setNotificationChannelAsync("default", {
49
+ name: "Default",
50
+ importance: Notifications.AndroidImportance.MAX,
51
+ vibrationPattern: [0, 250, 250, 250],
52
+ });
53
+ }
54
+
55
+ const projectId = Constants.expoConfig?.extra?.eas?.projectId;
56
+ const token = await Notifications.getExpoPushTokenAsync({ projectId });
57
+ return token.data;
58
+ }
59
+ `;
60
+ export function register(server) {
61
+ server.tool("mobile_addPushNotifications", "Wire up push notifications in an Expo project: add plugin to app.json, create notification handler utility, configure Android channel.", inputSchema, async (args) => {
62
+ try {
63
+ const root = args.project_path || process.cwd();
64
+ const appJsonPath = join(root, "app.json");
65
+ if (!existsSync(appJsonPath)) {
66
+ return errorResponse(new Error(`No app.json found at ${root}. Is this an Expo project?`));
67
+ }
68
+ const appJson = JSON.parse(readFileSync(appJsonPath, "utf-8"));
69
+ if (!appJson.expo)
70
+ appJson.expo = {};
71
+ if (!appJson.expo.plugins)
72
+ appJson.expo.plugins = [];
73
+ const hasPlugin = appJson.expo.plugins.some((p) => (Array.isArray(p) && p[0] === "expo-notifications") ||
74
+ p === "expo-notifications");
75
+ if (!hasPlugin) {
76
+ appJson.expo.plugins.push([
77
+ "expo-notifications",
78
+ {
79
+ icon: "./assets/notification-icon.png",
80
+ color: "#ffffff",
81
+ defaultChannel: args.channel_name,
82
+ },
83
+ ]);
84
+ }
85
+ if (!appJson.expo.android)
86
+ appJson.expo.android = {};
87
+ appJson.expo.android.useNextNotificationsApi = true;
88
+ writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + "\n");
89
+ const libDir = join(root, "lib");
90
+ mkdirSync(libDir, { recursive: true });
91
+ const handlerFile = join(libDir, "notifications.ts");
92
+ let handlerCreated = false;
93
+ if (!existsSync(handlerFile)) {
94
+ writeFileSync(handlerFile, NOTIFICATION_HANDLER_CODE);
95
+ handlerCreated = true;
96
+ }
97
+ const result = {
98
+ success: true,
99
+ app_json_updated: true,
100
+ notification_plugin_added: !hasPlugin,
101
+ handler_file: handlerCreated ? handlerFile : null,
102
+ channel_name: args.channel_name,
103
+ next_steps: [
104
+ "Install packages: npx expo install expo-notifications expo-device expo-constants",
105
+ "Run npx expo prebuild to regenerate native projects",
106
+ handlerCreated
107
+ ? "Import registerForPushNotifications from lib/notifications.ts in your root layout"
108
+ : "Notification handler already exists",
109
+ "Create assets/notification-icon.png (96x96, white on transparent, Android only)",
110
+ "Send push token to your backend after registration",
111
+ ],
112
+ };
113
+ return textResponse(JSON.stringify(result, null, 2));
114
+ }
115
+ catch (err) {
116
+ return errorResponse(err);
117
+ }
118
+ });
119
+ }
120
+ //# sourceMappingURL=addPushNotifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addPushNotifications.js","sourceRoot":"","sources":["../../src/tools/addPushNotifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=checkBuildHealth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkBuildHealth.d.ts","sourceRoot":"","sources":["../../src/tools/checkBuildHealth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6MzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyChD"}
@@ -0,0 +1,215 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { execSync } from "node:child_process";
4
+ import { join } from "node:path";
5
+ import { textResponse, errorResponse } from "../types.js";
6
+ const inputSchema = {
7
+ project_path: z
8
+ .string()
9
+ .optional()
10
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
11
+ platform: z
12
+ .enum(["ios", "android", "both"])
13
+ .optional()
14
+ .default("both")
15
+ .describe("Platform to check build health for"),
16
+ };
17
+ function checkAppJson(root) {
18
+ const appJsonPath = join(root, "app.json");
19
+ if (!existsSync(appJsonPath)) {
20
+ return { name: "app.json", status: "fail", message: "app.json not found" };
21
+ }
22
+ try {
23
+ const content = readFileSync(appJsonPath, "utf-8");
24
+ const config = JSON.parse(content);
25
+ if (!config.expo) {
26
+ return {
27
+ name: "app.json",
28
+ status: "fail",
29
+ message: 'app.json missing "expo" key',
30
+ };
31
+ }
32
+ const warnings = [];
33
+ if (!config.expo.name)
34
+ warnings.push("missing expo.name");
35
+ if (!config.expo.slug)
36
+ warnings.push("missing expo.slug");
37
+ if (!config.expo.version)
38
+ warnings.push("missing expo.version");
39
+ if (!config.expo.scheme)
40
+ warnings.push("missing expo.scheme (needed for deep linking)");
41
+ if (warnings.length > 0) {
42
+ return {
43
+ name: "app.json",
44
+ status: "warn",
45
+ message: `Valid JSON but: ${warnings.join(", ")}`,
46
+ };
47
+ }
48
+ return { name: "app.json", status: "pass", message: "Valid configuration" };
49
+ }
50
+ catch (e) {
51
+ return {
52
+ name: "app.json",
53
+ status: "fail",
54
+ message: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}`,
55
+ };
56
+ }
57
+ }
58
+ function checkPackageJson(root) {
59
+ const pkgPath = join(root, "package.json");
60
+ if (!existsSync(pkgPath)) {
61
+ return {
62
+ name: "package.json",
63
+ status: "fail",
64
+ message: "package.json not found",
65
+ };
66
+ }
67
+ try {
68
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
69
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
70
+ if (!deps.expo) {
71
+ return {
72
+ name: "package.json",
73
+ status: "fail",
74
+ message: "expo is not listed as a dependency",
75
+ };
76
+ }
77
+ return {
78
+ name: "package.json",
79
+ status: "pass",
80
+ message: `Expo ${deps.expo} detected`,
81
+ };
82
+ }
83
+ catch (e) {
84
+ return {
85
+ name: "package.json",
86
+ status: "fail",
87
+ message: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}`,
88
+ };
89
+ }
90
+ }
91
+ function checkNodeModules(root) {
92
+ if (!existsSync(join(root, "node_modules"))) {
93
+ return {
94
+ name: "node_modules",
95
+ status: "fail",
96
+ message: 'node_modules not found. Run "npm install".',
97
+ };
98
+ }
99
+ return { name: "node_modules", status: "pass", message: "Installed" };
100
+ }
101
+ function checkTypeScript(root) {
102
+ const tsconfigPath = join(root, "tsconfig.json");
103
+ if (!existsSync(tsconfigPath)) {
104
+ return {
105
+ name: "TypeScript",
106
+ status: "warn",
107
+ message: "No tsconfig.json found. TypeScript is recommended.",
108
+ };
109
+ }
110
+ try {
111
+ execSync("npx tsc --noEmit", {
112
+ cwd: root,
113
+ encoding: "utf-8",
114
+ timeout: 60000,
115
+ stdio: ["pipe", "pipe", "pipe"],
116
+ });
117
+ return {
118
+ name: "TypeScript",
119
+ status: "pass",
120
+ message: "Compiles without errors",
121
+ };
122
+ }
123
+ catch (e) {
124
+ const stderr = e instanceof Error && "stderr" in e ? e.stderr : String(e);
125
+ const errorCount = (stderr.match(/error TS/g) || []).length;
126
+ return {
127
+ name: "TypeScript",
128
+ status: "fail",
129
+ message: `${errorCount} TypeScript error(s) found`,
130
+ };
131
+ }
132
+ }
133
+ function checkNativeModules(root, platform) {
134
+ const pkgPath = join(root, "package.json");
135
+ if (!existsSync(pkgPath)) {
136
+ return {
137
+ name: "Native modules",
138
+ status: "warn",
139
+ message: "Cannot check without package.json",
140
+ };
141
+ }
142
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
143
+ const deps = Object.keys(pkg.dependencies || {});
144
+ const nativePackages = deps.filter((d) => d.startsWith("expo-camera") ||
145
+ d.startsWith("expo-location") ||
146
+ d.startsWith("expo-contacts") ||
147
+ d.startsWith("expo-media-library") ||
148
+ d.startsWith("expo-notifications") ||
149
+ d.startsWith("expo-sensors") ||
150
+ d.startsWith("expo-local-authentication") ||
151
+ d.startsWith("react-native-reanimated") ||
152
+ d.startsWith("react-native-gesture-handler") ||
153
+ d.startsWith("react-native-maps") ||
154
+ d.startsWith("react-native-webview"));
155
+ if (nativePackages.length === 0) {
156
+ return {
157
+ name: "Native modules",
158
+ status: "pass",
159
+ message: "No native modules detected (Expo Go compatible)",
160
+ };
161
+ }
162
+ const hasIosBuild = existsSync(join(root, "ios"));
163
+ const hasAndroidBuild = existsSync(join(root, "android"));
164
+ const needsIos = platform === "ios" || platform === "both";
165
+ const needsAndroid = platform === "android" || platform === "both";
166
+ const warnings = [];
167
+ if (needsIos && !hasIosBuild)
168
+ warnings.push("ios/ directory missing");
169
+ if (needsAndroid && !hasAndroidBuild)
170
+ warnings.push("android/ directory missing");
171
+ if (warnings.length > 0) {
172
+ return {
173
+ name: "Native modules",
174
+ status: "warn",
175
+ message: `${nativePackages.length} native module(s) found but ${warnings.join(", ")}. Run "npx expo prebuild".`,
176
+ };
177
+ }
178
+ return {
179
+ name: "Native modules",
180
+ status: "pass",
181
+ message: `${nativePackages.length} native module(s), native directories present`,
182
+ };
183
+ }
184
+ export function register(server) {
185
+ server.tool("mobile_checkBuildHealth", "Run build health checks on an Expo project: validate app.json, check dependencies, verify TypeScript, detect native module issues.", inputSchema, async (args) => {
186
+ try {
187
+ const root = args.project_path || process.cwd();
188
+ if (!existsSync(join(root, "app.json")) && !existsSync(join(root, "package.json"))) {
189
+ return errorResponse(new Error(`Not an Expo project: no app.json or package.json at ${root}`));
190
+ }
191
+ const checks = [
192
+ checkAppJson(root),
193
+ checkPackageJson(root),
194
+ checkNodeModules(root),
195
+ checkTypeScript(root),
196
+ checkNativeModules(root, args.platform),
197
+ ];
198
+ const passed = checks.filter((c) => c.status === "pass").length;
199
+ const failed = checks.filter((c) => c.status === "fail").length;
200
+ const warned = checks.filter((c) => c.status === "warn").length;
201
+ const result = {
202
+ project_path: root,
203
+ platform: args.platform,
204
+ summary: `${passed} passed, ${failed} failed, ${warned} warnings`,
205
+ healthy: failed === 0,
206
+ checks,
207
+ };
208
+ return textResponse(JSON.stringify(result, null, 2));
209
+ }
210
+ catch (err) {
211
+ return errorResponse(err);
212
+ }
213
+ });
214
+ }
215
+ //# sourceMappingURL=checkBuildHealth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkBuildHealth.js","sourceRoot":"","sources":["../../src/tools/checkBuildHealth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=configureDeepLinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configureDeepLinks.d.ts","sourceRoot":"","sources":["../../src/tools/configureDeepLinks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8BzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8FhD"}
@@ -0,0 +1,112 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { textResponse, errorResponse } from "../types.js";
5
+ const inputSchema = {
6
+ scheme: z
7
+ .string()
8
+ .describe("URL scheme for deep linking (e.g. 'myapp')"),
9
+ domain: z
10
+ .string()
11
+ .optional()
12
+ .describe("Domain for universal/app links (e.g. 'example.com'). Omit for scheme-only deep links."),
13
+ project_path: z
14
+ .string()
15
+ .optional()
16
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
17
+ };
18
+ const AASA_TEMPLATE = `{
19
+ "applinks": {
20
+ "apps": [],
21
+ "details": [
22
+ {
23
+ "appIDs": ["TEAM_ID.BUNDLE_ID"],
24
+ "paths": ["*"]
25
+ }
26
+ ]
27
+ }
28
+ }
29
+ `;
30
+ export function register(server) {
31
+ server.tool("mobile_configureDeepLinks", "Configure deep linking for an Expo project: set scheme, add intent filters for Android App Links, add associated domains for iOS Universal Links.", inputSchema, async (args) => {
32
+ try {
33
+ const root = args.project_path || process.cwd();
34
+ const appJsonPath = join(root, "app.json");
35
+ if (!existsSync(appJsonPath)) {
36
+ return errorResponse(new Error(`No app.json found at ${root}. Is this an Expo project?`));
37
+ }
38
+ const appJson = JSON.parse(readFileSync(appJsonPath, "utf-8"));
39
+ if (!appJson.expo)
40
+ appJson.expo = {};
41
+ appJson.expo.scheme = args.scheme;
42
+ const filesCreated = [];
43
+ if (args.domain) {
44
+ if (!appJson.expo.ios)
45
+ appJson.expo.ios = {};
46
+ appJson.expo.ios.associatedDomains = [
47
+ `applinks:${args.domain}`,
48
+ ];
49
+ if (!appJson.expo.android)
50
+ appJson.expo.android = {};
51
+ appJson.expo.android.intentFilters = [
52
+ {
53
+ action: "VIEW",
54
+ autoVerify: true,
55
+ data: [
56
+ {
57
+ scheme: "https",
58
+ host: args.domain,
59
+ pathPrefix: "/",
60
+ },
61
+ ],
62
+ category: ["BROWSABLE", "DEFAULT"],
63
+ },
64
+ ];
65
+ const wellKnownDir = join(root, "docs", ".well-known");
66
+ mkdirSync(wellKnownDir, { recursive: true });
67
+ const aasaFile = join(wellKnownDir, "apple-app-site-association");
68
+ if (!existsSync(aasaFile)) {
69
+ writeFileSync(aasaFile, AASA_TEMPLATE);
70
+ filesCreated.push(aasaFile);
71
+ }
72
+ }
73
+ writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + "\n");
74
+ const result = {
75
+ success: true,
76
+ scheme: args.scheme,
77
+ domain: args.domain || null,
78
+ app_json_updated: true,
79
+ files_created: filesCreated,
80
+ deep_link_examples: [
81
+ `${args.scheme}://` + " (opens app root)",
82
+ `${args.scheme}://settings` + " (opens /settings route)",
83
+ `${args.scheme}://chat/123` + " (opens /chat/[id] with id=123)",
84
+ ],
85
+ universal_link_examples: args.domain
86
+ ? [
87
+ `https://${args.domain}/settings`,
88
+ `https://${args.domain}/chat/123`,
89
+ ]
90
+ : [],
91
+ next_steps: [
92
+ "Run npx expo prebuild to regenerate native projects",
93
+ args.domain
94
+ ? `Host the apple-app-site-association file at https://${args.domain}/.well-known/apple-app-site-association`
95
+ : null,
96
+ args.domain
97
+ ? "Replace TEAM_ID.BUNDLE_ID in the AASA file with your Apple Team ID and bundle identifier"
98
+ : null,
99
+ args.domain
100
+ ? `Verify Android App Links at https://developers.google.com/digital-asset-links/tools/generator for ${args.domain}`
101
+ : null,
102
+ "Expo Router handles route matching automatically from the file system",
103
+ ].filter(Boolean),
104
+ };
105
+ return textResponse(JSON.stringify(result, null, 2));
106
+ }
107
+ catch (err) {
108
+ return errorResponse(err);
109
+ }
110
+ });
111
+ }
112
+ //# sourceMappingURL=configureDeepLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configureDeepLinks.js","sourceRoot":"","sources":["../../src/tools/configureDeepLinks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=integrateAI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrateAI.d.ts","sourceRoot":"","sources":["../../src/tools/integrateAI.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgIzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+ChD"}
@@ -0,0 +1,156 @@
1
+ import { z } from "zod";
2
+ import { writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { textResponse, errorResponse } from "../types.js";
5
+ const inputSchema = {
6
+ provider: z
7
+ .enum(["openai", "anthropic", "google"])
8
+ .describe("AI provider to integrate"),
9
+ features: z
10
+ .array(z.enum(["vision", "text", "audio"]))
11
+ .describe("AI features to scaffold (vision, text, audio)"),
12
+ project_path: z
13
+ .string()
14
+ .optional()
15
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
16
+ };
17
+ function generateClientCode(provider, features) {
18
+ const lines = [];
19
+ lines.push(`// AI client for ${provider}`);
20
+ lines.push(`// API keys must NOT be bundled in the app. Use a backend proxy.`);
21
+ lines.push(``);
22
+ lines.push(`const API_BASE = process.env.EXPO_PUBLIC_AI_PROXY_URL || "http://localhost:3000";`);
23
+ lines.push(``);
24
+ lines.push(`interface AIResponse {`);
25
+ lines.push(` text: string;`);
26
+ lines.push(` usage?: { prompt_tokens: number; completion_tokens: number };`);
27
+ lines.push(`}`);
28
+ lines.push(``);
29
+ lines.push(`interface AIError {`);
30
+ lines.push(` message: string;`);
31
+ lines.push(` status: number;`);
32
+ lines.push(`}`);
33
+ lines.push(``);
34
+ lines.push(`async function aiRequest(`);
35
+ lines.push(` endpoint: string,`);
36
+ lines.push(` body: Record<string, unknown>,`);
37
+ lines.push(` authToken: string,`);
38
+ lines.push(`): Promise<AIResponse> {`);
39
+ lines.push(` const controller = new AbortController();`);
40
+ lines.push(` const timeout = setTimeout(() => controller.abort(), 30000);`);
41
+ lines.push(``);
42
+ lines.push(` try {`);
43
+ lines.push(` const res = await fetch(\`\${API_BASE}\${endpoint}\`, {`);
44
+ lines.push(` method: "POST",`);
45
+ lines.push(` headers: {`);
46
+ lines.push(` "Content-Type": "application/json",`);
47
+ lines.push(` Authorization: \`Bearer \${authToken}\`,`);
48
+ lines.push(` },`);
49
+ lines.push(` body: JSON.stringify({ ...body, provider: "${provider}" }),`);
50
+ lines.push(` signal: controller.signal,`);
51
+ lines.push(` });`);
52
+ lines.push(``);
53
+ lines.push(` if (!res.ok) {`);
54
+ lines.push(` const error = await res.text();`);
55
+ lines.push(` throw new Error(\`AI request failed (\${res.status}): \${error}\`);`);
56
+ lines.push(` }`);
57
+ lines.push(``);
58
+ lines.push(` return res.json();`);
59
+ lines.push(` } finally {`);
60
+ lines.push(` clearTimeout(timeout);`);
61
+ lines.push(` }`);
62
+ lines.push(`}`);
63
+ if (features.includes("text")) {
64
+ lines.push(``);
65
+ lines.push(`export async function generateText(`);
66
+ lines.push(` prompt: string,`);
67
+ lines.push(` authToken: string,`);
68
+ lines.push(`): Promise<AIResponse> {`);
69
+ lines.push(` return aiRequest("/api/ai/text", { prompt }, authToken);`);
70
+ lines.push(`}`);
71
+ }
72
+ if (features.includes("vision")) {
73
+ lines.push(``);
74
+ lines.push(`export async function analyzeImage(`);
75
+ lines.push(` imageBase64: string,`);
76
+ lines.push(` prompt: string,`);
77
+ lines.push(` authToken: string,`);
78
+ lines.push(`): Promise<AIResponse> {`);
79
+ lines.push(` return aiRequest(`);
80
+ lines.push(` "/api/ai/vision",`);
81
+ lines.push(` { prompt, image: \`data:image/jpeg;base64,\${imageBase64}\` },`);
82
+ lines.push(` authToken,`);
83
+ lines.push(` );`);
84
+ lines.push(`}`);
85
+ }
86
+ if (features.includes("audio")) {
87
+ lines.push(``);
88
+ lines.push(`export async function transcribeAudio(`);
89
+ lines.push(` audioUri: string,`);
90
+ lines.push(` authToken: string,`);
91
+ lines.push(`): Promise<AIResponse> {`);
92
+ lines.push(` const formData = new FormData();`);
93
+ lines.push(` formData.append("file", {`);
94
+ lines.push(` uri: audioUri,`);
95
+ lines.push(` type: "audio/m4a",`);
96
+ lines.push(` name: "recording.m4a",`);
97
+ lines.push(` } as any);`);
98
+ lines.push(``);
99
+ lines.push(` const controller = new AbortController();`);
100
+ lines.push(` const timeout = setTimeout(() => controller.abort(), 60000);`);
101
+ lines.push(``);
102
+ lines.push(` try {`);
103
+ lines.push(` const res = await fetch(\`\${API_BASE}/api/ai/transcribe\`, {`);
104
+ lines.push(` method: "POST",`);
105
+ lines.push(` headers: { Authorization: \`Bearer \${authToken}\` },`);
106
+ lines.push(` body: formData,`);
107
+ lines.push(` signal: controller.signal,`);
108
+ lines.push(` });`);
109
+ lines.push(``);
110
+ lines.push(` if (!res.ok) throw new Error(\`Transcription failed: \${res.status}\`);`);
111
+ lines.push(` return res.json();`);
112
+ lines.push(` } finally {`);
113
+ lines.push(` clearTimeout(timeout);`);
114
+ lines.push(` }`);
115
+ lines.push(`}`);
116
+ }
117
+ lines.push(``);
118
+ return lines.join("\n");
119
+ }
120
+ export function register(server) {
121
+ server.tool("mobile_integrateAI", "Scaffold AI API integration with provider config, error handling, and TypeScript types.", inputSchema, async (args) => {
122
+ try {
123
+ const root = args.project_path || process.cwd();
124
+ const libDir = join(root, "lib");
125
+ mkdirSync(libDir, { recursive: true });
126
+ const clientFile = join(libDir, "ai.ts");
127
+ if (existsSync(clientFile)) {
128
+ return errorResponse(new Error(`AI client already exists at ${clientFile}. Delete it first or edit manually.`));
129
+ }
130
+ const code = generateClientCode(args.provider, args.features);
131
+ writeFileSync(clientFile, code);
132
+ const result = {
133
+ success: true,
134
+ provider: args.provider,
135
+ features: args.features,
136
+ file_created: clientFile,
137
+ next_steps: [
138
+ "Set EXPO_PUBLIC_AI_PROXY_URL in your .env to point to your backend proxy",
139
+ "Deploy a backend that proxies requests to the AI provider and holds the API key",
140
+ "Never bundle AI provider API keys directly in the mobile app",
141
+ args.features.includes("vision")
142
+ ? "Install expo-camera for vision features: npx expo install expo-camera"
143
+ : null,
144
+ args.features.includes("audio")
145
+ ? "Install expo-av for audio recording: npx expo install expo-av"
146
+ : null,
147
+ ].filter(Boolean),
148
+ };
149
+ return textResponse(JSON.stringify(result, null, 2));
150
+ }
151
+ catch (err) {
152
+ return errorResponse(err);
153
+ }
154
+ });
155
+ }
156
+ //# sourceMappingURL=integrateAI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrateAI.js","sourceRoot":"","sources":["../../src/tools/integrateAI.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=resetDevEnvironment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resetDevEnvironment.d.ts","sourceRoot":"","sources":["../../src/tools/resetDevEnvironment.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoCzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiJhD"}
@@ -0,0 +1,163 @@
1
+ import { z } from "zod";
2
+ import { execSync } from "node:child_process";
3
+ import { existsSync, rmSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { textResponse, errorResponse } from "../types.js";
6
+ const inputSchema = {
7
+ project_path: z
8
+ .string()
9
+ .optional()
10
+ .describe("Absolute path to the Expo project root. Defaults to cwd."),
11
+ include_pods: z
12
+ .boolean()
13
+ .optional()
14
+ .default(false)
15
+ .describe("Remove ios/Pods and run pod install (macOS only)"),
16
+ include_gradle: z
17
+ .boolean()
18
+ .optional()
19
+ .default(false)
20
+ .describe("Clean Android Gradle build cache"),
21
+ };
22
+ function safeRemove(path) {
23
+ if (!existsSync(path))
24
+ return false;
25
+ try {
26
+ rmSync(path, { recursive: true, force: true });
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ export function register(server) {
34
+ server.tool("mobile_resetDevEnvironment", "Nuclear reset for a stuck Expo dev environment: clear Metro cache, node_modules cache, .expo directory, and optionally iOS Pods and Android Gradle cache.", inputSchema, async (args) => {
35
+ try {
36
+ const root = args.project_path || process.cwd();
37
+ const steps = [];
38
+ if (!existsSync(join(root, "package.json"))) {
39
+ return errorResponse(new Error(`No package.json at ${root}. Is this a project root?`));
40
+ }
41
+ // Metro cache
42
+ const metroCache = join(root, "node_modules", ".cache", "metro");
43
+ steps.push({
44
+ name: "Metro cache",
45
+ status: safeRemove(metroCache) ? "cleaned" : "skipped",
46
+ message: safeRemove(metroCache)
47
+ ? "Removed node_modules/.cache/metro"
48
+ : "Metro cache not found",
49
+ });
50
+ // General node_modules cache
51
+ const nmCache = join(root, "node_modules", ".cache");
52
+ if (existsSync(nmCache)) {
53
+ safeRemove(nmCache);
54
+ steps.push({
55
+ name: "node_modules/.cache",
56
+ status: "cleaned",
57
+ message: "Removed all cached build artifacts",
58
+ });
59
+ }
60
+ else {
61
+ steps.push({
62
+ name: "node_modules/.cache",
63
+ status: "skipped",
64
+ message: "No cache directory found",
65
+ });
66
+ }
67
+ // .expo directory
68
+ const expoDir = join(root, ".expo");
69
+ steps.push({
70
+ name: ".expo directory",
71
+ status: safeRemove(expoDir) ? "cleaned" : "skipped",
72
+ message: existsSync(expoDir)
73
+ ? "Removed .expo directory"
74
+ : ".expo directory not found",
75
+ });
76
+ // Temp directory
77
+ const tmpDir = join(root, "tmp");
78
+ if (existsSync(tmpDir)) {
79
+ safeRemove(tmpDir);
80
+ steps.push({
81
+ name: "tmp directory",
82
+ status: "cleaned",
83
+ message: "Removed tmp directory",
84
+ });
85
+ }
86
+ // iOS Pods
87
+ if (args.include_pods) {
88
+ const podsDir = join(root, "ios", "Pods");
89
+ const podfileLock = join(root, "ios", "Podfile.lock");
90
+ if (existsSync(podsDir)) {
91
+ safeRemove(podsDir);
92
+ if (existsSync(podfileLock))
93
+ safeRemove(podfileLock);
94
+ try {
95
+ execSync("pod install", {
96
+ cwd: join(root, "ios"),
97
+ encoding: "utf-8",
98
+ timeout: 120000,
99
+ stdio: ["pipe", "pipe", "pipe"],
100
+ });
101
+ steps.push({
102
+ name: "iOS Pods",
103
+ status: "cleaned",
104
+ message: "Removed Pods, reinstalled via pod install",
105
+ });
106
+ }
107
+ catch {
108
+ steps.push({
109
+ name: "iOS Pods",
110
+ status: "error",
111
+ message: "Removed Pods but pod install failed. Run manually: cd ios && pod install",
112
+ });
113
+ }
114
+ }
115
+ else {
116
+ steps.push({
117
+ name: "iOS Pods",
118
+ status: "skipped",
119
+ message: "ios/Pods not found",
120
+ });
121
+ }
122
+ }
123
+ // Android Gradle cache
124
+ if (args.include_gradle) {
125
+ const gradleBuild = join(root, "android", "build");
126
+ const appBuild = join(root, "android", "app", "build");
127
+ let cleaned = false;
128
+ if (existsSync(gradleBuild)) {
129
+ safeRemove(gradleBuild);
130
+ cleaned = true;
131
+ }
132
+ if (existsSync(appBuild)) {
133
+ safeRemove(appBuild);
134
+ cleaned = true;
135
+ }
136
+ steps.push({
137
+ name: "Android Gradle",
138
+ status: cleaned ? "cleaned" : "skipped",
139
+ message: cleaned
140
+ ? "Removed android/build and android/app/build"
141
+ : "Android build directories not found",
142
+ });
143
+ }
144
+ const cleaned = steps.filter((s) => s.status === "cleaned").length;
145
+ const result = {
146
+ success: true,
147
+ project_path: root,
148
+ summary: `${cleaned} of ${steps.length} items cleaned`,
149
+ steps,
150
+ next_steps: [
151
+ "Run: npx expo start --clear",
152
+ "If issues persist: rm -rf node_modules && npm install",
153
+ "For native rebuild: npx expo prebuild --clean",
154
+ ],
155
+ };
156
+ return textResponse(JSON.stringify(result, null, 2));
157
+ }
158
+ catch (err) {
159
+ return errorResponse(err);
160
+ }
161
+ });
162
+ }
163
+ //# sourceMappingURL=resetDevEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resetDevEnvironment.js","sourceRoot":"","sources":["../../src/tools/resetDevEnvironment.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tmhs/mobile-mcp",
3
- "version": "0.2.0",
4
- "description": "MCP server for mobile app development - 6 tools for environment checks, project scaffolding, device deployment, screen generation, component generation, and dependency installation.",
3
+ "version": "0.4.0",
4
+ "description": "MCP server for mobile app development - 12 tools for environment checks, project scaffolding, device deployment, screen/component generation, dependency installation, permissions, AI integration, build health, push notifications, deep links, and dev environment reset.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {