Phase5 nl-to-tools-mapper

This skill should be used when guiding the OpenAI agent to map natural language user input to appropriate MCP tools, handling phrases like "Add task" → add_task, "List pending" → list_tasks(status="pending"), tool chains, and extracting user email from JWT.

install
source · Clone the upstream repo
git clone https://github.com/SyedaNabila559/phase5
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/SyedaNabila559/phase5 "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/nl-to-tools-mapper" ~/.claude/skills/syedanabila559-phase5-nl-to-tools-mapper && rm -rf "$T"
manifest: .claude/skills/nl-to-tools-mapper/SKILL.md
source content

NL to Tools Mapper Skill

This skill provides guidance for mapping natural language input to MCP tools and extracting user context from JWT.

Purpose

Guide the agent to map user input to tools:

  • "Add task" → add_task
  • "List pending" → list_tasks(status="pending")
  • Handle tool chains (list then delete)
  • Extract user email from JWT, respond in natural language

When to Use

Use this skill when:

  • Configuring agent instructions for tool mapping
  • Building natural language understanding for task commands
  • Implementing multi-step tool chains
  • Extracting user identity from authentication

Capabilities

  • NL Mapping: Convert natural language to tool calls
  • Intent Recognition: Identify user intent (add, list, complete, delete, update)
  • Parameter Extraction: Pull relevant details from user input
  • Tool Chaining: Execute multiple tools in sequence
  • User Context: Extract and use JWT claims

Agent System Prompt

SYSTEM_PROMPT = """You are a helpful task management assistant. You help users manage their tasks using the available tools.

## Your Capabilities

1. **Adding Tasks**: When user says "add task", "create task", "new task":
   - Use add_task tool
   - Extract title from user input
   - Ask for description if not provided
   - Set priority (default: 1) and due_date if mentioned

2. **Listing Tasks**: When user says "list tasks", "show my tasks":
   - Use list_tasks tool
   - Filter by status if specified ("pending", "completed")
   - Filter by priority if specified

3. **Completing Tasks**: When user says "complete task", "done":
   - Use complete_task tool
   - Extract task ID from context or ask user

4. **Deleting Tasks**: When user says "delete task", "remove task":
   - Use delete_task tool
   - Confirm before deleting

5. **Updating Tasks**: When user says "update task", "edit task":
   - Use update_task tool
   - Ask what fields to update

## Important Rules

- **Always respond in natural language**
- **Always use the user's email when available**
- **Confirm actions before executing destructive operations**
- **If unsure, ask for clarification**

## User Context

Your user is: {user_email}
All tasks you manage belong to this user.
"""

Intent Recognition Pattern

from enum import Enum
from typing import Optional
import re

class Intent(Enum):
    ADD_TASK = "add_task"
    LIST_TASKS = "list_tasks"
    COMPLETE_TASK = "complete_task"
    DELETE_TASK = "delete_task"
    UPDATE_TASK = "update_task"
    UNKNOWN = "unknown"

INTENT_PATTERNS = {
    Intent.ADD_TASK: [
        r"add\s+(a\s+)?task",
        r"create\s+(a\s+)?task",
        r"new\s+task",
        r"i\s+need\s+to.*task",
        r"remind\s+me\s+to"
    ],
    Intent.LIST_TASKS: [
        r"list\s+(all\s+)?tasks",
        r"show\s+(me\s+)?(my\s+)?tasks",
        r"what('s|\s+is)\s+(my\s+)?tasks",
        r"get\s+(my\s+)?tasks"
    ],
    Intent.COMPLETE_TASK: [
        r"complete\s+task",
        r"mark\s+.*\s+done",
        r".*task\s+is\s+done",
        r"finished?\s+task"
    ],
    Intent.DELETE_TASK: [
        r"delete\s+task",
        r"remove\s+task",
        r"cancel\s+task"
    ],
    Intent.UPDATE_TASK: [
        r"update\s+task",
        r"edit\s+task",
        r"change\s+.*\s+task",
        r"modify\s+task"
    ]
}

def detect_intent(message: str) -> Intent:
    """Detect user intent from natural language."""
    message_lower = message.lower()

    for intent, patterns in INTENT_PATTERNS.items():
        for pattern in patterns:
            if re.search(pattern, message_lower):
                return intent

    return Intent.UNKNOWN

Parameter Extraction

from typing import Optional, Dict, Any
import re

