Skill: aronchick/expanso-keyword-extract (version 1.0.0)

# keyword-extract "Extract keywords and key phrases from text for SEO, tagging, and indexing" ## Requirements - Expanso Edge installed (`expanso-edge` binary in PATH) - Install via: `clawhub install expanso-edge` ## Usage ### CLI Pipeline ```bash # Run standalone echo '<input>' | expanso-edge run pipeline-cli.yaml ``` ### MCP Pipeline ```bash # Start as MCP server expanso-edge run pipeline-mcp.yaml ``` ### Deploy to Expanso Cloud ```bash expanso-cli job deploy https://skills.expanso.io/keyword-extract/pipeline-cli.yaml ``` ## Files | File | Purpose | |------|---------| | `skill.yaml` | Skill metadata (inputs, outputs, credentials) | | `pipeline-cli.yaml` | Standalone CLI pipeline | | `pipeline-mcp.yaml` | MCP server pipeline |

path: README.md
content: # keyword-extract

Extract keywords and key phrases from text.

## Overview

This skill extracts important keywords, multi-word phrases, and main topics from text. Useful for SEO, content tagging, and search indexing.

## Usage

### CLI Mode

```bash
export OPENAI_API_KEY=sk-...

cat article.txt | expanso-edge run pipeline-cli.yaml
MAX_KEYWORDS=5 echo "Your text here..." | expanso-edge run pipeline-cli.yaml
```

### MCP Mode

```bash
PORT=8080 expanso-edge run pipeline-mcp.yaml &
curl -X POST http://localhost:8080/extract \
  -H "Content-Type: application/json" \
  -d '{"text": "Machine learning is transforming...", "max_keywords": 10}'
```

## Output

```json
{
  "keywords": [
    {"word": "machine", "relevance": 0.95},
    {"word": "learning", "relevance": 0.92},
    {"word": "AI", "relevance": 0.88}
  ],
  "phrases": [
    "machine learning",
    "artificial intelligence",
    "neural networks"
  ],
  "topics": [
    "Technology",
    "Artificial Intelligence"
  ],
  "keyword_count": 3,
  "metadata": {...}
}
```

## Use Cases

- SEO keyword research
- Content tagging
- Document indexing
- Topic modeling
- Article summarization


path: pipeline-cli.yaml
content: # Expanso Pipeline: keyword-extract (CLI mode)
# =============================================
#
# Usage:
#   cat article.txt | expanso-edge run pipeline-cli.yaml
#
# Requires OPENAI_API_KEY.

name: "keyword-extract-cli"
type: pipeline

config:
  input:
    stdin:
      codec: all
      max_buffer: 1048576

  pipeline:
    processors:
      - mapping: |
          meta trace_id = uuid_v4()
          meta input_hash = content().hash("sha256").encode("hex")
          meta input_length = content().length()
          let max_keywords = env("MAX_KEYWORDS").or("10").number().or(10)

          root.messages = [
            {
              "role": "system",
              "content": "You are a keyword extraction expert. Extract keywords from text and return JSON with: 'keywords' (array of single words with 'word' and 'relevance' 0-1), 'phrases' (array of 2-3 word key phrases), 'topics' (array of main themes). Limit to " + $max_keywords.string() + " keywords. Focus on nouns and important terms."
            },
            {
              "role": "user",
              "content": content()
            }
          ]

      - openai_chat_completion:
          [REDACTED_SECRET]"
          model: gpt-4o-mini

      - mapping: |
          let response = this.choices.0.message.content.parse_json().catch({
            "keywords": [],
            "phrases": [],
            "topics": []
          })

          root.keywords = $response.keywords.or([])
          root.phrases = $response.phrases.or([])
          root.topics = $response.topics.or([])
          root.keyword_count = $response.keywords.or([]).length()
          root.metadata = {
            "skill": "keyword-extract",
            "mode": "cli",
            "model": "gpt-4o-mini",
            "input_hash": meta("input_hash"),
            "input_length": meta("input_length"),
            "trace_id": meta("trace_id"),
            "timestamp": now()
          }

      - log:
          level: INFO
          message: |
            [keyword-extract] Extracted ${! root.keyword_count } keywords (trace: ${! meta("trace_id").slice(0, 8) })

  output:
    stdout:
      codec: json_object


