Skill: yifeiwang1981/qveris-skill (version 1.0.0)

--- name: qveris description: Search and execute dynamic tools via QVeris API. Use when needing to find and call external APIs/tools dynamically (weather, search, data retrieval, stock trading analysis, etc.). Requires QVERIS_API_KEY environment variable. triggers: - pattern: "股票|stock|股价|股市" description: "Detect stock-related queries" - pattern: "交易|trading|买卖|成交" description: "Detect trading-related queries" - pattern: "分析|analysis|数据|指标|技术分析|基本面" description: "Detect analysis-related queries" - pattern: "市值|涨跌|收盘|开盘|市盈率|pe|pb" description: "Detect stock indicator queries" auto_invoke: true examples: - "Check Tesla stock price" - "Analyze Apple's financial data" - "Get Bitcoin real-time price" - "Show me current weather in Tokyo" --- # QVeris Tool Search & Execution QVeris provides dynamic tool discovery and execution - search for tools by capability, then execute them with parameters. ## Setup Requires environment variable: - `QVERIS_API_KEY` - Get from https://qveris.ai ## Quick Start ### Search for tools ```bash uv run scripts/qveris_tool.py search "weather forecast API" ``` ### Execute a tool ```bash uv run scripts/qveris_tool.py execute openweathermap_current_weather --search-id <id> --params '{"city": "London", "units": "metric"}' ``` ## Script Usage ``` scripts/qveris_tool.py <command> [options] Commands: search <query> Search for tools matching a capability description execute <tool_id> Execute a specific tool with parameters Options: --limit N Max results for search (default: 5) --search-id ID Search ID from previous search (required for execute) --params JSON Tool parameters as JSON string --max-size N Max response size in bytes (default: 20480) --json Output raw JSON instead of formatted display ``` ## Workflow 1. **Search**: Describe the capability needed (not specific parameters) - Good: "weather forecast API" - Bad: "get weather for London" 2. **Select**: Review tools by `success_rate` and `avg_execution_time` 3. **Execute**: Call tool with `tool_id`, `search_id`, and `parameters` ## Example Session ```bash # Find weather tools uv run scripts/qveris_tool.py search "current weather data" # Execute with returned tool_id and search_id uv run scripts/qveris_tool.py execute openweathermap_current_weather \ --search-id abc123 \ --params '{"city": "Tokyo", "units": "metric"}' ``` ## Use Cases - **Weather Data**: Get current weather, forecasts for any location - **Stock Market**: Query stock prices, historical data, earnings calendars - **Search**: Web search, news retrieval - **Data APIs**: Currency exchange, geolocation, translations - **And more**: QVeris aggregates thousands of API tools

path: README.md
content: # QVeris Skill for Claude Code

[中文文档](README.zh-CN.md) | English

A skill that enables Claude Code to dynamically search and execute tools via the QVeris API.

## Features

- **Tool Discovery**: Search for APIs by describing what you need
- **Tool Execution**: Execute any discovered tool with parameters
- **Wide Coverage**: Access weather, stocks, search, currency, and thousands more APIs

## Installation

### Prerequisites

This skill requires `uv`, a fast Python package manager. Install it first:

**macOS and Linux:**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

**Windows:**
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

For other installation methods, see the [official uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).

### Install the Skill

**Option 1: Install via ClawdHub (Recommended)**
```bash
clawdhub install qveris
```

**Option 2: Install via NPX (For other coding agents)**
```bash
npx skills add hqman/qveris
```

**Option 3: Manual Installation**

1. Copy this folder to your Claude Code skills directory:
   ```bash
   cp -r qveris ~/.claude/skills/
   ```

2. Set your API key:
   ```bash
   export QVERIS_API_KEY="your-api-key-here"
   ```

   Get your API key at https://qveris.ai

## Usage

Once installed, Claude Code will automatically use this skill when you ask questions about:
- Weather data
- Stock prices and market analysis
- Web searches
- Currency exchange rates
- And more...

### Manual Commands

```bash
# Search for tools
uv run scripts/qveris_tool.py search "stock price data"

# Execute a tool
uv run scripts/qveris_tool.py execute <tool_id> --search-id <id> --params '{"symbol": "AAPL"}'
```

