Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:26:43 +08:00
commit 0784802e81
8 changed files with 263 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
{
"name": "websearch-tools",
"description": "Smart web tool routing via hooks that redirect WebFetch/WebSearch to Tavily. Includes context7 MCP for library docs and a skill for tool selection.",
"version": "1.2.1",
"author": {
"name": "Fatih Akyon"
},
"skills": [
"./skills"
],
"hooks": [
"./hooks"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# websearch-tools
Smart web tool routing via hooks that redirect WebFetch/WebSearch to Tavily. Includes context7 MCP for library docs and a skill for tool selection.

34
hooks/hooks.json Normal file
View File

@@ -0,0 +1,34 @@
{
"description": "Web search and Tavily integration hooks",
"hooks": {
"PreToolUse": [
{
"matcher": "WebFetch",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/webfetch_to_tavily_extract.py"
}
]
},
{
"matcher": "WebSearch",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/websearch_to_tavily_search.py"
}
]
},
{
"matcher": "mcp__tavily__tavily-extract",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/tavily_extract_to_advanced.py"
}
]
}
]
}
}

View File

@@ -0,0 +1,46 @@
#!/usr/bin/env python3
"""
PreToolUse hook: intercept mcp__tavily__tavily-extract
- Block GitHub URLs and suggest using GitHub MCP tools instead
- Otherwise, upgrade extract_depth to "advanced"
"""
import json
import sys
try:
data = json.load(sys.stdin)
tool_input = data["tool_input"]
urls = tool_input.get("urls", [])
# Check for GitHub URLs
github_domains = ("github.com", "raw.githubusercontent.com", "gist.github.com")
github_urls = [url for url in urls if any(domain in url for domain in github_domains)]
if github_urls:
# Block and suggest GitHub MCP tools
print(json.dumps({
"systemMessage": "GitHub URL detected in Tavily extract tool. AI is directed to use GitHub MCP tools instead.",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "GitHub URL detected. Please use GitHub MCP tools (mcp__github__*) for more robust data retrieval."
},
}, separators=(',', ':')))
sys.exit(2)
# Always ensure extract_depth="advanced" for non-GitHub URLs
tool_input["extract_depth"] = "advanced"
# Allow the call to proceed
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Automatically upgrading Tavily extract to advanced mode for better content extraction"
}
}, separators=(',', ':')))
sys.exit(0)
except (KeyError, json.JSONDecodeError) as err:
print(f"hook-error: {err}", file=sys.stderr)
sys.exit(1)

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python3
"""
PreToolUse hook: intercept WebFetch → suggest using tavily-extract instead
"""
import json
import sys
try:
data = json.load(sys.stdin)
url = data["tool_input"]["url"]
except (KeyError, json.JSONDecodeError) as err:
print(f"hook-error: {err}", file=sys.stderr)
sys.exit(1)
print(json.dumps({
"systemMessage": "WebFetch detected. AI is directed to use Tavily extract instead.",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Please use mcp__tavily__tavily-extract with urls: ['{url}'] and extract_depth: 'advanced'"
}
}, separators=(',', ':')))
sys.exit(0)

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""
PreToolUse hook: intercept WebSearch → suggest using Tavily search instead
"""
import json
import sys
try:
data = json.load(sys.stdin)
tool_input = data["tool_input"]
query = tool_input["query"]
except (KeyError, json.JSONDecodeError) as err:
print(f"hook-error: {err}", file=sys.stderr)
sys.exit(1)
print(json.dumps({
"systemMessage": "WebSearch detected. AI is directed to use Tavily search instead.",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Please use mcp__tavily__tavily-search with query: '{query}'"
}
}, separators=(',', ':')))
sys.exit(0)

61
plugin.lock.json Normal file
View File

@@ -0,0 +1,61 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:fcakyon/claude-codex-settings:plugins/websearch-tools",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "3daa2b5dd45909cccf5270b0c3fa5c6ac0aa8aa6",
"treeHash": "e01bd8701c7767c6854e87b53500da994ab2610aa49bbf049e6e7c28cd0b729b",
"generatedAt": "2025-11-28T10:16:50.949294Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "websearch-tools",
"description": "Smart web tool routing via hooks that redirect WebFetch/WebSearch to Tavily. Includes context7 MCP for library docs and a skill for tool selection.",
"version": "1.2.1"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "1fe0726bb9aa50266c7ee33eff5abdbe00e1e8727f2f9737331968ab62f19a2e"
},
{
"path": "hooks/hooks.json",
"sha256": "b922d7c24ce3f5fdb6581ba8bb7da2523cde43f4fb851dc112e46d031dd075cd"
},
{
"path": "hooks/scripts/webfetch_to_tavily_extract.py",
"sha256": "ac3433d5a252e9c651138bac783bc6dc551c96e6e2dedefe336d702c9b11c6dd"
},
{
"path": "hooks/scripts/websearch_to_tavily_search.py",
"sha256": "25543d9601135aaf3e1a99fb184cc12b02c0faeee6443af80d1eab203dba88a6"
},
{
"path": "hooks/scripts/tavily_extract_to_advanced.py",
"sha256": "b0fa4377fa04fc3ad60f5b6b4b10bf39d1d7cfe6d03b53b3e0a4a36fa45e5947"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "46220c8dc463e12961cd427674d596154335619d21659396de356bfee40c7ffa"
},
{
"path": "skills/tavily-usage/SKILL.md",
"sha256": "4ea803b1ba8db68521e8a28484962497a01bced49f313f6dbb1e00725586830a"
}
],
"dirSha256": "e01bd8701c7767c6854e87b53500da994ab2610aa49bbf049e6e7c28cd0b729b"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,58 @@
---
name: tavily-usage
description: This skill should be used when user asks to "search the web", "fetch content from URL", "extract page content", "use Tavily search", "scrape this website", "get information from this link", or "web search for X".
---
# Tavily Search and Extract
Use Tavily MCP tools for web search and content retrieval operations.
## Tool Selection
### Tavily Search (`mcp__tavily__tavily-search`)
Use for:
- Keyword-based searches across the web
- Finding relevant pages and content
- Quick answer gathering
- Multiple result discovery
**Best for**: Initial research, finding sources, broad queries
### Tavily Extract (`mcp__tavily__tavily-extract`)
Use for:
- Getting detailed content from specific URLs
- Deep analysis of page content
- Structured data extraction
- Following up on search results
**Best for**: In-depth analysis, specific URL content, detailed information
## Hook Behavior
`tavily_extract_to_advanced.py` hook automatically upgrades extract calls to advanced mode for better accuracy when needed.
## Integration Pattern
1. Use `mcp__tavily__tavily-search` for discovery phase
2. Analyze results to find relevant URLs
3. Use `mcp__tavily__tavily-extract` for detailed content on specific URLs
4. Process extracted content for user needs
## Environment Variables
Tavily MCP requires:
- `TAVILY_API_KEY` - API key from Tavily (tvly-...)
Configure in shell before using the plugin.
## Cost Considerations
- Search is cheaper than extract
- Use search to filter relevant URLs first
- Only extract URLs that are likely relevant
- Cache results when possible