Skip to main content
Glama
kao273183
by kao273183

score_initiative

Score product initiatives via RICE or Impact-Effort. Resolve from source record with initiative_id, or score ad-hoc using raw_text and optional overrides. Returns score, breakdown, priority tier, and rationale.

Instructions

Score one initiative with RICE or Impact-Effort. Pass initiative_id to score a source-resolved record (RICE inputs are read from raw_metadata) or raw_text + overrides for an ad-hoc score without a source record. method = 'rice' (default) or 'impact_effort'. overrides = {reach, impact, confidence, effort} — any subset; takes precedence over what was in the source. RICE tier thresholds: P0 > 25, P1 10..25, P2 3..10, P3 < 3. Every call with initiative_id appends a scored decision to the index at PLAN_PROJECT_ROOT/.mk-plan-master/index.json. Returns {initiative_id, method, score, breakdown, tier, rationale, stored}.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
initiative_idNo
raw_textNo
methodNorice
overridesNo

Implementation Reference

  • Main handler function for score_initiative tool. Orchestrates scoring by parsing arguments, fetching initiative metadata if initiative_id provided, delegating to _score_with_method, recording to index, and returning the result.
    def score_initiative_tool(arguments: dict) -> dict[str, Any]:
        method = (arguments.get("method") or "rice").lower()
        if method not in _VALID_METHODS:
            return _error(
                f"unknown scoring method: {method!r}",
                retryable=False,
                hint=f"Use one of {sorted(_VALID_METHODS)}.",
            )
    
        initiative_id = arguments.get("initiative_id")
        raw_text = arguments.get("raw_text")
        overrides = arguments.get("overrides") or {}
    
        if not initiative_id and not raw_text:
            return _error(
                "either initiative_id or raw_text is required",
                retryable=False,
                hint=(
                    "Pass initiative_id (resolved via the active adapter) or "
                    "raw_text + overrides for ad-hoc scoring without a source record."
                ),
            )
    
        initiative: Initiative | None = None
        meta: dict = {}
        title = ""
        url = ""
        source_name = ""
    
        if initiative_id:
            try:
                initiative = _fetch_initiative(str(initiative_id))
            except ValueError as exc:
                return _error(
                    str(exc),
                    retryable=False,
                    hint="Confirm initiative_id via list_initiatives.",
                )
            except Exception as exc:
                return _error(
                    f"{type(exc).__name__}: {exc}",
                    retryable=True,
                    hint="Transient adapter error — retry, then check credentials / network.",
                )
            meta = dict(initiative.raw_metadata)
            title = initiative.title
            url = initiative.url
            source_name = initiative.source
    
        result = _score_with_method(method, meta, overrides)
        used_id = str(initiative_id) if initiative_id else ""
    
        stored = False
        if used_id:
            try:
                decisions_index.record_score(
                    used_id,
                    method=method,
                    score=result["score"],
                    tier=result["tier"],
                    breakdown=result["breakdown"],
                    source=source_name,
                    title=title,
                    url=url,
                )
                stored = True
            except OSError as exc:
                return _error(
                    f"index write failed: {exc}",
                    retryable=True,
                    hint="Confirm PLAN_PROJECT_ROOT is writable.",
                )
    
        return {
            "initiative_id": used_id,
            "method": method,
            "score": result["score"],
            "breakdown": result["breakdown"],
            "tier": result["tier"],
            "rationale": result["rationale"],
            "stored": stored,
        }
  • Internal scoring dispatcher that routes to RICE or Impact-Effort scoring based on method parameter, computing score, breakdown, tier, and rationale.
    def _score_with_method(method: str, meta: dict, overrides: dict) -> dict:
        """Returns {score, breakdown, tier, rationale}. Pure arithmetic — no
        side effects, no index writes; that's the caller's job."""
        if method == "rice":
            inputs = _rice_inputs(meta, overrides)
            score = rice_score(**inputs)
            return {
                "score": score,
                "breakdown": inputs,
                "tier": rice_tier(score),
                "rationale": rice_rationale(**inputs),
            }
        # impact_effort
        inputs = _impact_effort_inputs(meta, overrides)
        score = impact_effort_score(**inputs)
        return {
            "score": score,
            "breakdown": inputs,
            "tier": impact_effort_quadrant(**inputs),
            "rationale": impact_effort_rationale(**inputs),
        }
  • Builds RICE input dict from initiative metadata and applies overrides (reach, impact, confidence, effort).
    def _rice_inputs(meta: dict, overrides: dict) -> dict:
        """Build the RICE input dict from initiative metadata, then apply any
        explicit overrides on top (AI / user wins over what's in the source)."""
        inputs = {
            "reach": _to_float(meta.get("reach"), RICE_DEFAULTS["reach"]),
            "impact": _coerce_impact(meta.get("impact")),
            "confidence": _to_float(meta.get("confidence"), RICE_DEFAULTS["confidence"]),
            "effort": _to_float(meta.get("effort"), RICE_DEFAULTS["effort"]),
        }
        if "reach" in overrides:
            inputs["reach"] = _to_float(overrides["reach"], inputs["reach"])
        if "impact" in overrides:
            inputs["impact"] = _coerce_impact(overrides["impact"])
        if "confidence" in overrides:
            inputs["confidence"] = _to_float(overrides["confidence"], inputs["confidence"])
        if "effort" in overrides:
            inputs["effort"] = _to_float(overrides["effort"], inputs["effort"])
        return inputs
  • Builds Impact-Effort input dict (1..5 scale) from metadata and overrides.
    def _impact_effort_inputs(meta: dict, overrides: dict) -> dict:
        """1..5 scale for both axes. If raw RICE-style values are present
        (impact 0.25..3), pass them through unchanged — the quadrant cutoff
        is independent of scale magnitude."""
        impact = _to_float(overrides.get("impact"), _coerce_impact(meta.get("impact")))
        effort = _to_float(overrides.get("effort"), _to_float(meta.get("effort"), 1))
        return {"impact": impact, "effort": effort}
  • Dispatch table registering 'score_initiative' -> scoring_tools.score_initiative_tool
    _DISPATCH: dict[str, Callable[[dict], dict]] = {
        "get_plan_source_info": initiatives_tools.get_plan_source_info_tool,
        "list_initiatives": initiatives_tools.list_initiatives_tool,
        "fetch_initiative": initiatives_tools.fetch_initiative_tool,
        "add_initiative": initiatives_tools.add_initiative_tool,
        "analyze_initiative": analysis_tools.analyze_initiative_tool,
        "score_initiative": scoring_tools.score_initiative_tool,
        "rank_backlog": scoring_tools.rank_backlog_tool,
        "generate_spec_draft": bridge_tools.generate_spec_draft_tool,
        "generate_roadmap": roadmap_tools.generate_roadmap_tool,
        "analyze_roadmap_balance": roadmap_tools.analyze_roadmap_balance_tool,
        "init_plan_knowledge": plan_knowledge_tools.init_plan_knowledge_tool,
        "get_plan_context": plan_knowledge_tools.get_plan_context_tool,
        "get_planning_history": history_tools.get_planning_history_tool,
        "get_decision_signature": history_tools.get_decision_signature_tool,
  • Tool registration with name, description, and inputSchema for score_initiative
    Tool(
        name="score_initiative",
        description=(
            "Score one initiative with RICE or Impact-Effort. Pass "
            "initiative_id to score a source-resolved record (RICE inputs are "
            "read from raw_metadata) or raw_text + overrides for an ad-hoc "
            "score without a source record. method = 'rice' (default) or "
            "'impact_effort'. overrides = {reach, impact, confidence, effort} "
            "— any subset; takes precedence over what was in the source. "
            "RICE tier thresholds: P0 > 25, P1 10..25, P2 3..10, P3 < 3. "
            "Every call with initiative_id appends a `scored` decision to the "
            "index at PLAN_PROJECT_ROOT/.mk-plan-master/index.json. "
            "Returns {initiative_id, method, score, breakdown, tier, "
            "rationale, stored}."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "initiative_id": {"type": "string"},
                "raw_text": {"type": "string"},
                "method": {"type": "string", "default": "rice"},
                "overrides": {"type": "object"},
            },
        },
    ),
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses side effect of appending scored decisions to index on every call with initiative_id, and specifies tier thresholds. No annotations, so description carries burden. Lacks authorization or rate limit info, but sufficient for basic transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise and well-structured: first sentence states core purpose, then details mode, method, overrides, side effect, return. No redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all essential aspects: purpose, two usage modes, parameter details, side effects, output format, tier thresholds. No major gaps for agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Explains the purpose of each parameter: initiative_id for source-resolved, raw_text for ad-hoc, method enum values, overrides object with individual fields and precedence rule. Adds meaning beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly describes scoring initiatives with RICE or Impact-Effort, distinguishes two modes (source-resolved vs ad-hoc), and method options. Differentiates from siblings like add_initiative (add) and analyze_initiative (analyze).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit context for when to use each parameter combination (initiative_id vs raw_text), and mentions default method and overrides. However, does not compare with sibling tools or specify when not to use this tool (e.g., for qualitative analysis).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kao273183/mk-plan-master'

If you have feedback or need assistance with the MCP directory API, please join our Discord server