## Author

[@hqmank](https://x.com/hqmank)

## License

MIT


path: README.zh-CN.md
content: # QVeris Skill for Claude Code

中文文档 | [English](README.md)

这是一个让 Claude Code 能够通过 QVeris API 动态搜索和执行工具的技能。

## 功能特性

- **工具发现**：通过描述您的需求来搜索 API
- **工具执行**：使用参数执行任何已发现的工具
- **广泛覆盖**：访问天气、股票、搜索、货币以及数千种其他 API

## 安装

### 前置要求

此技能需要 `uv`，一个快速的 Python 包管理工具。请先安装它：

**macOS 和 Linux:**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

**Windows:**
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

更多安装方式，请查看 [uv 官方安装指南](https://docs.astral.sh/uv/getting-started/installation/)。

### 安装技能

**方式一：通过 ClawdHub 安装（推荐）**
```bash
clawdhub install qveris
```

**方式二：通过 NPX 安装（适用于其他编码代理）**
```bash
npx skills add hqman/qveris
```

**方式三：手动安装**

1. 将此文件夹复制到您的 Claude Code 技能目录：
   ```bash
   cp -r qveris ~/.claude/skills/
   ```

2. 设置您的 API 密钥：
   ```bash
   export QVERIS_API_KEY="your-api-key-here"
   ```

   在 https://qveris.ai 获取您的 API 密钥

## 使用方法

安装完成后，当您询问以下问题时，Claude Code 将自动使用此技能：
- 天气数据
- 股票价格和市场分析
- 网络搜索
- 货币汇率
- 更多...

### 手动命令

```bash
# 搜索工具
uv run scripts/qveris_tool.py search "stock price data"

# 执行工具
uv run scripts/qveris_tool.py execute <tool_id> --search-id <id> --params '{"symbol": "AAPL"}'
```

## 作者

[@hqmank](https://x.com/hqmank)

## 许可证

MIT


path: pyproject.toml
content: [project]
name = "qveris-skill"
version = "0.1.0"
description = "QVeris API tool search and execution skill for Claude Code"
requires-python = ">=3.10"
dependencies = [
    "httpx>=0.25.0",
]


path: scripts/qveris_tool.py
content: #!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "httpx",
# ]
# ///
"""
QVeris Tool Search & Execution CLI

Search for tools by capability and execute them via QVeris API.

Usage:
    uv run qveris_tool.py search "weather forecast"
    uv run qveris_tool.py execute <tool_id> --search-id <id> --params '{"city": "London"}'
"""

import argparse
import asyncio
import json
import os
import sys

import httpx

BASE_URL = "https://qveris.ai/api/v1"


def get_api_key() -> str:
    """Get QVeris API key from environment."""
    key = os.environ.get("QVERIS_API_KEY")
    if not key:
        print("Error: QVERIS_API_KEY environment variable not set", file=sys.stderr)
        print("Get your API key at https://qveris.ai", file=sys.stderr)
        sys.exit(1)
    return key


async def search_tools(query: str, limit: int = 5) -> dict:
    """Search for tools matching a capability description."""
    [REDACTED_SECRET])

    async with httpx.AsyncClient(timeout=30) as client:
        response = await client.post(
            f"{BASE_URL}/search",
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
            },
            json={"query": query, "limit": limit},
        )
        response.raise_for_status()
        return response.json()


async def execute_tool(
    tool_id: str,
    search_id: str,
    parameters: dict,
    max_response_size: int = 20480,
) -> dict:
    """Execute a specific tool with parameters."""
    [REDACTED_SECRET])

    async with httpx.AsyncClient(timeout=60) as client:
        response = await client.post(
            f"{BASE_URL}/tools/execute",
            params={"tool_id": tool_id},
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
            },
            json={
                "search_id": search_id,
                "parameters": parameters,
                "max_response_size": max_response_size,
            },
        )
        response.raise_for_status()
        return response.json()


