Skip to main content
Glama

check_draft_status

Verify the claim status of a draft skill upload with a claim_token. Determine if the draft is claimed, expired, or awaiting agent verification.

Instructions

Check the status of a draft skill upload using a claim_token. / Draft 스킬 상태 공개 조회.

사용 시점:

  • 사람이 claim_url 을 클릭해서 인증을 끝냈는지 확인

  • contact_email 로 보낸 agent-level verify 메일이 처리됐는지 확인

  • Draft 가 30일 안에 claim 됐는지 / 만료됐는지 확인

Args: claim_token: upload_skill_draft 응답의 claim_token

Returns: 상태 요약 (claimed, expired, agent_verify_email_sent, agent_claimed 등).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
claim_tokenYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'check_draft_status' MCP tool. It accepts a claim_token, calls the API endpoint /v1/drafts/status, and returns a formatted status summary (claimed, expired, agent_claimed, etc.). Decorated with @mcp.tool() and @_log_tool.
    @mcp.tool()
    @_log_tool
    def check_draft_status(claim_token: str) -> str:
        """
        Check the status of a draft skill upload using a claim_token. / Draft 스킬 상태 공개 조회.
    
        사용 시점:
          - 사람이 claim_url 을 클릭해서 인증을 끝냈는지 확인
          - contact_email 로 보낸 agent-level verify 메일이 처리됐는지 확인
          - Draft 가 30일 안에 claim 됐는지 / 만료됐는지 확인
    
        Args:
            claim_token: upload_skill_draft 응답의 claim_token
    
        Returns:
            상태 요약 (claimed, expired, agent_verify_email_sent, agent_claimed 등).
        """
        if not claim_token or not claim_token.strip():
            return "❌ claim_token 은 필수입니다."
        import urllib.parse as _up
        result = _get(f"/v1/drafts/status?claim_token={_up.quote(claim_token.strip())}")
        if result.get("status") == "error" or result.get("error_code"):
            code = result.get("error_code") or "ERROR"
            msg = result.get("detail") or result.get("message") or "조회 실패"
            return f"❌ [{code}]: {msg}"
    
        claimed = bool(result.get("claimed"))
        expired = bool(result.get("expired"))
        agent_claimed = bool(result.get("agent_claimed"))
        icon = "✅" if claimed else ("⏳" if not expired else "⌛")
    
        lines = [
            f"{icon} Draft 상태 — {result.get('skill_name')}",
            f"  skill_id:                 {result.get('skill_id')}",
            f"  draft_agent_author:       {result.get('draft_agent_author')}",
            f"  created_at:               {result.get('created_at')}",
            f"  expires_at:               {result.get('expires_at')}",
            f"  claimed (skill-level):    {claimed}{' at ' + result['claimed_at'] if claimed else ''}",
            f"  expired:                  {expired}",
            f"  verify_email_sent:        {result.get('verify_email_sent')}  (skill-level 1:1 legacy)",
            f"  agent_verify_email_sent:  {result.get('agent_verify_email_sent')}  (agent-level, 2026-04-23)",
            f"  agent_claimed:            {agent_claimed}  (agent identity 이미 계정에 귀속)",
        ]
        if not claimed and not expired and not agent_claimed:
            lines.append("  ⏳ 아직 사람이 claim 하지 않았습니다. claim_url 을 사용자에게 전달했는지 확인하세요.")
        if agent_claimed and not claimed:
            lines.append("  ℹ️ agent-level claim 은 완료됐으나 이 특정 Draft 는 아직 이전 안 됐을 수 있음 — "
                         "vetting 완료 후 자동으로 owner 계정에 귀속됩니다.")
        return "\n".join(lines)
  • The @mcp.tool() decorator registers 'check_draft_status' as an MCP tool on the FastMCP server instance.
    @mcp.tool()
    @_log_tool
  • The _get() helper function is called by check_draft_status to make the GET request to /v1/drafts/status?claim_token=... It returns parsed JSON or an error dict.
    def _get(path: str, params: dict = None) -> dict:
        url = SKILL_STORE_URL + path
        if params:
            url += "?" + urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
        try:
            with urllib.request.urlopen(url, timeout=10) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            return {"status": "error", "message": f"HTTP {e.code}: {e.reason}"}
        except Exception as e:
            return {"status": "error", "message": str(e)}
Behavior3/5

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

No annotations are provided, so the description must cover behavioral traits. It indicates the tool returns a status summary (claimed, expired, etc.) and implies it is a read-only query, but does not disclose idempotency, rate limits, or token validity beyond the initial upload.

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?

The description is concise, starting with a clear purpose in English and Korean, followed by structured usage points and parameter/return details. Every sentence adds value with 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?

With only one parameter, clear purpose, and an output schema that exists, the description provides sufficient context. It lists possible return statuses and the conditions for calling the tool, making it complete for its complexity.

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

Parameters3/5

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

Schema coverage is 0%, but the description explains that claim_token comes from the upload_skill_draft response, adding crucial context. However, it does not specify the token's format, length, or any constraints, leaving some gaps.

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?

The description clearly states the tool checks the status of a draft skill upload using a claim_token. It lists three specific use cases (verifying if a claim_url was clicked, agent-level verify email processed, or draft claimed/expired), distinguishing it from siblings like check_vetting_status which checks different tokens.

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?

The description explicitly provides a 'when to use' section with three bullet points, defining clear contexts for invoking this tool. While it does not mention when not to use it or alternative tools, the guidance is strong enough for typical use.

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/garasegae/aiskillstore'

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