replicant-mcp 1.4.3 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -107,6 +107,17 @@ Use \`rtfm\` for detailed documentation on any tool.`,
107
107
  default:
108
108
  throw new Error(`Unknown tool: ${name}`);
109
109
  }
110
+ // Return images as native MCP image content blocks for efficiency
111
+ // (avoids Claude tokenizing base64 as text)
112
+ if (result && typeof result === "object" && "base64" in result && "mimeType" in result) {
113
+ const { base64, mimeType, ...metadata } = result;
114
+ return {
115
+ content: [
116
+ { type: "image", data: base64, mimeType },
117
+ { type: "text", text: JSON.stringify(metadata, null, 2) },
118
+ ],
119
+ };
120
+ }
110
121
  return {
111
122
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
112
123
  };
@@ -15,4 +15,8 @@ export declare class EnvironmentService {
15
15
  private findSdkPath;
16
16
  private getSearchPaths;
17
17
  clearCache(): void;
18
+ private getExecutableName;
19
+ private findAdbInPath;
20
+ private isValidSdkPath;
21
+ private getParentDir;
18
22
  }
@@ -23,8 +23,8 @@ export class EnvironmentService {
23
23
  };
24
24
  return this.cached;
25
25
  }
26
- const adbPath = path.join(sdkPath, "platform-tools", "adb");
27
- const emulatorPath = path.join(sdkPath, "emulator", "emulator");
26
+ const adbPath = path.join(sdkPath, "platform-tools", this.getExecutableName("adb", platform));
27
+ const emulatorPath = path.join(sdkPath, "emulator", this.getExecutableName("emulator", platform));
28
28
  // Verify adb exists
29
29
  if (!fs.existsSync(adbPath)) {
30
30
  issues.push(`adb not found at ${adbPath}`);
@@ -62,9 +62,9 @@ export class EnvironmentService {
62
62
  if (!env.sdkPath) {
63
63
  throw new ReplicantError(ErrorCode.SDK_NOT_FOUND, "Android SDK not found", "Install Android Studio or set ANDROID_HOME environment variable");
64
64
  }
65
- const avdManagerPath = path.join(env.sdkPath, "cmdline-tools", "latest", "bin", "avdmanager");
65
+ const avdManagerPath = path.join(env.sdkPath, "cmdline-tools", "latest", "bin", this.getExecutableName("avdmanager", env.platform));
66
66
  // Fallback to older location
67
- const legacyPath = path.join(env.sdkPath, "tools", "bin", "avdmanager");
67
+ const legacyPath = path.join(env.sdkPath, "tools", "bin", this.getExecutableName("avdmanager", env.platform));
68
68
  if (fs.existsSync(avdManagerPath)) {
69
69
  return avdManagerPath;
70
70
  }
@@ -76,14 +76,14 @@ export class EnvironmentService {
76
76
  findSdkPath(platform) {
77
77
  // 1. Check ANDROID_HOME
78
78
  if (process.env.ANDROID_HOME) {
79
- const adbPath = path.join(process.env.ANDROID_HOME, "platform-tools", "adb");
79
+ const adbPath = path.join(process.env.ANDROID_HOME, "platform-tools", this.getExecutableName("adb", platform));
80
80
  if (fs.existsSync(adbPath)) {
81
81
  return process.env.ANDROID_HOME;
82
82
  }
83
83
  }
84
84
  // 2. Check ANDROID_SDK_ROOT
85
85
  if (process.env.ANDROID_SDK_ROOT) {
86
- const adbPath = path.join(process.env.ANDROID_SDK_ROOT, "platform-tools", "adb");
86
+ const adbPath = path.join(process.env.ANDROID_SDK_ROOT, "platform-tools", this.getExecutableName("adb", platform));
87
87
  if (fs.existsSync(adbPath)) {
88
88
  return process.env.ANDROID_SDK_ROOT;
89
89
  }
@@ -91,11 +91,21 @@ export class EnvironmentService {
91
91
  // 3. Probe common paths
92
92
  const searchPaths = this.getSearchPaths(platform);
93
93
  for (const sdkPath of searchPaths) {
94
- const adbPath = path.join(sdkPath, "platform-tools", "adb");
94
+ const adbPath = path.join(sdkPath, "platform-tools", this.getExecutableName("adb", platform));
95
95
  if (fs.existsSync(adbPath)) {
96
96
  return sdkPath;
97
97
  }
98
98
  }
99
+ // 4. Probe PATH as last resort
100
+ const adbInPath = this.findAdbInPath(platform);
101
+ if (adbInPath) {
102
+ // adb is at <SDK>/platform-tools/adb, go up 2 levels
103
+ const platformToolsDir = this.getParentDir(adbInPath, platform);
104
+ const sdkPath = this.getParentDir(platformToolsDir, platform);
105
+ if (this.isValidSdkPath(sdkPath, platform)) {
106
+ return sdkPath;
107
+ }
108
+ }
99
109
  return null;
100
110
  }
101
111
  getSearchPaths(platform) {
@@ -127,4 +137,47 @@ export class EnvironmentService {
127
137
  clearCache() {
128
138
  this.cached = null;
129
139
  }
140
+ getExecutableName(baseName, platform) {
141
+ const currentPlatform = platform ?? os.platform();
142
+ if (currentPlatform !== "win32") {
143
+ return baseName;
144
+ }
145
+ const windowsExtensions = {
146
+ adb: ".exe",
147
+ emulator: ".exe",
148
+ avdmanager: ".bat",
149
+ };
150
+ return baseName + (windowsExtensions[baseName] || ".exe");
151
+ }
152
+ findAdbInPath(platform) {
153
+ const actualPlatform = platform ?? os.platform();
154
+ const adbName = this.getExecutableName("adb", actualPlatform);
155
+ const pathEnv = process.env.PATH || "";
156
+ const pathSeparator = actualPlatform === "win32" ? ";" : ":";
157
+ const dirSeparator = actualPlatform === "win32" ? "\\" : "/";
158
+ for (const dir of pathEnv.split(pathSeparator)) {
159
+ if (!dir)
160
+ continue;
161
+ // Use platform-appropriate path separator
162
+ const candidate = dir + dirSeparator + adbName;
163
+ if (fs.existsSync(candidate)) {
164
+ return candidate;
165
+ }
166
+ }
167
+ return null;
168
+ }
169
+ isValidSdkPath(sdkPath, platform) {
170
+ // Valid SDK should have platform-tools directory with adb
171
+ const actualPlatform = platform ?? os.platform();
172
+ const separator = actualPlatform === "win32" ? "\\" : "/";
173
+ const adbPath = sdkPath + separator + "platform-tools" + separator + this.getExecutableName("adb", platform);
174
+ return fs.existsSync(adbPath);
175
+ }
176
+ getParentDir(filePath, platform) {
177
+ const actualPlatform = platform ?? os.platform();
178
+ const separator = actualPlatform === "win32" ? "\\" : "/";
179
+ const parts = filePath.split(separator);
180
+ parts.pop(); // Remove last component
181
+ return parts.join(separator);
182
+ }
130
183
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicant-mcp",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "Android MCP server for AI-assisted Android development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",