PlyMove

Pedagogical chess intelligence for AI agents: explain positions and games for a target Elo.

我該用這個嗎

品質與安全性

A
說明品質
93%
結構描述完整度
99%
命名品質
90%
汙染風險
100%
權限相符程度
100%
協定合規性
100%

根據工具定義與協定合規性的自動化分析。

上下文成本

~3,906Token(工具定義)
~7.5 KB典型回應大小
顯著的注意力影響(128k 上下文的 3.05%)

這是每次將伺服器的工具載入模型上下文時所消耗的約略 token 數量。數量越高,可用於其他工作的注意力就越少。

安裝

一鍵安裝

將以下內容加入你的 `claude_desktop_config.json` 檔案:

{
  "mcpServers": {
    "mcp": {
      "url": "https://mcp.plymove.com/mcp"
    }
  }
}

遠端端點

https://mcp.plymove.com/mcpstreamable-http

它能做什麼

工具清單

工具(6)

🟢 唯讀🟡 寫入🔴 刪除⚪ 未知
🟢build_game_storyboard(pgn, target_elo, language, max_moments, include_rendered_story, ...)

Build a verified Elo-aware game storyboard: opening, story arc, ranked moments, branches, and main lesson. Read-only analysis — does not modify user files or external systems.

輸入結構描述

{
  "type": "object",
  "properties": {
    "pgn": {
      "type": "string",
      "description": "Full game PGN"
    },
    "target_elo": {
      "type": "integer",
      "description": "Learner Elo rating",
      "minimum": 400,
      "maximum": 3500
    },
    "language": {
      "type": "string",
      "description": "Output language (e.g. en)",
      "default": "en"
    },
    "max_moments": {
      "type": "integer",
      "description": "Maximum storyboard chapters",
      "minimum": 1,
      "maximum": 12,
      "default": 5
    },
    "include_rendered_story": {
      "type": "boolean",
      "description": "Include accessible recap prose",
      "default": true
    },
    "engine_depth": {
      "type": "integer",
      "description": "Stockfish depth for deep analysis",
      "minimum": 4,
      "maximum": 24
    },
    "shallow_depth": {
      "type": "integer",
      "description": "Stockfish depth for selective shallow scan (defaults to min(engine_depth, 10))",
      "minimum": 4,
      "maximum": 20
    },
    "output_format": {
      "type": "string",
      "enum": [
        "annotated_pgn",
        "storyboard_json",
        "both"
      ],
      "description": "Return annotated PGN, JSON storyboard, or both (default both).",
      "default": "both"
    }
  },
  "required": [
    "pgn",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "storyboard"
      ]
    },
    "target_elo": {
      "type": "integer",
      "minimum": 400,
      "maximum": 3500
    },
    "analysis_id": {
      "type": "string"
    },
    "annotated_pgn": {
      "type": "string",
      "description": "Legal annotated PGN when output_format includes annotated_pgn or both."
    },
    "main_lesson": {
      "type": "string"
    },
    "rendered_story": {
      "type": "string"
    },
    "human_model_available": {
      "type": "boolean"
    },
    "build": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "storyboard_pipeline_version": {
          "type": "string"
        },
        "git_sha": {
          "type": "string"
        },
        "core_git_sha": {
          "type": "string"
        },
        "adapter_git_sha": {
          "type": "string"
        },
        "adapter_version": {
          "type": "string"
        },
        "deployment_id": {
          "type": "string"
        },
        "upstream_mcp_url": {
          "type": "string"
        }
      }
    },
    "game": {
      "type": "object",
      "properties": {
        "white": {
          "type": "string"
        },
        "black": {
          "type": "string"
        },
        "result": {
          "type": "string"
        },
        "event": {
          "type": "string"
        }
      }
    },
    "opening": {
      "type": "object",
      "properties": {
        "recognized": {
          "type": "boolean"
        },
        "eco": {
          "type": "string"
        },
        "family": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "variation": {
          "type": "string"
        },
        "confidence": {
          "type": "number"
        },
        "source": {
          "type": "string"
        },
        "source_pin": {
          "type": "string"
        },
        "matched_ply": {
          "type": "integer"
        }
      }
    },
    "story_arc": {
      "type": "object",
      "properties": {
        "premise": {
          "type": "string"
        },
        "first_imbalance": {
          "type": "string"
        },
        "climax_event_id": {
          "type": "string"
        },
        "resolution": {
          "type": "string"
        },
        "main_lesson": {
          "type": "string"
        }
      }
    },
    "moments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer"
          },
          "event_id": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "anchor_ply": {
            "type": "integer"
          },
          "move_label": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "reason_selected": {
            "type": "string"
          },
          "sequence": {
            "type": "object",
            "additionalProperties": true
          },
          "branches": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      }
    },
    "engine": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "depth": {
          "type": "integer"
        }
      }
    },
    "human_model": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "available",
            "degraded",
            "unavailable"
          ]
        },
        "target_elo": {
          "type": "integer"
        }
      }
    },
    "verification": {
      "type": "object",
      "properties": {
        "pgn_legal": {
          "type": "boolean"
        },
        "all_variations_legal": {
          "type": "boolean"
        },
        "mainline_legal": {
          "type": "boolean"
        },
        "branches_legal": {
          "type": "boolean"
        },
        "mainline_preserved": {
          "type": "boolean"
        },
        "opening_verified": {
          "type": "boolean"
        },
        "claims_verified": {
          "type": "boolean"
        },
        "claim_count": {
          "type": "integer"
        },
        "verified_claim_count": {
          "type": "integer"
        },
        "branch_count": {
          "type": "integer"
        },
        "pedagogical_branch_count": {
          "type": "integer"
        },
        "chapters_requiring_branches": {
          "type": "integer"
        },
        "chapters_with_branches": {
          "type": "integer"
        },
        "branch_coverage_ratio": {
          "type": "number"
        },
        "warnings": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "runtime_ms": {
          "type": "integer"
        },
        "positions_scanned": {
          "type": "integer"
        },
        "events_detected": {
          "type": "integer"
        },
        "moments_selected": {
          "type": "integer"
        },
        "cache_hit": {
          "type": "boolean"
        },
        "degraded": {
          "type": "boolean"
        },
        "opening_explanation": {
          "type": "string"
        },
        "branch_coverage": {
          "type": "object",
          "additionalProperties": true
        },
        "stage_timings": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "output_format": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "kind",
    "target_elo",
    "verification"
  ],
  "description": "Elo-aware game storyboard with optional annotated PGN, opening, story arc, ranked moments, and verification."
}
🟢explain_game(pgn, target_elo, verbosity)

