Skip to main content
Glama

upload_artifact

Upload APK or AAB files to create releases on Google Play Console tracks, enabling controlled app distribution to internal, alpha, beta, or production users.

Instructions

Upload an APK or AAB and create a release on the given track.

File type auto-detected from extension (.apk/.aab). Upload and track assignment are atomic.

Args: package_name: Package name, e.g. com.example.myapp file_path: Absolute local path to the APK or AAB. track: "internal" (default), "alpha", "beta", or "production". status: "draft" (default), "inProgress", or "completed". rollout_percentage: Rollout % when status is "inProgress". Default 10%. release_name: Optional human-readable name. release_notes: Optional {lang: text} dict, e.g. {"en-US": "Initial release"}.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
package_nameYes
file_pathYes
trackNointernal
statusNodraft
rollout_percentageNo
release_nameNo
release_notesNo

Implementation Reference

  • MCP tool registration and wrapper for upload_artifact, which delegates to the underlying publisher client.
    @mcp.tool()
    def upload_artifact(
        package_name: str,
        file_path: str,
        track: str = "internal",
        status: str = "draft",
        rollout_percentage: float = 10.0,
        release_name: str = "",
        release_notes: Optional[dict] = None,
    ) -> str:
        """Upload an APK or AAB and create a release on the given track.
    
        File type auto-detected from extension (.apk/.aab). Upload and track
        assignment are atomic.
    
        Args:
            package_name: Package name, e.g. com.example.myapp
            file_path: Absolute local path to the APK or AAB.
            track: "internal" (default), "alpha", "beta", or "production".
            status: "draft" (default), "inProgress", or "completed".
            rollout_percentage: Rollout % when status is "inProgress". Default 10%.
            release_name: Optional human-readable name.
            release_notes: Optional {lang: text} dict, e.g. {"en-US": "Initial release"}.
        """
        try:
            notes = _notes_from_dict(release_notes)
            result = _publisher().upload_artifact(
                package_name=package_name,
                file_path=file_path,
                track=track,
                rollout_percentage=rollout_percentage if status == "inProgress" else None,
                release_name=release_name or None,
                release_notes=notes,
                status=status,
            )
  • Actual implementation of the upload_artifact logic, handling the file upload and track assignment process.
    def upload_artifact(
        self,
        package_name: str,
        file_path: str,
        track: str,
        rollout_percentage: Optional[float] = None,
        release_name: Optional[str] = None,
        release_notes: Optional[List[Dict[str, str]]] = None,
        status: str = "draft",
    ) -> Dict[str, Any]:
        """Upload an APK or AAB and create a release on the given track.
    
        File type is inferred from the extension (.apk or .aab).
        Everything (upload + track assignment) happens in a single edit.
        """
        ext = os.path.splitext(file_path)[1].lower()
        if ext == ".apk":
            mime = APK_MIME
            artifact_type = "apk"
        elif ext == ".aab":
            mime = BUNDLE_MIME
            artifact_type = "bundle"
        else:
            raise ValueError(f"Unrecognized file extension '{ext}'. Use .apk or .aab.")
    
        media = MediaFileUpload(file_path, mimetype=mime, resumable=True)
        edit_id = self._create_edit(package_name)
        try:
            if artifact_type == "apk":
                artifact = self.service.edits().apks().upload(
                    packageName=package_name, editId=edit_id, media_body=media
                ).execute()
            else:
                artifact = self.service.edits().bundles().upload(
                    packageName=package_name, editId=edit_id, media_body=media
                ).execute()
    
            version_code = artifact["versionCode"]
            release: Dict[str, Any] = {
                "versionCodes": [str(version_code)],
                "status": status,
            }
            if status == "inProgress" and rollout_percentage is not None:
                if rollout_percentage >= 100:
                    release["status"] = "completed"
                else:
                    release["userFraction"] = round(rollout_percentage / 100.0, 4)
            if release_name:
                release["name"] = release_name
            if release_notes:
                release["releaseNotes"] = release_notes
    
            updated_track = self._update_track(
                package_name, edit_id, track, {"track": track, "releases": [release]}
            )
            commit = self._commit_edit(package_name, edit_id)

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/AgiMaulana/GooglePlayConsoleMcp'

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