def display_search_results(result: dict) -> None:
    """Display search results in a formatted way."""
    search_id = result.get("search_id", "N/A")
    tools = result.get("results", [])
    total = result.get("total", len(tools))

    print(f"\nSearch ID: {search_id}")
    print(f"Found {total} tools\n")

    if not tools:
        print("No tools found.")
        return

    for i, tool in enumerate(tools, 1):
        tool_id = tool.get("tool_id", "N/A")
        name = tool.get("name", "N/A")
        desc = tool.get("description", "N/A")

        # Stats
        stats = tool.get("stats", {})
        success_rate = stats.get("success_rate", "N/A")
        avg_time = stats.get("avg_execution_time_ms", "N/A")

        if isinstance(success_rate, (int, float)):
            success_rate = f"{success_rate:.0%}"
        if isinstance(avg_time, (int, float)):
            avg_time = f"{avg_time:.1f}ms"

        print(f"[{i}] {name}")
        print(f"    ID: {tool_id}")
        print(f"    {desc[:100]}{'...' if len(desc) > 100 else ''}")
        print(f"    Success: {success_rate} | Avg Time: {avg_time}")

        # Show params
        params = tool.get("params", [])
        if params:
            required = [p["name"] for p in params if p.get("required")]
            optional = [p["name"] for p in params if not p.get("required")]
            if required:
                print(f"    Required: {', '.join(required)}")
            if optional:
                print(f"    Optional: {', '.join(optional[:5])}{'...' if len(optional) > 5 else ''}")

        # Show example
        examples = tool.get("examples", {})
        sample = examples.get("sample_parameters")
        if sample:
            print(f"    Example: {json.dumps(sample)}")

        print()


def display_execution_result(result: dict) -> None:
    """Display tool execution result."""
    success = result.get("success", False)
    exec_time = result.get("elapsed_time_ms", "N/A")
    cost = result.get("cost", 0)

    status = "Success" if success else "Failed"
    print(f"\n{status}")
    print(f"Time: {exec_time}ms | Cost: {cost}")

    if not success:
        error = result.get("error_message", "Unknown error")
        print(f"Error: {error}")

    data = result.get("result", {})
    if data:
        print("\nResult:")
        print(json.dumps(data, indent=2, ensure_ascii=False))


async def main():
    parser = argparse.ArgumentParser(
        description="QVeris Tool Search & Execution CLI",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  %(prog)s search "weather forecast API"
  %(prog)s execute openweathermap_current_weather --search-id abc123 --params '{"city": "London"}'
        """,
    )

    subparsers = parser.add_subparsers(dest="command", required=True)

    # Search command
    search_parser = subparsers.add_parser("search", help="Search for tools")
    search_parser.add_argument("query", help="Capability description to search for")
    search_parser.add_argument("--limit", type=int, default=5, help="Max results (default: 5)")
    search_parser.add_argument("--json", action="store_true", help="Output raw JSON")

    # Execute command
    exec_parser = subparsers.add_parser("execute", help="Execute a tool")
    exec_parser.add_argument("tool_id", help="Tool ID to execute")
    exec_parser.add_argument("--search-id", required=True, help="Search ID from previous search")
    exec_parser.add_argument("--params", default="{}", help="Tool parameters as JSON string")
    exec_parser.add_argument("--max-size", type=int, default=20480, help="Max response size")
    exec_parser.add_argument("--json", action="store_true", help="Output raw JSON")

    args = parser.parse_args()

    try:
        if args.command == "search":
            result = await search_tools(args.query, args.limit)
            if args.json:
                print(json.dumps(result, indent=2, ensure_ascii=False))
            else:
                display_search_results(result)

        elif args.command == "execute":
            params = json.loads(args.params)
            result = await execute_tool(
                args.tool_id,
                args.search_id,
                params,
                args.max_size,
            )
            if args.json:
                print(json.dumps(result, indent=2, ensure_ascii=False))
            else:
                display_execution_result(result)

    except httpx.HTTPStatusError as e:
        print(f"HTTP Error: {e.response.status_code}", file=sys.stderr)
        print(e.response.text, file=sys.stderr)
        sys.exit(1)
    except json.JSONDecodeError as e:
        print(f"Invalid JSON in --params: {e}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    asyncio.run(main())


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)