Skip to main content
Glama

Match Water Profile

match_water_profile

Find brewing water profiles by entering a city name or beer style. Returns mineral composition and style recommendations.

Instructions

Find brewing water profiles by city name or beer style. Returns mineral composition (Ca, Mg, Na, Cl, SO4, HCO3) and style recommendations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesCity name or beer style to find water profile for

Implementation Reference

  • The main handler function 'registerMatchWaterProfile' that registers the 'match_water_profile' tool on the MCP server. It implements a 3-strategy search: (1) fuzzy search water profiles by name/city, (2) fuzzy search by bestFor (style) field, (3) search styles and cross-reference with water profiles. Returns formatted text with mineral composition and style recommendations.
    export function registerMatchWaterProfile(server: McpServer): void {
      server.registerTool(
        "match_water_profile",
        {
          title: "Match Water Profile",
          description:
            "Find brewing water profiles by city name or beer style. Returns mineral composition (Ca, Mg, Na, Cl, SO4, HCO3) and style recommendations.",
          inputSchema: {
            query: z
              .string()
              .describe("City name or beer style to find water profile for"),
          },
        },
        async ({ query }) => {
          // Strategy 1: search water profiles by name/city
          let results = fuzzySearch(WATER_PROFILES, query, ["name", "city"]);
    
          // Strategy 2: if no direct match, search by bestFor (style name)
          if (results.length === 0 && query.trim()) {
            results = fuzzySearch(WATER_PROFILES, query, ["bestFor"]);
          }
    
          // Strategy 3: if still no match, search styles first, then find water profiles for those styles
          if (results.length === 0 && query.trim()) {
            const matchedStyles = fuzzySearch(STYLES, query, ["name", "category"]);
            if (matchedStyles.length > 0) {
              const styleNames = matchedStyles.map((s) => s.name.toLowerCase());
              results = WATER_PROFILES.filter((wp) =>
                wp.bestFor.some((bf) =>
                  styleNames.some((sn) => bf.toLowerCase().includes(sn) || sn.includes(bf.toLowerCase())),
                ),
              );
            }
          }
    
          if (results.length === 0) {
            return {
              content: [
                {
                  type: "text" as const,
                  text: `No water profiles found matching '${query}'. Try a city name (e.g. 'Burton', 'Dublin') or beer style (e.g. 'IPA', 'Pilsner').`,
                },
              ],
            };
          }
    
          return {
            content: [
              {
                type: "text" as const,
                text: results.map(formatProfile).join("\n\n---\n\n"),
              },
            ],
          };
        },
      );
    }
  • Input schema for the 'match_water_profile' tool. Uses Zod to define a single required string parameter 'query' described as 'City name or beer style to find water profile for'.
    {
      title: "Match Water Profile",
      description:
        "Find brewing water profiles by city name or beer style. Returns mineral composition (Ca, Mg, Na, Cl, SO4, HCO3) and style recommendations.",
      inputSchema: {
        query: z
          .string()
          .describe("City name or beer style to find water profile for"),
      },
  • Import statement that pulls in the registerMatchWaterProfile function from the tools module.
    import { registerMatchWaterProfile } from "./tools/match-water-profile.js";
  • Registration call that passes the MCP server instance to registerMatchWaterProfile, wiring the tool into the server.
    registerMatchWaterProfile(server);
  • Helper function 'formatProfile' that formats a WaterProfile object into a human-readable Markdown string including name, city, mineral composition (Ca, Mg, Na, Cl, SO4, HCO3), sulfate:chloride ratio, description, and style recommendations.
    function formatProfile(wp: WaterProfile): string {
      const ratio =
        wp.chloride > 0
          ? (wp.sulfate / wp.chloride).toFixed(1)
          : wp.sulfate > 0
            ? "∞"
            : "0.0";
      return [
        `## ${wp.name} (${wp.city})`,
        `Ca: ${wp.calcium} | Mg: ${wp.magnesium} | Na: ${wp.sodium}`,
        `Cl: ${wp.chloride} | SO4: ${wp.sulfate} | HCO3: ${wp.bicarbonate}`,
        `Sulfate:Chloride ratio: ${ratio}`,
        "",
        wp.description,
        "",
        `Best for: ${wp.bestFor.join(", ")}`,
      ].join("\n");
    }
Behavior4/5

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

Despite no annotations, the description discloses the tool returns mineral composition and style recommendations. It implies a read-only lookup without side effects, which is sufficient for this type of 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?

Single sentence efficiently conveys purpose, input, and output. No unnecessary words.

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?

For a simple lookup with one parameter and no output schema, the description adequately explains functionality and return content. Could mention format or multiple results, but not essential.

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?

Schema coverage is 100% with one parameter clearly documented. The description reinforces that 'query' accepts city name or beer style, adding context beyond the schema by mentioning the output composition.

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?

Clearly states it finds brewing water profiles by city or beer style, and returns mineral composition and style recommendations. Distinct from sibling tools which cover off-flavors, pairings, ingredients, styles, and recipes.

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?

Implicitly guides usage: when you need water profile information based on city or style. No exclusion criteria or alternatives mentioned, but context from sibling tools makes it clear.

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/gregario/brewers-almanack'

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