1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JiraでAIを強化する | 第2章:タスクを自動化:AIによるTicketとコメント操作

Posted at

はじめに

第1章では、Jiraと**Model Context Protocol(MCP)**の基本を学び、JiraプロジェクトからTicketやSprintデータを取得するMCPサーバーを構築しました。これにより、AIがプロジェクトの情報を取得できるようになりました。今回は、この基盤を進化させ、JiraにTicketを作成したり、コメントを追加したりする機能を実装します。これにより、タスクを自動化するエージェントを構築します。

この第2章では、MCPサーバーを通じてAIがTicketに優先度を付けたり、コメントを追加したりできるようにします。たとえば、ユーザーが特定のキーワードを含むTicketを作成すると、AIが自動で「High」優先度を付けることができます。コード例とステップごとのガイドで、プロジェクトタスク自動化の可能性を体感しましょう。さあ、始めましょう!

タスク自動化エージェントとは?

タスク自動化エージェントは、JiraのTicketやコメントを操作し、プロジェクト管理を効率化するAIです。MCPサーバーを介して、以下のような機能を実現できます:

  • Ticket管理:Ticketの作成、優先度設定、コメント追加。
  • 自動化ルール:特定の条件(例:キーワードやステータス)に基づいてアクションを実行。
  • チーム支援:Ticketの割り当てや通知を最適化。

ユースケース

  • バグ管理:AIが「エラー」キーワードを含むTicketに「High」優先度を自動付与。
  • コミュニケーション:AIがTicketに初期コメントを追加し、担当者に指示。
  • ワークフロー最適化:AIが期限付きTicketを作成し、チームに割り当て。

開発環境の準備

第1章の環境を基に、以下の準備を行います:

  • Python 3.8以降mcpライブラリrequestsライブラリClaude Desktop:第1章と同じ。
  • python-dotenv:環境変数の管理(既にインストール済み)。
  • Jiraプロジェクト:Ticket操作のための設定。

Jiraのセットアップ

  1. Jira APIトークンの確認
    • 第1章のトークンを使用。
    • 権限を確認:プロジェクトでのTicket作成、編集、コメント追加が可能。
  2. プロジェクト準備
    • 第1章のプロジェクト(例:MCP-TEST、キー:MCP)を使用。
    • Ticketタイプ(例:Bug、Task)と優先度(例:High、Medium、Low)を設定。
    • テスト用ユーザーをプロジェクトに追加(コメントや割り当て用)。
  3. 環境変数
    第1章の.envファイル(JIRA_URLJIRA_EMAILJIRA_API_TOKENJIRA_PROJECT_KEY)を再利用:
    JIRA_URL=https://your-domain.atlassian.net
    JIRA_EMAIL=your_email@example.com
    JIRA_API_TOKEN=your_jira_api_token
    JIRA_PROJECT_KEY=MCP
    

コード例:タスク自動化用MCPサーバー

以下のMCPサーバーは、JiraからTicketデータを取得し、Ticket作成やコメント追加の機能を提供します。

from mcp import MCPServer
import os
from dotenv import load_dotenv
import requests
from requests.auth import HTTPBasicAuth

class JiraTaskServer(MCPServer):
    def __init__(self, host, port, url, email, api_token, project_key):
        super().__init__(host, port)
        self.url = url
        self.email = email
        self.api_token = api_token
        self.project_key = project_key
        self.base_url = f"{url}/rest/api/3"
        self.auth = HTTPBasicAuth(email, api_token)
        self.headers = {
            "Accept": "application/json",
            "Content-Type": "application/json"
        }
        self.register_resource("get_tickets", self.get_tickets)
        self.register_tool("create_ticket", self.create_ticket)
        self.register_tool("add_comment", self.add_comment)

    def get_tickets(self, params):
        try:
            url = f"{self.base_url}/search"
            query = {
                "jql": f"project={self.project_key} AND status={params.get('status', 'Open')}",
                "maxResults": params.get("limit", 10)
            }
            response = requests.get(url, headers=self.headers, auth=self.auth, params=query)
            response.raise_for_status()
            issues = response.json()["issues"]
            ticket_list = [
                {
                    "key": issue["key"],
                    "summary": issue["fields"]["summary"],
                    "status": issue["fields"]["status"]["name"],
                    "creator": issue["fields"]["creator"]["displayName"],
                    "created": issue["fields"]["created"]
                }
                for issue in issues
            ]
            return {"status": "success", "tickets": ticket_list}
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def create_ticket(self, params):
        try:
            summary = params.get("summary", "")
            description = params.get("description", "")
            issue_type = params.get("issue_type", "Task")
            priority = params.get("priority", "Medium")
            if not summary:
                return {"status": "error", "message": "サマリーが必要です"}
            
            url = f"{self.base_url}/issue"
            payload = {
                "fields": {
                    "project": {"key": self.project_key},
                    "summary": summary,
                    "description": description,
                    "issuetype": {"name": issue_type},
                    "priority": {"name": priority}
                }
            }
            response = requests.post(url, headers=self.headers, auth=self.auth, json=payload)
            response.raise_for_status()
            issue = response.json()
            return {"status": "success", "ticket_key": issue["key"]}
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def add_comment(self, params):
        try:
            ticket_key = params.get("ticket_key", "")
            comment = params.get("comment", "")
            if not ticket_key or not comment:
                return {"status": "error", "message": "Ticketキーとコメントが必要です"}
            
            url = f"{self.base_url}/issue/{ticket_key}/comment"
            payload = {"body": comment}
            response = requests.post(url, headers=self.headers, auth=self.auth, json=payload)
            response.raise_for_status()
            comment = response.json()
            return {"status": "success", "comment_id": comment["id"]}
        except Exception as e:
            return {"status": "error", "message": str(e)}

