Skip to main content
Glama
kongyo2

Stellaris Modding MCP Server

stellaris-version

Read-only

Retrieve current Stellaris version details, including build ID, last update time, and available version numbers, to support modding activities effectively.

Instructions

ステラリスの現在のバージョン情報を取得します。ビルドID、最終更新日時、利用可能なバージョン番号などmodding に必要な情報を提供します。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • src/server.ts:297-435 (registration)
    Registration of the 'stellaris-version' tool using FastMCP server.addTool, including annotations, description, handler, name, and empty schema.
      annotations: {
        openWorldHint: true, // 外部APIにアクセスする
        readOnlyHint: true, // データを変更しない
        title: "Stellaris Version Info",
      },
      description:
        "ステラリスの現在のバージョン情報を取得します。ビルドID、最終更新日時、利用可能なバージョン番号などmodding に必要な情報を提供します。",
      execute: async (_args, { log }) => {
        try {
          log.info("Fetching Stellaris version info from SteamCMD API...");
    
          const appInfo = (await fetchSteamAppInfo(STELLARIS_APP_ID)) as {
            common?: { name?: string; oslist?: string };
            config?: { installdir?: string };
            depots?: {
              branches?: Record<
                string,
                { buildid?: string; description?: string; timeupdated?: string }
              >;
            };
            extended?: { developer?: string; publisher?: string };
          };
          const branches = appInfo.depots?.branches;
    
          if (!branches) {
            throw new Error("Branch information not found in API response");
          }
    
          const publicBranch = branches.public;
    
          // バージョン番号らしきブランチを抽出(数字.数字.数字の形式)
          const versionBranches = Object.keys(branches)
            .filter((branch) => /^\d+\.\d+/.test(branch))
            .sort((a, b) => {
              // バージョン番号でソート
              const aVersion = a.split(".").map((n) => parseInt(n) || 0);
              const bVersion = b.split(".").map((n) => parseInt(n) || 0);
              for (let i = 0; i < Math.max(aVersion.length, bVersion.length); i++) {
                const diff = (bVersion[i] || 0) - (aVersion[i] || 0);
                if (diff !== 0) return diff;
              }
              return 0;
            });
    
          const latestVersionBranch = versionBranches[0];
          const currentVersionInfo = latestVersionBranch
            ? branches[latestVersionBranch]
            : null;
    
          const result = {
            availableVersions: versionBranches.slice(0, 10), // 最新10バージョンを表示
            currentPublic: {
              buildId: publicBranch?.buildid,
              lastUpdated: publicBranch?.timeupdated
                ? formatTimestamp(publicBranch.timeupdated)
                : "Unknown",
              lastUpdatedUnix: publicBranch?.timeupdated,
            },
            gameInfo: {
              appId: STELLARIS_APP_ID,
              developer: appInfo.extended?.developer,
              installDir: appInfo.config?.installdir,
              publisher: appInfo.extended?.publisher,
              supportedOS: appInfo.common?.oslist,
            },
            gameName: appInfo.common?.name || "Stellaris",
            latestVersion: latestVersionBranch
              ? {
                buildId: currentVersionInfo?.buildid,
                description: currentVersionInfo?.description || "説明なし",
                lastUpdated: currentVersionInfo?.timeupdated
                  ? formatTimestamp(currentVersionInfo.timeupdated)
                  : "Unknown",
                lastUpdatedUnix: currentVersionInfo?.timeupdated,
                version: latestVersionBranch,
              }
              : null,
            specialBranches: Object.keys(branches).filter(
              (branch) => !versionBranches.includes(branch) && branch !== "public",
            ),
          };
    
          log.info("Successfully retrieved Stellaris version info", {
            latestVersion: result.latestVersion?.version,
            publicBuildId: result.currentPublic.buildId,
          });
    
          return {
            content: [
              {
                text: `# ステラリス バージョン情報
    
    ## 現在のPublicブランチ
    - **ビルドID**: ${result.currentPublic.buildId}
    - **最終更新**: ${result.currentPublic.lastUpdated}
    
    ${result.latestVersion
                    ? `## 最新バージョン
    - **バージョン**: ${result.latestVersion.version}
    - **ビルドID**: ${result.latestVersion.buildId}
    - **説明**: ${result.latestVersion.description}
    - **最終更新**: ${result.latestVersion.lastUpdated}`
                    : ""
                  }
    
    ## ゲーム情報
    - **ゲーム名**: ${result.gameName}
    - **App ID**: ${result.gameInfo.appId}
    - **インストールディレクトリ**: ${result.gameInfo.installDir}
    - **対応OS**: ${result.gameInfo.supportedOS}
    - **開発者**: ${result.gameInfo.developer}
    - **パブリッシャー**: ${result.gameInfo.publisher}
    
    ## 利用可能なバージョン(最新10件)
    ${result.availableVersions.map((version) => `- ${version}`).join("\n")}
    
    ## 特別なブランチ
    ${result.specialBranches.map((branch) => `- ${branch}`).join("\n")}
    
    ---
    *データ取得元: SteamCMD API (https://api.steamcmd.net/)*`,
                type: "text",
              },
            ],
          };
        } catch (error) {
          const errorMessage =
            error instanceof Error ? error.message : String(error);
          log.error("Failed to fetch Stellaris version info", {
            error: errorMessage,
          });
          throw new Error(
            `ステラリスのバージョン情報の取得に失敗しました: ${errorMessage}`,
          );
        }
      },
      name: "stellaris-version",
      parameters: z.object({}), // パラメータなし
    });
  • The main handler function that executes the tool: fetches Stellaris app info from SteamCMD API, extracts current/latest versions, build IDs, updates, available versions, and formats into a markdown report.
      execute: async (_args, { log }) => {
        try {
          log.info("Fetching Stellaris version info from SteamCMD API...");
    
          const appInfo = (await fetchSteamAppInfo(STELLARIS_APP_ID)) as {
            common?: { name?: string; oslist?: string };
            config?: { installdir?: string };
            depots?: {
              branches?: Record<
                string,
                { buildid?: string; description?: string; timeupdated?: string }
              >;
            };
            extended?: { developer?: string; publisher?: string };
          };
          const branches = appInfo.depots?.branches;
    
          if (!branches) {
            throw new Error("Branch information not found in API response");
          }
    
          const publicBranch = branches.public;
    
          // バージョン番号らしきブランチを抽出(数字.数字.数字の形式)
          const versionBranches = Object.keys(branches)
            .filter((branch) => /^\d+\.\d+/.test(branch))
            .sort((a, b) => {
              // バージョン番号でソート
              const aVersion = a.split(".").map((n) => parseInt(n) || 0);
              const bVersion = b.split(".").map((n) => parseInt(n) || 0);
              for (let i = 0; i < Math.max(aVersion.length, bVersion.length); i++) {
                const diff = (bVersion[i] || 0) - (aVersion[i] || 0);
                if (diff !== 0) return diff;
              }
              return 0;
            });
    
          const latestVersionBranch = versionBranches[0];
          const currentVersionInfo = latestVersionBranch
            ? branches[latestVersionBranch]
            : null;
    
          const result = {
            availableVersions: versionBranches.slice(0, 10), // 最新10バージョンを表示
            currentPublic: {
              buildId: publicBranch?.buildid,
              lastUpdated: publicBranch?.timeupdated
                ? formatTimestamp(publicBranch.timeupdated)
                : "Unknown",
              lastUpdatedUnix: publicBranch?.timeupdated,
            },
            gameInfo: {
              appId: STELLARIS_APP_ID,
              developer: appInfo.extended?.developer,
              installDir: appInfo.config?.installdir,
              publisher: appInfo.extended?.publisher,
              supportedOS: appInfo.common?.oslist,
            },
            gameName: appInfo.common?.name || "Stellaris",
            latestVersion: latestVersionBranch
              ? {
                buildId: currentVersionInfo?.buildid,
                description: currentVersionInfo?.description || "説明なし",
                lastUpdated: currentVersionInfo?.timeupdated
                  ? formatTimestamp(currentVersionInfo.timeupdated)
                  : "Unknown",
                lastUpdatedUnix: currentVersionInfo?.timeupdated,
                version: latestVersionBranch,
              }
              : null,
            specialBranches: Object.keys(branches).filter(
              (branch) => !versionBranches.includes(branch) && branch !== "public",
            ),
          };
    
          log.info("Successfully retrieved Stellaris version info", {
            latestVersion: result.latestVersion?.version,
            publicBuildId: result.currentPublic.buildId,
          });
    
          return {
            content: [
              {
                text: `# ステラリス バージョン情報
    
    ## 現在のPublicブランチ
    - **ビルドID**: ${result.currentPublic.buildId}
    - **最終更新**: ${result.currentPublic.lastUpdated}
    
    ${result.latestVersion
                    ? `## 最新バージョン
    - **バージョン**: ${result.latestVersion.version}
    - **ビルドID**: ${result.latestVersion.buildId}
    - **説明**: ${result.latestVersion.description}
    - **最終更新**: ${result.latestVersion.lastUpdated}`
                    : ""
                  }
    
    ## ゲーム情報
    - **ゲーム名**: ${result.gameName}
    - **App ID**: ${result.gameInfo.appId}
    - **インストールディレクトリ**: ${result.gameInfo.installDir}
    - **対応OS**: ${result.gameInfo.supportedOS}
    - **開発者**: ${result.gameInfo.developer}
    - **パブリッシャー**: ${result.gameInfo.publisher}
    
    ## 利用可能なバージョン(最新10件)
    ${result.availableVersions.map((version) => `- ${version}`).join("\n")}
    
    ## 特別なブランチ
    ${result.specialBranches.map((branch) => `- ${branch}`).join("\n")}
    
    ---
    *データ取得元: SteamCMD API (https://api.steamcmd.net/)*`,
                type: "text",
              },
            ],
          };
        } catch (error) {
          const errorMessage =
            error instanceof Error ? error.message : String(error);
          log.error("Failed to fetch Stellaris version info", {
            error: errorMessage,
          });
          throw new Error(
            `ステラリスのバージョン情報の取得に失敗しました: ${errorMessage}`,
          );
        }
      },
  • Zod schema for tool parameters: empty object as no parameters are required.
    parameters: z.object({}), // パラメータなし
  • Helper function to fetch Steam app information via SteamCMD API, used by the stellaris-version handler.
    async function fetchSteamAppInfo(appId: string): Promise<unknown> {
      const response = await fetchWithRetry(`${STEAMCMD_API_BASE}/info/${appId}`);
      if (!response.ok) {
        throw new Error(
          `Failed to fetch app info: ${response.status} ${response.statusText}`,
        );
      }
      const data = (await response.json()) as {
        data: Record<string, unknown>;
        status: string;
      };
      if (data.status !== "success") {
        throw new Error(`API returned error: ${JSON.stringify(data.data)}`);
      }
      return data.data[appId];
    }
  • Retry utility with exponential backoff for API calls, crucial for reliable SteamCMD and GitHub API access in the handler.
    async function fetchWithRetry(
      url: string,
      options?: RequestInit,
      retryCount = 0,
    ): Promise<Response> {
      try {
        const response = await fetch(url, options);
    
        // レート制限の場合は特別な処理
        if (response.status === 403 && response.statusText.includes("rate limit")) {
          if (retryCount < RETRY_CONFIG.maxRetries) {
            const delay = Math.min(
              RETRY_CONFIG.baseDelay *
              Math.pow(RETRY_CONFIG.backoffMultiplier, retryCount),
              RETRY_CONFIG.maxDelay,
            );
    
            console.log(
              `Rate limit hit, retrying in ${delay}ms (attempt ${retryCount + 1}/${RETRY_CONFIG.maxRetries})`,
            );
            await new Promise((resolve) => setTimeout(resolve, delay));
            return fetchWithRetry(url, options, retryCount + 1);
          }
        }
    
        // 一時的なサーバーエラーの場合もリトライ
        if (response.status >= 500 && response.status < 600) {
          if (retryCount < RETRY_CONFIG.maxRetries) {
            const delay = Math.min(
              RETRY_CONFIG.baseDelay *
              Math.pow(RETRY_CONFIG.backoffMultiplier, retryCount),
              RETRY_CONFIG.maxDelay,
            );
    
            console.log(
              `Server error ${response.status}, retrying in ${delay}ms (attempt ${retryCount + 1}/${RETRY_CONFIG.maxRetries})`,
            );
            await new Promise((resolve) => setTimeout(resolve, delay));
            return fetchWithRetry(url, options, retryCount + 1);
          }
        }
    
        return response;
      } catch (error) {
        // ネットワークエラーの場合もリトライ
        if (retryCount < RETRY_CONFIG.maxRetries) {
          const delay = Math.min(
            RETRY_CONFIG.baseDelay *
            Math.pow(RETRY_CONFIG.backoffMultiplier, retryCount),
            RETRY_CONFIG.maxDelay,
          );
    
          console.log(
            `Network error, retrying in ${delay}ms (attempt ${retryCount + 1}/${RETRY_CONFIG.maxRetries}):`,
            error instanceof Error ? error.message : String(error),
          );
          await new Promise((resolve) => setTimeout(resolve, delay));
          return fetchWithRetry(url, options, retryCount + 1);
        }
    
        throw error;
      }
    }
