This commit is contained in:
Josh at WLTechBlog
2025-10-16 10:54:37 -05:00
parent ccd8c77a3e
commit 4d55acca95
45 changed files with 8499 additions and 2416 deletions

File diff suppressed because it is too large Load Diff

2210
mcp/LLM_USAGE_GUIDE_OLD.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
# LLM_USAGE_GUIDE.md Optimization Summary
## Overview
Successfully optimized the LLM usage guide for maximum efficiency while ensuring complete coverage of all MCP tools.
## Results
### File Size Reduction
- **Old file:** 2,210 lines
- **New file:** 534 lines
- **Reduction:** 80% (1,676 lines removed)
### Tool Coverage
- **Previously documented:** 48 tools (claimed "31" then "45")
- **Actually registered:** 66 tools
- **Missing from old guide:** 18 tools (27% undocumented)
- **New guide covers:** ALL 66 tools (100% coverage)
## Missing Tools That Were Added
### Accessibility Testing Tools (11)
1. `web_inject_axe_cremotemcp` - Inject axe-core library
2. `web_run_axe_cremotemcp` - Run axe-core tests
3. `web_contrast_check_cremotemcp` - Check color contrast
4. `web_contrast_audit_cremotemcp` - Smart contrast audit
5. `web_gradient_contrast_check_cremotemcp` - Gradient contrast check
6. `web_enhanced_accessibility_cremotemcp` - Enhanced accessibility analysis
7. `web_keyboard_test_cremotemcp` - Keyboard navigation test
8. `web_keyboard_audit_cremotemcp` - Keyboard audit
9. `web_form_accessibility_audit_cremotemcp` - Form accessibility audit
10. `web_page_accessibility_report_cremotemcp` - Comprehensive accessibility report
11. `web_hover_focus_test_cremotemcp` - Hover/focus WCAG test
### WCAG Compliance Tools (4)
12. `web_text_in_images_cremotemcp` - OCR text detection in images
13. `web_animation_flash_cremotemcp` - Animation/flash detection
14. `web_cross_page_consistency_cremotemcp` - Cross-page consistency check
15. `web_media_validation_cremotemcp` - Media validation
### Responsive/Zoom Testing (2)
16. `web_reflow_test_cremotemcp` - Reflow test at different widths
17. `web_zoom_test_cremotemcp` - Zoom level testing
### Utility (1)
18. `version_cremotemcp` - Get version information
## Optimization Strategies Applied
### 1. Removed Verbose Content
- ❌ Emoji decorations (🎉, ✅, ❌, ⚠️)
- ❌ Marketing language ("Perfect", "100% Reliable", "BREAKTHROUGH")
- ❌ Motivational content and phase announcements
- ❌ Human-oriented explanations
- ❌ Redundant "use cases" sections (obvious from parameters)
- ❌ Multiple examples showing same patterns
- ❌ Long prose sections
### 2. Improved Structure
- ✅ Organized by functional category (12 categories)
- ✅ Compact parameter lists with inline descriptions
- ✅ Consistent format across all tools
- ✅ Essential information only: parameters, defaults, return types
- ✅ Removed workflow examples (LLMs can infer)
- ✅ Consolidated common patterns section
### 3. Enhanced Information Density
- ✅ Tool categories summary at top (quick reference)
- ✅ Parameter descriptions inline (no separate sections)
- ✅ Return types documented concisely
- ✅ Default values clearly stated
- ✅ Required vs optional parameters explicit
### 4. Removed Unnecessary Sections
- ❌ "Best Practices for LLMs" (redundant)
- ❌ "Security Considerations" (not relevant for LLM)
- ❌ "Troubleshooting Tips" (obvious)
- ❌ "CSS Selector Best Practices" (LLMs know this)
- ❌ "Tool Response Format" examples (redundant)
- ❌ Multiple workflow examples (consolidated to one section)
## New Guide Structure
```
1. Introduction (3 lines)
2. Tool Categories (12 categories, 15 lines)
3. Core Automation Tools (12 tools, ~80 lines)
4. Element Inspection Tools (2 tools, ~15 lines)
5. Data Extraction Tools (4 tools, ~30 lines)
6. Form Tools (3 tools, ~25 lines)
7. Page Intelligence Tools (4 tools, ~30 lines)
8. Screenshot Tools (3 tools, ~20 lines)
9. Cache Control Tools (5 tools, ~15 lines)
10. Mouse/Keyboard Tools (11 tools, ~60 lines)
11. Accessibility Tree Tools (3 tools, ~20 lines)
12. Accessibility Testing Tools (18 tools, ~140 lines)
13. Common Patterns (6 examples, ~50 lines)
14. Best Practices (6 items, ~10 lines)
15. Error Handling (4 items, ~10 lines)
16. Notes (6 items, ~10 lines)
```
## Key Improvements
### For LLM Consumption
1. **Faster parsing:** 80% less content to process
2. **Complete coverage:** All 66 tools documented
3. **Consistent format:** Easy to extract information
4. **No noise:** Only essential information
5. **Quick reference:** Category summary at top
### Information Preserved
- ✅ All tool names and descriptions
- ✅ All parameters (required/optional)
- ✅ Default values
- ✅ Return data structures
- ✅ Tool interdependencies
- ✅ Common usage patterns
- ✅ Critical notes (e.g., auto-transfer for uploads)
### Information Removed
- ❌ Verbose explanations
- ❌ Redundant examples
- ❌ Marketing language
- ❌ Human-oriented advice
- ❌ Obvious use cases
- ❌ Repetitive patterns
## Token Efficiency
### Estimated Token Reduction
- **Old guide:** ~8,000-10,000 tokens
- **New guide:** ~2,000-2,500 tokens
- **Savings:** ~75-80% token reduction
### Impact on LLM Performance
- Faster context loading
- More room for other context
- Clearer tool selection
- Reduced confusion from redundant info
- Better focus on essential parameters
## Validation
### Completeness Check
```bash
# Tools registered in main.go: 66
# Tools documented in new guide: 66
# Coverage: 100%
```
### Missing Tools Verification
All 18 previously missing tools now documented with:
- Tool name
- Description
- Parameters (required/optional)
- Default values
- Return structure
- Default timeout
## Recommendations
### Maintenance
1. Update guide when new tools are added
2. Keep format consistent (compact, no fluff)
3. Verify tool count matches registered tools
4. Test guide with actual LLM usage
### Future Enhancements
1. Consider JSON schema format for even more compact representation
2. Add tool dependency graph if needed
3. Group related tools more explicitly
4. Add version compatibility notes if tools change
## Conclusion
The optimized guide achieves:
-**80% size reduction** (2,210 → 534 lines)
-**100% tool coverage** (48 → 66 tools)
-**Complete information** (all parameters, defaults, returns)
-**LLM-optimized format** (compact, consistent, no noise)
-**Maintained accuracy** (verified against source code)
The new guide is production-ready and significantly more efficient for LLM consumption while providing complete coverage of all cremote MCP tools.