Legacy alias for build_game_storyboard — Elo-aware game storyboard (read-only analysis; does not write files).

輸入結構描述

{
  "type": "object",
  "properties": {
    "pgn": {
      "type": "string",
      "description": "Full game PGN"
    },
    "target_elo": {
      "type": "integer",
      "description": "Learner Elo rating",
      "minimum": 400,
      "maximum": 3500
    },
    "verbosity": {
      "type": "string",
      "enum": [
        "minimal",
        "standard",
        "detailed"
      ],
      "description": "Storyboard chapter count: minimal (~3), standard (~5), detailed (~8)."
    }
  },
  "required": [
    "pgn",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "storyboard"
      ]
    },
    "target_elo": {
      "type": "integer",
      "minimum": 400,
      "maximum": 3500
    },
    "analysis_id": {
      "type": "string"
    },
    "annotated_pgn": {
      "type": "string",
      "description": "Legal annotated PGN when output_format includes annotated_pgn or both."
    },
    "main_lesson": {
      "type": "string"
    },
    "rendered_story": {
      "type": "string"
    },
    "human_model_available": {
      "type": "boolean"
    },
    "build": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "storyboard_pipeline_version": {
          "type": "string"
        },
        "git_sha": {
          "type": "string"
        },
        "core_git_sha": {
          "type": "string"
        },
        "adapter_git_sha": {
          "type": "string"
        },
        "adapter_version": {
          "type": "string"
        },
        "deployment_id": {
          "type": "string"
        },
        "upstream_mcp_url": {
          "type": "string"
        }
      }
    },
    "game": {
      "type": "object",
      "properties": {
        "white": {
          "type": "string"
        },
        "black": {
          "type": "string"
        },
        "result": {
          "type": "string"
        },
        "event": {
          "type": "string"
        }
      }
    },
    "opening": {
      "type": "object",
      "properties": {
        "recognized": {
          "type": "boolean"
        },
        "eco": {
          "type": "string"
        },
        "family": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "variation": {
          "type": "string"
        },
        "confidence": {
          "type": "number"
        },
        "source": {
          "type": "string"
        },
        "source_pin": {
          "type": "string"
        },
        "matched_ply": {
          "type": "integer"
        }
      }
    },
    "story_arc": {
      "type": "object",
      "properties": {
        "premise": {
          "type": "string"
        },
        "first_imbalance": {
          "type": "string"
        },
        "climax_event_id": {
          "type": "string"
        },
        "resolution": {
          "type": "string"
        },
        "main_lesson": {
          "type": "string"
        }
      }
    },
    "moments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer"
          },
          "event_id": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "anchor_ply": {
            "type": "integer"
          },
          "move_label": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "reason_selected": {
            "type": "string"
          },
          "sequence": {
            "type": "object",
            "additionalProperties": true
          },
          "branches": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      }
    },
    "engine": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "depth": {
          "type": "integer"
        }
      }
    },
    "human_model": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "available",
            "degraded",
            "unavailable"
          ]
        },
        "target_elo": {
          "type": "integer"
        }
      }
    },
    "verification": {
      "type": "object",
      "properties": {
        "pgn_legal": {
          "type": "boolean"
        },
        "all_variations_legal": {
          "type": "boolean"
        },
        "mainline_legal": {
          "type": "boolean"
        },
        "branches_legal": {
          "type": "boolean"
        },
        "mainline_preserved": {
          "type": "boolean"
        },
        "opening_verified": {
          "type": "boolean"
        },
        "claims_verified": {
          "type": "boolean"
        },
        "claim_count": {
          "type": "integer"
        },
        "verified_claim_count": {
          "type": "integer"
        },
        "branch_count": {
          "type": "integer"
        },
        "pedagogical_branch_count": {
          "type": "integer"
        },
        "chapters_requiring_branches": {
          "type": "integer"
        },
        "chapters_with_branches": {
          "type": "integer"
        },
        "branch_coverage_ratio": {
          "type": "number"
        },
        "warnings": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "runtime_ms": {
          "type": "integer"
        },
        "positions_scanned": {
          "type": "integer"
        },
        "events_detected": {
          "type": "integer"
        },
        "moments_selected": {
          "type": "integer"
        },
        "cache_hit": {
          "type": "boolean"
        },
        "degraded": {
          "type": "boolean"
        },
        "opening_explanation": {
          "type": "string"
        },
        "branch_coverage": {
          "type": "object",
          "additionalProperties": true
        },
        "stage_timings": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "output_format": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "kind",
    "target_elo",
    "verification"
  ],
  "description": "Elo-aware game storyboard with optional annotated PGN, opening, story arc, ranked moments, and verification."
}
🟢find_teaching_moments(pgn, target_elo, verbosity)

