Skip to main content
Glama

generate

Create structured JSON constraints that keep an LLM character's voice consistent by specifying four personality axes and optional sliders.

Instructions

Generate character constraints using the FIVE engine.

This tool calls the FIVE Character Engine API to produce JSON constraints that keep an LLM character's voice consistent.

Each call costs $1 and consumes one credit from your account.

Args: character_name: Name of the character to generate constraints for. q1: Personality axis 1 – choose A, B, C, or D. q2: Personality axis 2 – choose A, B, C, or D. q3: Personality axis 3 – choose A, B, C, or D. q4: Personality axis 4 – choose A, B, C, or D. s1: Style slider 1 (1-5, default 3). Optional fine-tuning. s2: Style slider 2 (1-5, default 3). Optional fine-tuning. s3: Style slider 3 (1-5, default 3). Optional fine-tuning. s4: Style slider 4 (1-5, default 3). Optional fine-tuning. free_text: Optional free-form description to further guide generation.

Returns: A dict with keys: status, remaining (credits left), constraint (the generated JSON constraint object).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
character_nameYes
q1Yes
q2Yes
q3Yes
q4Yes
s1No
s2No
s3No
s4No
free_textNo

Implementation Reference

  • The `generate` async function is the tool handler. It collects character_name, four personality axes (q1-q4), optional style sliders (s1-s4), and free_text, then POSTs them to the FIVE /generate endpoint, handling auth/credit/rate-limit errors.
    @mcp.tool()
    async def generate(
        character_name: str,
        q1: ChoiceABCD,
        q2: ChoiceABCD,
        q3: ChoiceABCD,
        q4: ChoiceABCD,
        s1: Optional[ScaleValue] = None,
        s2: Optional[ScaleValue] = None,
        s3: Optional[ScaleValue] = None,
        s4: Optional[ScaleValue] = None,
        free_text: Optional[str] = None,
    ) -> dict:
        """Generate character constraints using the FIVE engine.
    
        This tool calls the FIVE Character Engine API to produce JSON
        constraints that keep an LLM character's voice consistent.
    
        Each call costs $1 and consumes one credit from your account.
    
        Args:
            character_name: Name of the character to generate constraints for.
            q1: Personality axis 1 – choose A, B, C, or D.
            q2: Personality axis 2 – choose A, B, C, or D.
            q3: Personality axis 3 – choose A, B, C, or D.
            q4: Personality axis 4 – choose A, B, C, or D.
            s1: Style slider 1 (1-5, default 3). Optional fine-tuning.
            s2: Style slider 2 (1-5, default 3). Optional fine-tuning.
            s3: Style slider 3 (1-5, default 3). Optional fine-tuning.
            s4: Style slider 4 (1-5, default 3). Optional fine-tuning.
            free_text: Optional free-form description to further guide generation.
    
        Returns:
            A dict with keys: status, remaining (credits left), constraint (the
            generated JSON constraint object).
        """
        api_key = _get_api_key()
    
        payload: dict = {
            "character_name": character_name,
            "q1": q1,
            "q2": q2,
            "q3": q3,
            "q4": q4,
        }
        # Only send optional fields when explicitly provided
        if s1 is not None:
            payload["s1"] = s1
        if s2 is not None:
            payload["s2"] = s2
        if s3 is not None:
            payload["s3"] = s3
        if s4 is not None:
            payload["s4"] = s4
        if free_text is not None:
            payload["free_text"] = free_text
    
        async with httpx.AsyncClient(timeout=TIMEOUT) as client:
            resp = await client.post(
                FIVE_API_URL,
                json=payload,
                headers={
                    "Authorization": f"Bearer {api_key}",
                    "Content-Type": "application/json",
                },
            )
    
        if resp.status_code == 401:
            raise RuntimeError(
                "Authentication failed. Check your FIVE_API_KEY."
            )
        if resp.status_code == 402:
            raise RuntimeError(
                "Insufficient credits. Top up at https://fiveengine.dev"
            )
        if resp.status_code == 429:
            raise RuntimeError(
                "Rate limited. Please wait a moment and try again."
            )
    
        resp.raise_for_status()
        return resp.json()
  • Type aliases used as input schemas for the generate tool: ChoiceABCD (Literal 'A'|'B'|'C'|'D') for personality axes, and ScaleValue (Literal 1-5) for style sliders.
    ChoiceABCD = Literal["A", "B", "C", "D"]
    ScaleValue = Literal[1, 2, 3, 4, 5]
  • The `@mcp.tool()` decorator registers the `generate` function as an MCP tool on the FastMCP server instance.
    @mcp.tool()
    async def generate(
  • Helper function that reads the FIVE_API_KEY environment variable and raises a clear RuntimeError if it's missing. Used by the generate handler.
    def _get_api_key() -> str:
        """Read API key from environment; abort clearly if missing."""
        key = os.environ.get("FIVE_API_KEY", "")
        if not key:
            raise RuntimeError(
                "FIVE_API_KEY is not set. "
                "Get your key at https://fiveengine.dev and set it as an "
                "environment variable (e.g. FIVE_API_KEY=five_sk_xxx)."
            )
        return key
Behavior4/5

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

With no annotations, the description carries full burden and reveals key behaviors: calls an external API, costs $1 per call, consumes credits, returns a dict with status/remaining/constraint. It does not detail error handling or rate limits, but the main behavioral traits are well covered.

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 structured with a brief intro, cost note, Args list, and Returns summary. It is not overly verbose; each sentence serves a purpose. However, the Args section could be slightly more compact, but overall it is well-organized and front-loaded.

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 complexity (10 parameters, no annotations, no output schema), the description is largely complete: it explains the tool's purpose, cost, parameter semantics, and return format. It lacks details on error scenarios or edge cases, but the core information is sufficient for correct use.

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

Parameters5/5

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

The schema has 0% description coverage, so the description fully compensates by explaining all 10 parameters: character_name as the character, q1-q4 as personality axes with options A-D, s1-s4 as style sliders with range 1-5 and defaults, and free_text as optional free-form input. This adds significant context beyond the schema's type/enum definitions.

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 verb 'Generate' and the resource 'character constraints using the FIVE engine', and explains the purpose: to keep an LLM character's voice consistent. There are no sibling tools to differentiate, but the purpose is specific and unambiguous.

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 for generating character constraints but does not provide explicit when-to-use or when-not-to-use guidance. The cost disclosure ($1 per call) serves as a caution, but no exclusions or alternatives are mentioned, which is acceptable given no siblings.

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/kiro0x/five-mcp'

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