Behavior4/5

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

Annotations provide readOnlyHint=true and openWorldHint=true, indicating this is a safe read operation with no side effects. The description adds valuable context beyond annotations by specifying what information is retrieved (build ID, last update time, version numbers) and its purpose for modding. It does not contradict annotations, as '取得します' (get) aligns with read-only behavior. However, it lacks details on rate limits or authentication needs, though these may not be critical for this tool.

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

Conciseness5/5

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

The description is concise and well-structured in two sentences: the first states the core purpose, and the second elaborates on the specific information provided. Every sentence adds value by clarifying scope and utility, with no wasted words or redundancy. It is front-loaded with the main action.

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

Completeness4/5

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

Given the tool's simplicity (0 parameters, read-only annotations, no output schema), the description is complete enough for an agent to understand its function and use case. It covers what the tool does, what information it returns, and the context (modding). However, without an output schema, it could benefit from more detail on the return format, though the annotations and lack of parameters mitigate this gap.

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

Parameters4/5

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

The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description appropriately does not discuss parameters, focusing instead on the tool's output and purpose. This meets the baseline for tools with no parameters, as it avoids unnecessary repetition of schema information.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'ステラリスの現在のバージョン情報を取得します' (Get current version information for Stellaris). It specifies the verb '取得します' (get/retrieve) and resource 'バージョン情報' (version information), and distinguishes from siblings by mentioning modding-specific details like build ID, last update time, and version numbers, which none of the sibling tools (cwtools-config, stellaris-search, stellaris-validate) appear to cover.

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 implies usage context by stating it provides 'modding に必要な情報' (information necessary for modding), suggesting this tool is for modding-related tasks. However, it does not explicitly state when to use this tool versus alternatives like stellaris-search or stellaris-validate, nor does it provide exclusions or prerequisites. The guidance is present but not comprehensive.

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

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/kongyo2/Stellaris-Modding-MCP-Server'

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