Legacy alias for build_game_storyboard — ranked storyboard chapters from a PGN (read-only analysis).

輸入結構描述

{
  "type": "object",
  "properties": {
    "pgn": {
      "type": "string",
      "description": "Full game PGN"
    },
    "target_elo": {
      "type": "integer",
      "description": "Learner Elo rating",
      "minimum": 400,
      "maximum": 3500
    },
    "verbosity": {
      "type": "string",
      "enum": [
        "minimal",
        "standard",
        "detailed"
      ],
      "description": "Storyboard chapter count: minimal (~3), standard (~5), detailed (~8)."
    }
  },
  "required": [
    "pgn",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "storyboard"
      ]
    },
    "target_elo": {
      "type": "integer",
      "minimum": 400,
      "maximum": 3500
    },
    "analysis_id": {
      "type": "string"
    },
    "annotated_pgn": {
      "type": "string",
      "description": "Legal annotated PGN when output_format includes annotated_pgn or both."
    },
    "main_lesson": {
      "type": "string"
    },
    "rendered_story": {
      "type": "string"
    },
    "human_model_available": {
      "type": "boolean"
    },
    "build": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "storyboard_pipeline_version": {
          "type": "string"
        },
        "git_sha": {
          "type": "string"
        },
        "core_git_sha": {
          "type": "string"
        },
        "adapter_git_sha": {
          "type": "string"
        },
        "adapter_version": {
          "type": "string"
        },
        "deployment_id": {
          "type": "string"
        },
        "upstream_mcp_url": {
          "type": "string"
        }
      }
    },
    "game": {
      "type": "object",
      "properties": {
        "white": {
          "type": "string"
        },
        "black": {
          "type": "string"
        },
        "result": {
          "type": "string"
        },
        "event": {
          "type": "string"
        }
      }
    },
    "opening": {
      "type": "object",
      "properties": {
        "recognized": {
          "type": "boolean"
        },
        "eco": {
          "type": "string"
        },
        "family": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "variation": {
          "type": "string"
        },
        "confidence": {
          "type": "number"
        },
        "source": {
          "type": "string"
        },
        "source_pin": {
          "type": "string"
        },
        "matched_ply": {
          "type": "integer"
        }
      }
    },
    "story_arc": {
      "type": "object",
      "properties": {
        "premise": {
          "type": "string"
        },
        "first_imbalance": {
          "type": "string"
        },
        "climax_event_id": {
          "type": "string"
        },
        "resolution": {
          "type": "string"
        },
        "main_lesson": {
          "type": "string"
        }
      }
    },
    "moments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer"
          },
          "event_id": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "anchor_ply": {
            "type": "integer"
          },
          "move_label": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "reason_selected": {
            "type": "string"
          },
          "sequence": {
            "type": "object",
            "additionalProperties": true
          },
          "branches": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      }
    },
    "engine": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "depth": {
          "type": "integer"
        }
      }
    },
    "human_model": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "available",
            "degraded",
            "unavailable"
          ]
        },
        "target_elo": {
          "type": "integer"
        }
      }
    },
    "verification": {
      "type": "object",
      "properties": {
        "pgn_legal": {
          "type": "boolean"
        },
        "all_variations_legal": {
          "type": "boolean"
        },
        "mainline_legal": {
          "type": "boolean"
        },
        "branches_legal": {
          "type": "boolean"
        },
        "mainline_preserved": {
          "type": "boolean"
        },
        "opening_verified": {
          "type": "boolean"
        },
        "claims_verified": {
          "type": "boolean"
        },
        "claim_count": {
          "type": "integer"
        },
        "verified_claim_count": {
          "type": "integer"
        },
        "branch_count": {
          "type": "integer"
        },
        "pedagogical_branch_count": {
          "type": "integer"
        },
        "chapters_requiring_branches": {
          "type": "integer"
        },
        "chapters_with_branches": {
          "type": "integer"
        },
        "branch_coverage_ratio": {
          "type": "number"
        },
        "warnings": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "runtime_ms": {
          "type": "integer"
        },
        "positions_scanned": {
          "type": "integer"
        },
        "events_detected": {
          "type": "integer"
        },
        "moments_selected": {
          "type": "integer"
        },
        "cache_hit": {
          "type": "boolean"
        },
        "degraded": {
          "type": "boolean"
        },
        "opening_explanation": {
          "type": "string"
        },
        "branch_coverage": {
          "type": "object",
          "additionalProperties": true
        },
        "stage_timings": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "output_format": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "kind",
    "target_elo",
    "verification"
  ],
  "description": "Elo-aware game storyboard with optional annotated PGN, opening, story arc, ranked moments, and verification."
}
🟢explain_position(fen, target_elo)