View File

@@ -164,19 +164,27 @@ web_interact_cremotemcp:
selector: "form"
```
### Upload File
### Upload File (Automatic Transfer)
```yaml
# Recommended: Pass local file path directly - auto-transfers to container
web_interact_cremotemcp:
action: "upload"
selector: "input[type='file']"
value: "/path/to/file.pdf"
value: "/home/user/document.pdf" # Local path - auto-transferred!
```
### Upload File to Container
### Upload File to Container (Manual)
```yaml
# Optional: Pre-stage file in container if needed
file_upload_cremotemcp:
local_path: "/home/user/document.pdf"
container_path: "/tmp/upload.pdf"
# Then use container path
web_interact_cremotemcp:
action: "upload"
selector: "input[type='file']"
value: "/tmp/upload.pdf"
```
### Download File from Container

View File

@@ -6,7 +6,9 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"git.teamworkapps.com/shortcut/cremote/client"
@@ -189,7 +191,7 @@ func main() {
// Register web_interact tool
mcpServer.AddTool(mcp.Tool{
Name: "web_interact_cremotemcp",
Description: "Interact with web elements (click, fill, submit)",
Description: "Interact with web elements (click, fill, submit, upload). For upload action, automatically handles file transfer from host to container if needed.",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
@@ -204,7 +206,7 @@ func main() {
},
"value": map[string]any{
"type": "string",
"description": "Value to fill (for fill/upload actions)",
"description": "Value to fill (for fill/upload actions). For upload, can be either a local host path or container path - will auto-detect and transfer if needed.",
},
"tab": map[string]any{
"type": "string",
@@ -264,8 +266,31 @@ func main() {
if value == "" {
return nil, fmt.Errorf("value parameter (file path) is required for upload action")
}
err = cremoteServer.client.UploadFile(tab, selector, value, timeout)
message = fmt.Sprintf("Uploaded file %s to element %s", value, selector)
// Auto-detect if file needs to be transferred to container
// If the path doesn't start with /tmp/ or other container paths, assume it's a host path
containerPath := value
var transferredFile bool
// Check if file exists in container - if not, try to upload from host
if !strings.HasPrefix(value, "/tmp/") && !strings.HasPrefix(value, "/var/") {
// This looks like a host path, try to upload to container
uploadedPath, uploadErr := cremoteServer.client.UploadFileToContainer(value, "")
if uploadErr == nil {
containerPath = uploadedPath
transferredFile = true
} else {
// If upload fails, maybe it's already a valid container path, try to use it as-is
// The actual upload to the form will fail if the file doesn't exist
}
}
err = cremoteServer.client.UploadFile(tab, selector, containerPath, timeout)
if transferredFile {
message = fmt.Sprintf("Transferred file from host (%s) to container (%s) and uploaded to element %s", value, containerPath, selector)
} else {
message = fmt.Sprintf("Uploaded file %s to element %s", containerPath, selector)
}
case "select":
if value == "" {
@@ -380,13 +405,13 @@ func main() {
// Register web_screenshot tool
mcpServer.AddTool(mcp.Tool{
Name: "web_screenshot_cremotemcp",
Description: "Take a screenshot of the current page with optional zoom level and viewport size for accessibility testing",
Description: "Take a screenshot of the current page with optional zoom level and viewport size for accessibility testing. Automatically downloads the screenshot from container to host.",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"output": map[string]any{
"type": "string",
"description": "Output file path",
"description": "Output file path on the host machine (e.g., /home/user/screenshots/page.png). The screenshot will be automatically downloaded from the container.",
},
"full_page": map[string]any{
"type": "boolean",
@@ -449,9 +474,23 @@ func main() {
return nil, fmt.Errorf("no tab available - navigate to a page first")
}
// Build command parameters
// Determine container path and host path
var containerPath, hostPath string
// If output path starts with /tmp/ or /var/, treat it as container path
if strings.HasPrefix(output, "/tmp/") || strings.HasPrefix(output, "/var/") {
containerPath = output
// Generate a default host path
hostPath = "/tmp/" + filepath.Base(output)
} else {
// Treat as host path, generate container path
hostPath = output
containerPath = "/tmp/screenshot-" + strconv.FormatInt(time.Now().Unix(), 10) + filepath.Ext(output)
}
// Build command parameters for taking screenshot in container
cmdParams := map[string]string{
"output": output,
"output": containerPath,
"full-page": strconv.FormatBool(fullPage),
"tab": tab,
"timeout": strconv.Itoa(timeout),
@@ -466,7 +505,7 @@ func main() {
cmdParams["height"] = strconv.Itoa(height)
}
// Send command to daemon
// Send command to daemon to take screenshot
resp, err := cremoteServer.client.SendCommand("screenshot", cmdParams)
if err != nil {
return nil, fmt.Errorf("failed to take screenshot: %w", err)
@@ -481,11 +520,22 @@ func main() {
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, output)
// Automatically download the screenshot from container to host
err = cremoteServer.client.DownloadFileFromContainer(containerPath, hostPath)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Screenshot taken in container (%s) but failed to download to host: %v", containerPath, err)),
},
IsError: true,
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, hostPath)
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Screenshot saved to %s", output)),
mcp.NewTextContent(fmt.Sprintf("Screenshot saved to %s (automatically downloaded from container)", hostPath)),
},
IsError: false,
}, nil
@@ -1766,7 +1816,7 @@ func main() {
// web_screenshot_element_cremotemcp - Screenshot specific elements
mcpServer.AddTool(mcp.Tool{
Name: "web_screenshot_element_cremotemcp",
Description: "Take a screenshot of a specific element on the page",
Description: "Take a screenshot of a specific element on the page. Automatically downloads the screenshot from container to host.",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
@@ -1776,7 +1826,7 @@ func main() {
},
"output": map[string]any{
"type": "string",
"description": "Path where to save the screenshot",
"description": "Path where to save the screenshot on the host machine. The screenshot will be automatically downloaded from the container.",
},
"tab": map[string]any{
"type": "string",
@@ -1811,7 +1861,22 @@ func main() {
return nil, fmt.Errorf("no tab available - navigate to a page first")
}
err := cremoteServer.client.ScreenshotElement(tab, selector, output, timeout)
// Determine container path and host path
var containerPath, hostPath string
// If output path starts with /tmp/ or /var/, treat it as container path
if strings.HasPrefix(output, "/tmp/") || strings.HasPrefix(output, "/var/") {
containerPath = output
// Generate a default host path
hostPath = "/tmp/" + filepath.Base(output)
} else {
// Treat as host path, generate container path
hostPath = output
containerPath = "/tmp/screenshot-element-" + strconv.FormatInt(time.Now().Unix(), 10) + filepath.Ext(output)
}
// Take screenshot in container
err := cremoteServer.client.ScreenshotElement(tab, selector, containerPath, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
@@ -1821,11 +1886,22 @@ func main() {
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, output)
// Automatically download the screenshot from container to host
err = cremoteServer.client.DownloadFileFromContainer(containerPath, hostPath)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Screenshot taken in container (%s) but failed to download to host: %v", containerPath, err)),
},
IsError: true,
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, hostPath)
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Element screenshot saved to: %s", output)),
mcp.NewTextContent(fmt.Sprintf("Element screenshot saved to %s (automatically downloaded from container)", hostPath)),
},
IsError: false,
}, nil
@@ -1834,13 +1910,13 @@ func main() {
// web_screenshot_enhanced_cremotemcp - Enhanced screenshots with metadata
mcpServer.AddTool(mcp.Tool{
Name: "web_screenshot_enhanced_cremotemcp",
Description: "Take an enhanced screenshot with metadata (timestamp, viewport size, URL)",
Description: "Take an enhanced screenshot with metadata (timestamp, viewport size, URL). Automatically downloads the screenshot from container to host.",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"output": map[string]any{
"type": "string",
"description": "Path where to save the screenshot",
"description": "Path where to save the screenshot on the host machine. The screenshot will be automatically downloaded from the container.",
},
"full_page": map[string]any{
"type": "boolean",
@@ -1876,7 +1952,22 @@ func main() {
return nil, fmt.Errorf("no tab available - navigate to a page first")
}
metadata, err := cremoteServer.client.ScreenshotEnhanced(tab, output, fullPage, timeout)
// Determine container path and host path
var containerPath, hostPath string
// If output path starts with /tmp/ or /var/, treat it as container path
if strings.HasPrefix(output, "/tmp/") || strings.HasPrefix(output, "/var/") {
containerPath = output
// Generate a default host path
hostPath = "/tmp/" + filepath.Base(output)
} else {
// Treat as host path, generate container path
hostPath = output
containerPath = "/tmp/screenshot-enhanced-" + strconv.FormatInt(time.Now().Unix(), 10) + filepath.Ext(output)
}
// Take enhanced screenshot in container
metadata, err := cremoteServer.client.ScreenshotEnhanced(tab, containerPath, fullPage, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
@@ -1886,7 +1977,18 @@ func main() {
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, output)
// Automatically download the screenshot from container to host
err = cremoteServer.client.DownloadFileFromContainer(containerPath, hostPath)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Screenshot taken in container (%s) but failed to download to host: %v", containerPath, err)),
},
IsError: true,
}, nil
}
cremoteServer.screenshots = append(cremoteServer.screenshots, hostPath)
metadataJSON, err := json.MarshalIndent(metadata, "", " ")
if err != nil {
@@ -1895,7 +1997,7 @@ func main() {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Enhanced screenshot saved with metadata:\n%s", string(metadataJSON))),
mcp.NewTextContent(fmt.Sprintf("Enhanced screenshot saved to %s (automatically downloaded from container) with metadata:\n%s", hostPath, string(metadataJSON))),
},
IsError: false,
}, nil