Skip to main content
Glama

pyodide_install-packages

Install Python packages in Pyodide environments using space-separated format, enabling Python code execution via LLMs on the MCP server.

Instructions

Install Python packages using Pyodide. Multiple packages can be specified using space-separated format.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
packageYesPython package(s) to install. For multiple packages, use space-separated format (e.g., 'numpy matplotlib pandas').

Implementation Reference

  • Primary handler function executing the pyodide_install-packages tool logic: installs one or more Python packages via Pyodide, with sophisticated fallback mechanism for unsupported packages.
    async installPackage(packageName: string) { if (!this.pyodide) { return formatCallToolError("Pyodide not initialized"); } try { // パッケージ名をスペースで分割 const packages = packageName .split(" ") .map((pkg) => pkg.trim()) .filter(Boolean); if (packages.length === 0) { return formatCallToolError("No valid package names specified"); } // 出力メッセージを集める const outputs: string[] = []; // 各パッケージを処理 for (const pkg of packages) { try { // 1. まずpyodide.loadPackageでインストールを試みる outputs.push(`Attempting to install ${pkg} using loadPackage...`); try { await this.pyodide.loadPackage(pkg, { messageCallback: (msg) => { outputs.push(`loadPackage: ${msg}`); }, errorCallback: (err) => { throw new Error(err); }, }); outputs.push(`Successfully installed ${pkg} using loadPackage.`); continue; // このパッケージは成功したので次のパッケージへ } catch (loadPackageError) { outputs.push( `loadPackage failed for ${pkg}: ${ loadPackageError instanceof Error ? loadPackageError.message : String(loadPackageError) }` ); outputs.push(`Falling back to micropip for ${pkg}...`); // loadPackageが失敗した場合は、micropipを使用する // micropipがまだロードされていない場合はロードする try { // micropipをロードする await this.pyodide.loadPackage("micropip", { messageCallback: (msg) => { outputs.push(`loadPackage: ${msg}`); }, errorCallback: (err) => { throw new Error(err); }, }); } catch (micropipLoadError) { throw new Error( `Failed to load micropip: ${ micropipLoadError instanceof Error ? micropipLoadError.message : String(micropipLoadError) }` ); } // 2. micropipを使ったインストール処理 // 一時ディレクトリを作成 const tempDir = process.env.PYODIDE_CACHE_DIR || "./cache"; if (!fs.existsSync(tempDir)) { fs.mkdirSync(tempDir, { recursive: true }); } // Pyodide内のtempディレクトリを作成 this.pyodide.FS.mkdirTree("/tmp/wheels"); // PyPIからwheelのURLを取得 const wheelUrl = await getWheelUrl(pkg); const wheelFilename = path.basename(wheelUrl); const localWheelPath = path.join(tempDir, wheelFilename); // wheelをダウンロード outputs.push(`Downloading wheel for ${pkg}...`); await downloadWheel(wheelUrl, localWheelPath); // wheelをPyodideのファイルシステムにコピー const wheelData = fs.readFileSync(localWheelPath); const pyodideWheelPath = `/tmp/wheels/${wheelFilename}`; this.pyodide.FS.writeFile(pyodideWheelPath, wheelData); // micropipでインストール const { output } = await withOutputCapture( this.pyodide, async () => { await this.pyodide!.runPythonAsync(` import micropip await micropip.install("emfs:${pyodideWheelPath}") `); }, { suppressConsole: true } ); outputs.push( `Successfully installed ${pkg} using micropip: ${output}` ); } } catch (error) { // 個別のパッケージのエラーを記録して続行 outputs.push( `Failed to install ${pkg}: ${ error instanceof Error ? error.message : String(error) }` ); } } return formatCallToolSuccess(outputs.join("\n\n")); } catch (error) { return formatCallToolError(error); } }
  • MCP tool schema definition for pyodide_install-packages, including input schema for the 'package' parameter.
    export const INSTALL_PYTHON_PACKAGES_TOOL: Tool = { name: "pyodide_install-packages", description: "Install Python packages using Pyodide. Multiple packages can be specified using space-separated format.", inputSchema: { type: "object", properties: { package: { type: "string", description: "Python package(s) to install. For multiple packages, use space-separated format (e.g., 'numpy matplotlib pandas').", }, }, required: ["package"], }, };
  • Tool registration: includes INSTALL_PYTHON_PACKAGES_TOOL in the list returned by ListToolsRequestHandler.
    const TOOLS: Tool[] = [ tools.EXECUTE_PYTHON_TOOL, tools.INSTALL_PYTHON_PACKAGES_TOOL, tools.GET_MOUNT_POINTS_TOOL, tools.LIST_MOUNTED_DIRECTORY_TOOL, tools.READ_IMAGE_TOOL, ];
  • MCP server handler dispatcher for the tool: argument validation and invocation of PyodideManager.installPackage.
    case "pyodide_install-packages": { const installPythonPackagesArgs = isInstallPythonPackagesArgs(args); if (installPythonPackagesArgs instanceof type.errors) { throw installPythonPackagesArgs; } const { package: packageName } = installPythonPackagesArgs; const results = await pyodideManager.installPackage(packageName); return results; }
  • Supporting function to obtain PyPI wheel URL used in manual installation fallback.
    async function getWheelUrl(packageName: string): Promise<string> { return new Promise((resolve, reject) => { const url = `https://pypi.org/pypi/${packageName}/json`; https .get(url, (response) => { if (response.statusCode !== 200) { reject( new Error(`Failed to get package info: ${response.statusCode}`) ); return; } let data = ""; response.on("data", (chunk) => { data += chunk; }); response.on("end", () => { try { const packageInfo = JSON.parse(data); const releases = packageInfo.releases[packageInfo.info.version]; // py3-none-any.whl形式のWheelファイルを検索 const wheel = releases.find( (release: any) => release.packagetype === "bdist_wheel" && release.filename.includes("py3-none-any.whl") ); if (wheel) { resolve(wheel.url); } else { reject(new Error(`No compatible wheel found for ${packageName}`)); } } catch (error) { reject(error); } }); }) .on("error", reject); }); }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yonaka15/mcp-pyodide'

If you have feedback or need assistance with the MCP directory API, please join our Discord server