Explain a single position for a target learner Elo (read-only analysis).

輸入結構描述

{
  "type": "object",
  "properties": {
    "fen": {
      "type": "string",
      "description": "Position FEN"
    },
    "target_elo": {
      "type": "integer",
      "description": "Learner Elo rating",
      "minimum": 400,
      "maximum": 3500
    }
  },
  "required": [
    "fen",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "schema": {
      "type": "string"
    },
    "target_elo": {
      "type": "integer"
    },
    "fen": {
      "type": "string"
    },
    "explanation": {
      "type": "string"
    },
    "teaching_reason": {
      "type": "string"
    },
    "task": {
      "type": "object",
      "additionalProperties": true
    },
    "evidence": {
      "type": "object",
      "additionalProperties": true
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": [
    "target_elo",
    "fen"
  ],
  "description": "Learner-specific position explanation."
}
🟢compare_moves(fen, moves, target_elo)

Compare candidate moves at a position for a learner (read-only analysis).

輸入結構描述

{
  "type": "object",
  "properties": {
    "fen": {
      "type": "string",
      "description": "Position FEN"
    },
    "moves": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Candidate moves in SAN"
    },
    "target_elo": {
      "type": "integer",
      "description": "Learner Elo rating",
      "minimum": 400,
      "maximum": 3500
    }
  },
  "required": [
    "fen",
    "moves",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "schema": {
      "type": "string"
    },
    "target_elo": {
      "type": "integer"
    },
    "fen": {
      "type": "string"
    },
    "comparisons": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "move_san": {
            "type": "string"
          },
          "legal": {
            "type": "boolean"
          },
          "teaching_score": {
            "type": "number"
          },
          "explanation": {
            "type": "string"
          },
          "task": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "move_san",
          "legal"
        ]
      }
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": [
    "target_elo",
    "fen",
    "comparisons"
  ],
  "description": "Pedagogical comparison of candidate moves at a position."
}
🟢analyze_what_if(pgn, analysis_id, anchor_ply, move_label, alternative_move_san, ...)

