@tmhs/mobile-mcp 0.2.0 → 0.3.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,12 @@ 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";
10
13
  const server = new McpServer({
11
14
  name: "mobile-mcp",
12
- version: "0.2.0",
15
+ version: "0.3.0",
13
16
  });
14
17
  registerCheckDevEnvironment(server);
15
18
  registerScaffoldProject(server);
@@ -17,6 +20,9 @@ registerRunOnDevice(server);
17
20
  registerGenerateScreen(server);
18
21
  registerGenerateComponent(server);
19
22
  registerInstallDependency(server);
23
+ registerAddPermission(server);
24
+ registerIntegrateAI(server);
25
+ registerCheckBuildHealth(server);
20
26
  async function main() {
21
27
  const transport = new StdioServerTransport();
22
28
  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;AAEnF,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;AAEjC,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=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=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":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,GAAG;IAClB,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;SACvC,QAAQ,CAAC,0BAA0B,CAAC;IACvC,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;SAC1C,QAAQ,CAAC,+CAA+C,CAAC;IAC5D,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;CACxE,CAAC;AAEF,SAAS,kBAAkB,CACzB,QAAgB,EAChB,QAAkB;IAElB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;IAChG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IAC9E,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/B,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,CAAC,oDAAoD,QAAQ,OAAO,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhB,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;QACzE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QACjF,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAChF,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;QAC1F,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,yFAAyF,EACzF,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACjC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3B,OAAO,aAAa,CAClB,IAAI,KAAK,CACP,+BAA+B,UAAU,qCAAqC,CAC/E,CACF,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9D,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAEhC,MAAM,MAAM,GAAG;gBACb,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,YAAY,EAAE,UAAU;gBACxB,UAAU,EAAE;oBACV,0EAA0E;oBAC1E,iFAAiF;oBACjF,8DAA8D;oBAC9D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC9B,CAAC,CAAC,uEAAuE;wBACzE,CAAC,CAAC,IAAI;oBACR,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;wBAC7B,CAAC,CAAC,+DAA+D;wBACjE,CAAC,CAAC,IAAI;iBACT,CAAC,MAAM,CAAC,OAAO,CAAC;aAClB,CAAC;YAEF,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
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.3.0",
4
+ "description": "MCP server for mobile app development - 9 tools for environment checks, project scaffolding, device deployment, screen/component generation, dependency installation, permissions, AI integration, and build health checks.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {