Skip to main content
Glama
Luminaire1337

MTA:SA Documentation MCP Server

search_functions

Search MTA:SA functions and events by name or keyword to find canonical function names with side and category information.

Instructions

Primary discovery tool. Search MTA:SA functions and events by name or keyword before coding. Returns canonical function names with side/category so LLMs can reliably chain into docs tools.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesFunction name or partial name to search for
sideNoFilter by client-side, server-side, or shared functions
limitNoMaximum number of results

Implementation Reference

  • src/index.ts:90-133 (registration)
    Registration of the 'search_functions' tool via server.registerTool, with inputSchema and handler callback.
    // Register tool: search_functions
    server.registerTool(
      "search_functions",
      {
        description:
          "Primary discovery tool. Search MTA:SA functions and events by name or keyword before coding. Returns canonical function names with side/category so LLMs can reliably chain into docs tools.",
        inputSchema: {
          query: z.string().describe("Function name or partial name to search for"),
          side: z
            .enum(["client", "server", "shared"])
            .optional()
            .describe("Filter by client-side, server-side, or shared functions"),
          limit: z
            .number()
            .int()
            .min(1)
            .max(200)
            .optional()
            .default(30)
            .describe("Maximum number of results"),
        },
      },
      async ({ query, side, limit }): Promise<CallToolResult> => {
        const results = searchFunctions(query, side, limit);
        const formatted =
          results.length > 0
            ? results.map((f) => `${f.name} [${f.side}] - ${f.category}`).join("\n")
            : "No entries found.";
    
        const nextSteps =
          results.length > 0
            ? "\n\nNext: call `get_function_docs` for one entry or `get_multiple_function_docs` for several results from this list."
            : "\n\nTip: try broader keywords (e.g., database, gui, dx, event, vehicle) or use `find_functions_for_task`.";
    
        return {
          content: [
            {
              type: "text",
              text: `Found ${results.length} MTA:SA functions/events:\n\n${formatted}${nextSteps}`,
            },
          ],
        };
      },
    );
  • Handler logic for search_functions: calls searchFunctions() from queries, formats results, returns text response with next steps.
    async ({ query, side, limit }): Promise<CallToolResult> => {
      const results = searchFunctions(query, side, limit);
      const formatted =
        results.length > 0
          ? results.map((f) => `${f.name} [${f.side}] - ${f.category}`).join("\n")
          : "No entries found.";
    
      const nextSteps =
        results.length > 0
          ? "\n\nNext: call `get_function_docs` for one entry or `get_multiple_function_docs` for several results from this list."
          : "\n\nTip: try broader keywords (e.g., database, gui, dx, event, vehicle) or use `find_functions_for_task`.";
    
      return {
        content: [
          {
            type: "text",
            text: `Found ${results.length} MTA:SA functions/events:\n\n${formatted}${nextSteps}`,
          },
        ],
      };
    },
  • Helper function searchFunctions() that executes the SQL query via queries.searchMetadata() with LIKE pattern matching and side filter.
    // Helper to execute metadata search
    export const searchFunctions = (
      query: string,
      side?: MtasaSide,
      limit: number = 30,
    ): MtasaFunction[] => {
      const safeLimit = clampLimit(limit, 30, 200);
      const trimmedQuery = query.trim();
      const searchPattern = `%${trimmedQuery}%`;
      const rows = queries
        .searchMetadata()
        .all(searchPattern, side || null, side || null, safeLimit);
      return rows as MtasaFunction[];
    };
  • SQL query definition for metadata search (searchMetadata): SELECT with LIKE, side filtering, and case-insensitive ordering.
    searchMetadata: () =>
      db.prepare(`
      SELECT * FROM function_metadata 
      WHERE name LIKE ? 
      AND (? IS NULL OR side = ? OR side = 'shared')
      ORDER BY name COLLATE NOCASE
      LIMIT ?
    `),
  • Type definitions: MtasaSide enum and MtasaFunction interface returned by search_functions.
    export type MtasaSide = "client" | "server" | "shared";
    
    export interface MtasaFunction {
      name: string;
      type: number;
      category: string;
      side: MtasaSide;
    }
Behavior4/5

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

With no annotations, the description takes full responsibility. It states it returns canonical function names with side/category, implying a read-only search. No mention of rate limits or pagination, but the purpose is transparent and non-destructive.

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?

Two focused sentences with no wasted words. Front-loads the primary purpose and ends with a clear outcome statement.

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?

Though no output schema, the description adequately describes return content (canonical names with side/category). It covers the tool's role in a workflow. Minor gaps: no mention of no-results behavior or limit parameter, but sufficient for a search tool.

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 coverage is 100%, so the schema already documents all parameters. The description adds contextual value but no parameter-specific details beyond what the schema provides, meeting the baseline for high coverage.

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 action (search), resource (MTA:SA functions and events), and value (returns canonical names with side/category for chaining). It distinguishes itself as the 'primary discovery tool' before coding, setting it apart from sibling documentation tools.

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?

The description explicitly guides usage 'before coding' and hints at chaining into docs tools. It doesn't specify when not to use or alternatives, but the context is clear enough for an agent to understand it's the first step.

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/Luminaire1337/mtasa-docs-mcp'

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