Analyze a user-requested alternative at a mainline decision point: legal SAN validation, Stockfish continuation, Maia naturalness, teaching point, and annotated RAV PGN (read-only).

輸入結構描述

{
  "type": "object",
  "properties": {
    "pgn": {
      "type": "string",
      "description": "Full game PGN (or use analysis_id from a prior storyboard)"
    },
    "analysis_id": {
      "type": "string",
      "description": "Stored analysis id when PGN is omitted"
    },
    "anchor_ply": {
      "type": "integer",
      "description": "Mainline ply of the played move (decision point)"
    },
    "move_label": {
      "type": "string",
      "description": "Human move label e.g. 17...Be6 or 24.Rxd4"
    },
    "alternative_move_san": {
      "type": "string",
      "description": "Requested alternative in SAN — never auto-substituted"
    },
    "target_elo": {
      "type": "integer",
      "minimum": 400,
      "maximum": 3500
    },
    "analysis_profile": {
      "type": "string",
      "enum": [
        "fast",
        "chatgpt",
        "standard",
        "deep"
      ],
      "description": "Time/depth budget profile"
    },
    "max_branch_plies": {
      "type": "integer",
      "minimum": 2,
      "maximum": 16,
      "description": "Max continuation plies"
    },
    "engine_depth": {
      "type": "integer",
      "minimum": 4,
      "maximum": 20
    }
  },
  "required": [
    "alternative_move_san",
    "target_elo"
  ]
}

輸出結構描述

{
  "type": "object",
  "properties": {
    "schema": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "target_elo": {
      "type": "integer"
    },
    "anchor_ply": {
      "type": "integer"
    },
    "move_label": {
      "type": "string"
    },
    "fen_before": {
      "type": "string"
    },
    "played_move": {
      "type": "string"
    },
    "alternative_move": {
      "type": "string"
    },
    "evaluation_delta_cp": {
      "type": "integer"
    },
    "maia_probability": {
      "type": "number"
    },
    "continuation_sans": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "teaching_point": {
      "type": "string"
    },
    "rav_pgn": {
      "type": "string"
    },
    "branches_legal": {
      "type": "boolean"
    },
    "branch_semantically_attached": {
      "type": "boolean"
    },
    "mainline_preserved": {
      "type": "boolean"
    },
    "diagnostics": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": [
    "target_elo",
    "played_move",
    "alternative_move",
    "continuation_sans",
    "teaching_point",
    "rav_pgn",
    "branches_legal",
    "branch_semantically_attached"
  ],
  "description": "User-requested what-if branch with legal RAV and teaching comparison."
}

社群

為此伺服器評分

證據

近期觀測

已驗證未記錄版本6 個工具
已驗證未記錄版本6 個工具