Skip to main content
Glama

release-create

Create new app versions on App Store and Google Play. When no version is specified, it checks and displays the latest versions from each store.

Instructions

Create a new version on App Store/Google Play. If version is not provided, checks and displays latest versions from each store.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appNoRegistered app slug
packageNameNoGoogle Play package name
bundleIdNoApp Store bundle ID
versionNoVersion string to create (e.g., 1.2.0). If not provided, will check and display latest versions.
storeNoTarget store (default: both)
versionCodesNoVersion code array for Google Play (required when creating Google Play version)

Implementation Reference

  • The `handleAsoCreateVersion` function is the main handler for the 'release-create' tool. It resolves app identifiers, loads config, optionally prompts for version if not provided, and creates new versions on App Store and/or Google Play using the respective services.
    export async function handleAsoCreateVersion(options: AsoCreateVersionOptions) {
      const { app, version, store = "both", versionCodes } = options;
      let { packageName, bundleId } = options;
    
      const resolved = appResolutionService.resolve({
        slug: app,
        packageName,
        bundleId,
      });
    
      if (!resolved.success) {
        return {
          content: [
            {
              type: "text" as const,
              text: resolved.error.message,
            },
          ],
        };
      }
    
      const {
        slug,
        bundleId: resolvedBundleId,
        packageName: resolvedPackageName,
        hasAppStore,
        hasGooglePlay,
      } = resolved.data;
    
      bundleId = resolvedBundleId;
      packageName = resolvedPackageName;
    
      let config;
      try {
        config = loadConfig();
      } catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
          content: [
            {
              type: "text" as const,
              text: `❌ Failed to load config: ${message}`,
            },
          ],
          isError: true,
        };
      }
    
      // If version is not provided, check latest versions and prompt user
      if (!version) {
        const versionInfo = await getLatestVersions({
          store,
          bundleId,
          packageName,
          hasAppStore,
          hasGooglePlay,
        });
    
        return {
          content: [
            {
              type: "text" as const,
              text: versionInfo.messages.join("\n"),
            },
          ],
        };
      }
    
      // Version is provided, proceed with creation
      console.error(`[MCP] 📦 Creating version: ${version}`);
      console.error(`[MCP]   Store: ${store}`);
      console.error(`[MCP]   App: ${slug}`);
      if (packageName) console.error(`[MCP]   Package Name: ${packageName}`);
      if (bundleId) console.error(`[MCP]   Bundle ID: ${bundleId}`);
      if (versionCodes) {
        console.error(`[MCP]   Version Codes: ${versionCodes.join(", ")}`);
      }
    
      const results: string[] = [];
    
      if (store === "appStore" || store === "both") {
        if (!hasAppStore) {
          results.push(`⏭️  Skipping App Store (not registered for App Store)`);
        } else if (!config.appStore) {
          results.push(
            `⏭️  Skipping App Store (not configured in ~/.config/pabal-mcp/config.json)`
          );
        } else if (!bundleId) {
          results.push(`⏭️  Skipping App Store (no bundleId provided)`);
        } else {
          const createResult = await appStoreService.createVersion(
            bundleId,
            version
          );
          if (!createResult.success) {
            results.push(
              `❌ App Store version creation failed: ${createResult.error.message}`
            );
          } else {
            const state = createResult.data.state?.toUpperCase() || "UNKNOWN";
            results.push(
              `✅ App Store version ${createResult.data.versionString} created (${state})`
            );
          }
        }
      }
    
      if (store === "googlePlay" || store === "both") {
        if (!hasGooglePlay) {
          results.push(`⏭️  Skipping Google Play (not registered for Google Play)`);
        } else if (!config.playStore) {
          results.push(
            `⏭️  Skipping Google Play (not configured in ~/.config/pabal-mcp/config.json)`
          );
        } else if (!packageName) {
          results.push(`⏭️  Skipping Google Play (no packageName provided)`);
        } else if (!versionCodes || versionCodes.length === 0) {
          results.push(`⏭️  Skipping Google Play (no version codes provided)`);
        } else {
          const createResult = await googlePlayService.createVersion(
            packageName,
            version,
            versionCodes
          );
          if (!createResult.success) {
            results.push(
              `❌ Google Play version creation failed: ${createResult.error.message}`
            );
          } else {
            results.push(
              `✅ Google Play production draft created with versionCodes: ${versionCodes.join(
                ", "
              )}`
            );
          }
        }
      }
    
      return {
        content: [
          {
            type: "text" as const,
            text: `📦 Version Creation Results:\n${results.join("\n")}`,
          },
        ],
      };
    }
  • src/index.ts:299-325 (registration)
    The 'release-create' tool is registered here using `registerToolWithInfo`, which adds it to the MCP server, provides the description, input schema, and links to the `handleAsoCreateVersion` handler.
    registerToolWithInfo(
      "release-create",
      {
        description:
          "Create a new version on App Store/Google Play. If version is not provided, checks and displays latest versions from each store.",
        inputSchema: z.object({
          app: z.string().optional().describe("Registered app slug"),
          packageName: z.string().optional().describe("Google Play package name"),
          bundleId: z.string().optional().describe("App Store bundle ID"),
          version: z
            .string()
            .optional()
            .describe(
              "Version string to create (e.g., 1.2.0). If not provided, will check and display latest versions."
            ),
          store: storeSchema.describe("Target store (default: both)"),
          versionCodes: z
            .array(z.number())
            .optional()
            .describe(
              "Version code array for Google Play (required when creating Google Play version)"
            ),
        }),
      },
      handleAsoCreateVersion,
      "Release Management"
    );
  • TypeScript interface defining the input options for the handler, matching the Zod schema used in registration.
    interface AsoCreateVersionOptions {
      app?: string; // Registered app slug
      packageName?: string; // For Google Play
      bundleId?: string; // For App Store
      version?: string; // Optional: if not provided, will check latest versions and prompt
      store?: StoreType;
      versionCodes?: number[]; // For Google Play
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions the tool can create versions or check/display latest versions, but doesn't clarify whether this is a read-only or write operation, what permissions are needed, whether it's destructive, or what the output format looks like. The dual behavior (create vs. check) adds complexity that isn't fully explained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately concise with two sentences that cover both primary and conditional behaviors. It's front-loaded with the main purpose, though the conditional behavior could be slightly clearer. No wasted words, but the dual functionality might benefit from more structured phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (dual create/check behavior, 6 parameters, no annotations, no output schema), the description is insufficient. It doesn't explain the relationship between parameters (e.g., how app, packageName, and bundleId interact), doesn't clarify whether creation is for one store or both when version is provided, and provides no information about return values or error conditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds minimal value by mentioning the conditional behavior when version is not provided, but doesn't provide additional semantic context beyond what's in the parameter descriptions. Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's primary function ('Create a new version on App Store/Google Play') with a specific verb and resource. It also mentions a secondary behavior when version is not provided. However, it doesn't explicitly distinguish this from sibling tools like 'release-check-versions' or 'release-update-notes', which appear related to release management.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage context by explaining what happens when the version parameter is omitted ('checks and displays latest versions'). However, it doesn't offer guidance on when to use this tool versus alternatives like 'release-check-versions' or 'release-update-notes', nor does it mention prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/quartz-labs-dev/pabal-mcp'

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