Skip to main content
Glama

decode_level_from_url

Extract and visualize VibeTide 2D platformer level data from encoded URL strings to enable sharing and editing of game levels.

Instructions

Decode a VibeTide level from an encoded URL string.

Args:
    encoded_level: The encoded level string from a URL or sharing link

Returns the decoded level data with visualization.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
encoded_levelYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary implementation of the decode_level_from_url MCP tool handler. Uses the global level_encoder to decode the input string, generates ASCII visualization, builds play URL, and returns structured response.
    @mcp.tool()
    async def decode_level_from_url(encoded_level: str) -> Dict[str, Any]:
        """Decode a VibeTide level from an encoded URL string.
    
        Args:
            encoded_level: The encoded level string from a URL or sharing link
    
        Returns the decoded level data with visualization.
        """
        try:
            level_data = level_encoder.decode(encoded_level)
            visualization = visualize_level(level_data)
            play_url = f"{VIBE_TIDE_CONFIG['web_player_url']}?level={encoded_level}"
    
            return {
                "success": True,
                "level_data": level_data,
                "visualization": visualization,
                "play_url": play_url,
                "encoded_level": encoded_level,
                "message": f"Successfully decoded level: {level_data.get('name', 'Unnamed Level')}",
            }
    
        except Exception as e:
            logger.error(f"Failed to decode level: {e}")
            return {"success": False, "error": f"Failed to decode level: {str(e)}"}
  • Core helper method in LevelEncoder class that implements the decoding logic: base64url decode, parse dimensions and params, RLE decode, reconstruct 2D tiles, generate name from analysis.
    def decode(self, encoded_string: str) -> Dict[str, Any]:
        """Decode URL-safe string back to level data"""
        try:
            encoded_string = encoded_string.strip()
            if not encoded_string:
                raise ValueError("Empty encoded string")
    
            # Decode from base64url
            decoded = self._base64url_decode(encoded_string)
    
            # Parse parameters if present
            main_data = decoded
            game_params = {}
    
            if "|" in decoded:
                parts = decoded.split("|", 1)
                if len(parts) == 2:
                    main_data, params_data = parts
                    try:
                        params_json = self._base64url_decode(params_data)
                        game_params = json.loads(params_json)
                    except Exception as e:
                        logger.warning(f"Failed to parse parameters: {e}")
    
            # Parse format: widthxheight:encoded_data
            if ":" not in main_data:
                raise ValueError("Invalid format: missing colon")
    
            dimensions, tile_data = main_data.split(":", 1)
    
            if "x" not in dimensions:
                raise ValueError("Invalid format: missing dimensions")
    
            width, height = map(int, dimensions.split("x"))
    
            if width < 1 or height < 1:
                raise ValueError(f"Invalid dimensions: {width}x{height}")
    
            # Decode run-length encoding
            tile_string = self._run_length_decode(tile_data)
    
            # Convert back to 2D array
            tiles = []
            index = 0
    
            for y in range(height):
                tiles.append([])
                for x in range(width):
                    char = tile_string[index] if index < len(tile_string) else "."
                    tiles[y].append(self.char_tiles.get(char, 0))
                    index += 1
    
            result = {
                "tiles": tiles,
                "width": width,
                "height": height,
                "name": self._generate_level_name(tiles),
            }
    
            # Add game parameters
            for param in ["maxEnemies", "enemySpawnChance", "coinSpawnChance"]:
                if param in game_params:
                    result[param] = game_params[param]
    
            return result
    
        except Exception as e:
            logger.error(f"Failed to decode level: {e}")
            raise ValueError(f"Level decoding failed: {str(e)}")
  • Server startup logging that lists the decode_level_from_url tool as available.
    logger.info("  - decode_level_from_url: Decode level from URL")
    logger.info("  - get_tile_reference: Get tile type reference")
  • setup_mcp.py:288-288 (registration)
    Setup script prints list of available tools including decode_level_from_url.
    print("- decode_level_from_url: Decode levels from sharing URLs")
Behavior2/5

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

No annotations are provided, so the description carries the full burden. It states the tool returns 'decoded level data with visualization,' which adds some behavioral context about the output. However, it lacks details on potential errors (e.g., invalid URLs), performance aspects, or side effects, which are important for a decoding operation with no annotation coverage.

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 well-structured and concise: a clear purpose statement followed by brief Arg and Return sections. Every sentence adds value without redundancy. It could be slightly more front-loaded by integrating the return info into the main statement, but overall it's efficient.

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 moderate complexity (decoding from URLs), the description covers the core purpose and parameter semantics adequately. The presence of an output schema means the description doesn't need to detail return values, and it appropriately focuses on the decoding process. It could improve by addressing error cases or sibling differentiation.

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 description adds meaningful context for the single parameter: 'encoded_level' is described as 'The encoded level string from a URL or sharing link.' This clarifies the parameter's purpose and format beyond the schema's minimal title ('Encoded Level') and 0% coverage. With only one parameter, this provides adequate semantic value.

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 purpose: 'Decode a VibeTide level from an encoded URL string.' It specifies the verb ('decode'), resource ('VibeTide level'), and source ('encoded URL string'). However, it doesn't explicitly differentiate from siblings like 'view_level' or 'play_level' beyond the URL decoding aspect.

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 mentioning 'URL or sharing link,' suggesting this tool is for processing shared/encoded levels rather than direct access. However, it doesn't provide explicit guidance on when to use this versus alternatives like 'view_level' or 'play_level,' nor does it mention any exclusions or prerequisites.

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/banjtheman/vibe_tide_mcp'

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