path: pipeline-mcp.yaml
content: # Expanso Pipeline: keyword-extract (MCP mode)
# =============================================
#
# Usage:
#   PORT=8080 expanso-edge run pipeline-mcp.yaml &
#   curl -X POST http://localhost:8080/extract -d '{"text": "..."}'

name: "keyword-extract-mcp"
type: pipeline

config:
  http:
    enabled: true
    address: "0.0.0.0:${PORT:-8080}"

  input:
    http_server:
      path: /extract
      allowed_verbs: [POST]
      timeout: 60s

  pipeline:
    processors:
      - mapping: |
          let input_text = this.text.or(content())
          let max_keywords = this.max_keywords.or(10)
          meta trace_id = uuid_v4()
          meta input_hash = $input_text.hash("sha256").encode("hex")
          meta input_length = $input_text.length()

          root.messages = [
            {
              "role": "system",
              "content": "You are a keyword extraction expert. Extract keywords from text and return JSON with: 'keywords' (array of single words with 'word' and 'relevance' 0-1), 'phrases' (array of 2-3 word key phrases), 'topics' (array of main themes). Limit to " + $max_keywords.string() + " keywords. Focus on nouns and important terms."
            },
            {
              "role": "user",
              "content": $input_text
            }
          ]

      - openai_chat_completion:
          [REDACTED_SECRET]"
          model: gpt-4o-mini

      - mapping: |
          let response = this.choices.0.message.content.parse_json().catch({
            "keywords": [],
            "phrases": [],
            "topics": []
          })

          root.keywords = $response.keywords.or([])
          root.phrases = $response.phrases.or([])
          root.topics = $response.topics.or([])
          root.keyword_count = $response.keywords.or([]).length()
          root.metadata = {
            "skill": "keyword-extract",
            "mode": "mcp",
            "model": "gpt-4o-mini",
            "input_hash": meta("input_hash"),
            "input_length": meta("input_length"),
            "trace_id": meta("trace_id"),
            "timestamp": now()
          }

      - log:
          level: INFO
          message: |
            [keyword-extract] Extracted ${! root.keyword_count } keywords (trace: ${! meta("trace_id").slice(0, 8) })

  output:
    sync_response: {}

selector:
  match_labels:
    capability: llm


path: skill.yaml
content: # Skill: keyword-extract
# Version: 1.0.0
#
# Extract keywords and key phrases from text.

name: "keyword-extract"
version: "1.0.0"
description: "Extract keywords and key phrases from text for SEO, tagging, and indexing"

author:
  name: "Expanso Team"
  url: "https://expanso.io"
  avatar: "EX"

credentials:
  - name: OPENAI_API_KEY
    required: false
    description: OpenAI API key

inputs:
  - name: text
    type: string
    required: true
    description: Text to analyze
  - name: max_keywords
    type: integer
    default: 10
    description: Maximum keywords to extract

outputs:
  - name: keywords
    type: array
    description: Extracted keywords with scores
  - name: phrases
    type: array
    description: Key phrases (2-3 words)
  - name: topics
    type: array
    description: Main topics/themes

backends:
  - name: openai
    type: remote
    requires: [OPENAI_API_KEY]
    description: OpenAI GPT
  - name: ollama
    type: local
    models: [llama3.2, mistral]
    description: Local Ollama

components:
  inputs:
    - stdin
    - http_server
  processors:
    - mapping
    - openai_chat_completion
  outputs:
    - stdout
    - sync_response


path: test/fixtures/input.txt
content: Machine learning and artificial intelligence are transforming how businesses operate. Companies are using deep learning and neural networks to automate processes, improve customer service, and make data-driven decisions. The future of technology lies in these advanced algorithms and their applications.


path: test/test.yaml
content: # Test cases for keyword-extract skill

tests:
  - name: "Extract keywords from text"
    input: "Machine learning and artificial intelligence are transforming technology."
    expected:
      has_field: keywords
      has_field: phrases
      has_field: topics
      metadata_has: [skill, trace_id, timestamp]


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