if __name__ == "__main__":
    load_dotenv()
    server = JiraTaskServer(
        host="localhost",
        port=8133,
        url=os.getenv("JIRA_URL"),
        email=os.getenv("JIRA_EMAIL"),
        api_token=os.getenv("JIRA_API_TOKEN"),
        project_key=os.getenv("JIRA_PROJECT_KEY")
    )
    print("JiraタスクMCPサーバーを起動中: http://localhost:8133")
    server.start()

コードの説明

  • get_tickets:第1章から再利用。プロジェクトのTicketを取得。
  • create_ticket:新しいTicketを作成。サマリー、説明、課題タイプ、優先度を指定。
  • add_comment:指定したTicketにコメントを追加。Ticketキーとコメント内容を指定。
  • register_resource/tool:Ticket取得をリソース、Ticket作成・コメント追加をツールとして登録。

前提条件

  • Jira APIトークンにプロジェクトへの書き込み権限がある。
  • プロジェクトに課題タイプ(例:Bug、Task)と優先度(例:High、Medium、Low)が設定済み。
  • .envファイルに正しいJIRA_URLJIRA_EMAILJIRA_API_TOKENJIRA_PROJECT_KEYが設定済み。

サーバーのテスト

サーバーが正しく動作するか確認します:

  1. サーバー起動

    python jira_task_server.py
    

    コンソールに「JiraタスクMCPサーバーを起動中: http://localhost:8133」と表示。

  2. Ticket作成のテスト
    Pythonでリクエストを送信:

    import requests
    import json
    
    url = "http://localhost:8133"
    payload = {
        "jsonrpc": "2.0",
        "method": "create_ticket",
        "params": {
            "summary": "新しいバグ報告",
            "description": "アプリがクラッシュする問題が発生。",
            "issue_type": "Bug",
            "priority": "High"
        },
        "id": 1
    }
    response = requests.post(url, json=payload)
    print(json.dumps(response.json(), indent=2, ensure_ascii=False))
    

    期待されるレスポンス:

    {
      "jsonrpc": "2.0",
      "result": {
        "status": "success",
        "ticket_key": "MCP-3"
      },
      "id": 1
    }
    
  3. コメント追加のテスト

    payload = {
        "jsonrpc": "2.0",
        "method": "add_comment",
        "params": {
            "ticket_key": "MCP-3",
            "comment": "問題を確認しました。詳細を教えてください。"
        },
        "id": 2
    }
    response = requests.post(url, json=payload)
    print(json.dumps(response.json(), indent=2, ensure_ascii=False))
    

    期待されるレスポンス:

    {
      "jsonrpc": "2.0",
      "result": {
        "status": "success",
        "comment_id": "10001"
      },
      "id": 2
    }
    

Claude Desktopとの接続

サーバーをClaude Desktopに接続します:

  1. 設定ファイルの編集
    Claude Desktopの設定ファイル(例:claude_desktop_config.json)に以下を追加:

    {
      "mcp_servers": [
        {
          "name": "JiraTaskServer",
          "url": "http://localhost:8133",
          "auth": "none"
        }
      ]
    }
    
  2. Claudeでテスト
    Claude Desktopを起動し、プロンプトを入力:

    プロジェクトに「新しいバグ報告」というBug Ticketを作成し、優先度を「High」にしてください。
    

    レスポンス例:

    Ticket MCP-3「新しいバグ報告」を作成し、優先度を「High」に設定しました。
    

    別のプロンプト:

    Ticket MCP-3に「問題を確認しました。詳細を教えてください。」とコメントしてください。
    

    レスポンス例:

    Ticket MCP-3にコメントを追加しました。
    

実装のコツと注意点

  • エラーハンドリング:無効なTicketキーや優先度が存在しない場合のエラーを適切に処理。
  • レートリミティング:Jira APIの制限(例:600リクエスト/分、クラウドインスタンスによる)に注意。
  • セキュリティ:本番環境では、auth: noneを避け、トークン認証を導入。
  • テスト:テスト用プロジェクトを作成し、本番データに影響を与えない。
  • 拡張性:大量のTicketを処理する場合、キャッシュ(例:Redis)を検討。

試してみよう:挑戦課題

以下の機能を追加して、エージェントを強化してみてください:

  • 特定のキーワード(例:「エラー」)を含むTicketに自動で「High」優先度を付ける機能。
  • Ticketに担当者を割り当てるツール。
  • Ticketのステータスを更新(例:Open → In Progress)する機能。

まとめと次のステップ

この第2章では、JiraにTicketを作成し、コメントを追加するMCPサーバーを構築し、プロジェクトタスク自動化エージェントを実現しました。AIがTicketを操作できるようになり、チームの効率が向上しました。

次の第3章では、JiraのTicketデータを活用してプロジェクト分析エージェントを構築します。たとえば、AIがSprintの完了率やチームのパフォーマンスを分析し、プロジェクトのインサイトを提供します。プロジェクト分析AIに興味がある方は、ぜひお楽しみに!


役に立ったと思ったら、「いいね」や「ストック」をしていただけると嬉しいです!次の章でまたお会いしましょう!

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?