Skip to main content
Glama

lookup_function

Look up an LSL function by name to retrieve its full record, including signature, parameters, return type, and AI pitfalls. Uses fuzzy matching if exact name is not found.

Instructions

Look up an LSL function by name.

Returns the full function record: signature, parameters, return type, delay, energy cost, caveats, examples, related functions, and any known AI-specific pitfalls associated with this function.

Falls back to fuzzy matching if the exact name is not found, and returns a 'did_you_mean' list when no match exists at all — helping catch hallucinated function names.

Args: name: Function name, e.g. "llListen" or "llReplaceSubString".

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYes

Implementation Reference

  • server.py:86-103 (registration)
    MCP tool registration via @mcp.tool() decorator. Delegates to lsl_lookup_function() in tools/lookup.py.
    @mcp.tool()
    def lookup_function(name: str) -> dict:
        """
        Look up an LSL function by name.
    
        Returns the full function record: signature, parameters, return type,
        delay, energy cost, caveats, examples, related functions, and any known
        AI-specific pitfalls associated with this function.
    
        Falls back to fuzzy matching if the exact name is not found, and returns
        a 'did_you_mean' list when no match exists at all — helping catch
        hallucinated function names.
    
        Args:
            name: Function name, e.g. "llListen" or "llReplaceSubString".
        """
        log.info("lookup_function(%r)", name)
        return lsl_lookup_function(name)
  • Core handler that queries the SQLite DB with exact match, prefix match, and substring fallback. Returns full function record or error with 'did_you_mean' suggestions.
    def lsl_lookup_function(name: str) -> dict:
        """
        Look up an LSL function by name.
    
        Tries an exact match first, then falls back to a case-insensitive prefix
        match, then a LIKE search. Returns the full function record including
        parameters, caveats, examples, related functions, and any known AI pitfalls
        associated with this function.
    
        If the name does not match any real LSL function, returns an error dict
        with a 'did_you_mean' list of close matches.
    
        Args:
            name: The function name to look up, e.g. "llListen" or "lllisten".
    
        Returns:
            dict with keys: name, signature, return_type, description, parameters,
            delay, energy_cost, mono_only, deprecated, caveats, examples, related,
            permissions_required, scope, known_ai_pitfalls.
            On failure: {"error": str, "did_you_mean": list[str]}
        """
        con = _connect()
    
        # 1. Exact match (case-insensitive)
        row = con.execute(
            "SELECT * FROM functions WHERE lower(name) = lower(?)", (name,)
        ).fetchone()
    
        # 2. Prefix match
        if not row:
            row = con.execute(
                "SELECT * FROM functions WHERE lower(name) LIKE lower(?)",
                (name.rstrip("%") + "%",),
            ).fetchone()
    
        # 3. Substring match
        if not row:
            row = con.execute(
                "SELECT * FROM functions WHERE lower(name) LIKE lower(?)",
                (f"%{name}%",),
            ).fetchone()
    
        if not row:
            # Suggest close matches via FTS
            suggestions = con.execute(
                "SELECT name FROM functions_fts WHERE name MATCH ? LIMIT 5",
                (name,),
            ).fetchall()
            return {
                "error": f"No LSL function found matching '{name}'.",
                "did_you_mean": [s["name"] for s in suggestions],
            }
    
        return _hydrate_function(con, row)
  • Helper that hydrates a full function record from the DB, fetching parameters, caveats, examples, related functions, permissions, scope entries, and known AI pitfalls.
    def _hydrate_function(con: sqlite3.Connection, row: sqlite3.Row) -> dict:
        """
        Given a functions row, fetch all child records and return a complete dict.
        """
        fid = row["id"]
    
        params = con.execute(
            """
            SELECT position, name, type, description
            FROM function_parameters
            WHERE function_id = ?
            ORDER BY position
            """,
            (fid,),
        ).fetchall()
    
        caveats = con.execute(
            "SELECT caveat FROM function_caveats WHERE function_id = ?", (fid,)
        ).fetchall()
    
        examples = con.execute(
            "SELECT example FROM function_examples WHERE function_id = ?", (fid,)
        ).fetchall()
    
        related = con.execute(
            "SELECT related_name FROM function_related WHERE function_id = ?", (fid,)
        ).fetchall()
    
        permissions = con.execute(
            "SELECT permission FROM function_permissions WHERE function_id = ?", (fid,)
        ).fetchall()
    
        scope = con.execute(
            "SELECT scope, allowed FROM function_scope WHERE function_id = ?", (fid,)
        ).fetchall()
    
        pitfalls = con.execute(
            """
            SELECT id, category, title, bad_example, good_example, notes, ai_source
            FROM pitfalls
            WHERE category = 'nonexistent_functions'
               OR (bad_example LIKE '%' || ? || '%')
            """,
            (row["name"],),
        ).fetchall()
    
        return {
            "name":          row["name"],
            "signature":     row["signature"],
            "return_type":   row["return_type"],
            "description":   row["description"],
            "delay":         row["delay"],
            "energy_cost":   row["energy_cost"],
            "mono_only":     bool(row["mono_only"]),
            "deprecated":    bool(row["deprecated"]),
            "since_version": row["since_version"],
            "parameters": [
                {
                    "position":    p["position"],
                    "name":        p["name"],
                    "type":        p["type"],
                    "description": p["description"],
                }
                for p in params
            ],
            "caveats":              [c["caveat"] for c in caveats],
            "examples":             [e["example"] for e in examples],
            "related":              [r["related_name"] for r in related],
            "permissions_required": [p["permission"] for p in permissions],
            "scope":                [{"scope": s["scope"], "allowed": bool(s["allowed"])} for s in scope],
            "known_ai_pitfalls": [
                {
                    "id":          p["id"],
                    "category":    p["category"],
                    "title":       p["title"],
                    "bad_example": p["bad_example"],
                    "good_example": p["good_example"],
                    "notes":       p["notes"],
                    "ai_source":   p["ai_source"],
                }
                for p in pitfalls
            ],
        }
Behavior5/5

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

Discloses fuzzy matching, 'did_you_mean' list, and full return record (signature, parameters, etc.), fully informing the agent of behavior without annotations.

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?

Concise with clear bullet-like listing of return fields; every sentence adds value without redundancy.

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

Completeness5/5

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

Complete for a single-parameter tool without output schema; covers return content, fallback, and examples adequately.

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?

Provides concrete examples like 'llListen' and 'llReplaceSubString,' adding value beyond the schema, though schema coverage is 0%.

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 'Look up an LSL function by name,' distinguishing it from sibling 'search_functions' by emphasizing exact lookup and fuzzy fallback.

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

Usage Guidelines4/5

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

Indicates use for exact names with fallback and 'did_you_mean' for non-matches, but doesn't explicitly contrast with 'search_functions' or specify when not to use.

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/Treeeeeeeeeeeeee/second-life-mcp-server'

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