def extract_task_params(message: str, intent: Intent) -> Dict[str, Any]:
    """Extract tool parameters from user input."""
    params = {}

    if intent == Intent.ADD_TASK:
        # Extract title
        title_match = re.search(
            r"(?:add|create|new)\s+(?:a\s+)?(?:task\s+)?(?:to\s+)?(?:my\s+)?(.+)",
            message,
            re.IGNORECASE
        )
        if title_match:
            params["title"] = title_match.group(1).strip()

        # Extract priority
        priority_match = re.search(r"priority\s*[:=]?\s*(\d+)", message)
        if priority_match:
            params["priority"] = int(priority_match.group(1))

        # Extract due date
        due_match = re.search(
            r"(?:due|by|on)\s+((?:\w+\s+)?\d{1,2}(?:st|nd|rd|th)?(?:\s+\w+)?(?:\s+\d{4})?)",
            message,
            re.IGNORECASE
        )
        if due_match:
            params["due_date"] = due_match.group(1)

    elif intent == Intent.LIST_TASKS:
        if "pending" in message.lower():
            params["status"] = "pending"
        elif "completed" in message.lower():
            params["status"] = "completed"

    return params

Tool Chain Handling

async def handle_tool_chain(
    user_id: str,
    message: str
) -> Dict[str, Any]:
    """Handle complex multi-step operations."""
    intent = detect_intent(message)
    params = extract_task_params(message, intent)

    # Example: "List my pending tasks and delete the first one"
    if "list" in message.lower() and "delete" in message.lower():
        # Step 1: List tasks
        tasks = await list_tasks(user_id=user_id, status="pending")

        if tasks and len(tasks) > 0:
            # Step 2: Delete first task
            first_task_id = tasks[0]["id"]
            result = await delete_task(user_id=user_id, task_id=first_task_id)

            return {
                "response": f"I found {len(tasks)} pending tasks and deleted the first one: '{tasks[0]['title']}'",
                "chain_steps": ["list_tasks", "delete_task"],
                "executed": True
            }

    # Single tool call
    return await route_to_tool(intent, user_id, params)

JWT User Extraction

from typing import Optional
import jwt

async def get_user_from_jwt(authorization: Optional[str]) -> Optional[dict]:
    """Extract user info from JWT token."""
    if not authorization:
        return None

    try:
        token = authorization.replace("Bearer ", "")
        payload = jwt.decode(
            token,
            BETTER_AUTH_SECRET,
            algorithms=["HS256"]
        )
        return {
            "user_id": payload.get("userId") or payload.get("sub"),
            "email": payload.get("email"),
            "name": payload.get("name")
        }
    except jwt.InvalidTokenError:
        return None

def format_user_response(user: dict, message: str) -> str:
    """Format response with user context."""
    if user and user.get("email"):
        return f"Sure, {user['email']}! {message}"
    return message

Complete Agent Loop

async def process_user_message(
    user_id: str,
    message: str,
    conversation_history: list
) -> dict:
    """Process user message and generate response."""

    # Get user context
    user = await get_user_from_jwt(request.headers.get("Authorization"))

    # Build system prompt with user context
    system_prompt = SYSTEM_PROMPT.format(user_email=user["email"] if user else "User")

    # Detect intent and extract parameters
    intent = detect_intent(message)
    params = extract_task_params(message, intent)
    params["user_id"] = user_id

    # Route to appropriate tool
    if intent != Intent.UNKNOWN:
        result = await route_to_tool(intent, user_id, params)
        response = format_user_response(user, result["response"])
    else:
        response = format_user_response(
            user,
            "I'm not sure what you mean. Try: 'add task', 'list tasks', 'complete task', or 'delete task'."
        )

    return {
        "response": response,
        "intent": intent.value,
        "params": params
    }

Response Templates

RESPONSE_TEMPLATES = {
    "add_task": "I've added the task '{title}' to your list.",
    "list_tasks": "Here are your {status} tasks:\n{任务列表}",
    "complete_task": "Done! I've marked '{title}' as completed.",
    "delete_task": "I've deleted '{title}' from your tasks.",
    "update_task": "I've updated '{title}' with the new details.",
    "no_tasks": "You don't have any {status} tasks right now."
}

Verification Checklist

  • Intent detection works for common phrases
  • Parameters extracted correctly
  • User email shown in responses
  • Tool chains execute in order
  • Natural language responses
  • Handles unknown intents gracefully