mcpField
T
Tempo MCP Server

Tempo MCP Server

ローカル
github.com/ivelin-web生産性4817 週間前に更新

Tempo MCP Server について

Tempo MCP Server は Jira 上の Tempo ワークログを管理し、Claude や Cursor などの MCP クライアントから作成、編集、削除、集計を行えるようにします。AI で工数入力を扱いたい Jira ユーザーを対象とし、リモートとローカルの両方で実行できます。

主な機能

  1. 01指定期間のワークログ取得
  2. 02ワークログの作成、一括作成、編集、削除
  3. 03ワークログ未入力の営業日の確認
  4. 04課題、アカウント、日、週、月単位の時間集計
  5. 05Cloudflare Workers へのリモートデプロイ

活用シーン

  1. 01チャットから Jira 課題へのワークログ登録
  2. 02一定期間のワークログの一括インポート
  3. 031週間や1か月で工数が未入力の営業日の確認

MCP 対応

MCP サーバーとして動作し、Tempo のワークログ関連ツールを Claude や Cursor などのクライアントに提供し、Tempo と Jira API を通じて操作を実行します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"tempo": {
"command": "npx",
"args": [
"-y",
"wrangler"
]
}
}
}
起動コマンドnpx -y wrangler

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmwrangler

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

MseeP.ai セキュリティ評価バッジ

Tempo MCP サーバー

Jira の Tempo 作業ログを管理する Model Context Protocol(MCP)サーバーです。このサーバーは Tempo の API を通じて時間を記録し、作業ログを管理するツールを提供します。Claude、Cursor などの MCP 対応クライアントから利用できます。

npm バージョン ライセンス:MIT

機能

  • 作業ログの取得:指定した期間の作業ログをすべて取得します
  • 作業ログの作成:Jira 課題に作業時間を記録します
  • 一括作成:複数の作業ログを一度の操作で作成します
  • 作業ログの編集:作業時間、日付、説明を変更します
  • 作業ログの削除:既存の作業ログを削除します
  • 未記録日のレポート:想定より少ない時間しか記録していない営業日を見つけます(Tempo のユーザースケジュールを使用するため、休日と非稼働日は自動的に除外されます)
  • 作業ログの分析:課題、アカウント、日、週、月ごとに時間を集計し、合計と割合を表示します

システム要件

  • Node.js 18+(LTS を推奨)— ローカルの stdio モードでのみ必要です
  • Jira Cloud インスタンス
  • Tempo API トークン
  • Jira API トークン(OAuth 2.0 PKCE 認証を使用する場合は不要です)

使用方法

この MCP サーバーには、次の 3 つの使用方法があります。

  1. リモート/Cloudflare Workers(インストール不要) — 一度ホストして、チームで共有します。各ユーザーはセットアップページから自分専用の URL を生成し、Claude.ai または ChatGPT に貼り付けます。ウェブとモバイルから利用できます。
  2. NPX:ノート PC 上で npx を使って直接実行します。クローンは不要です。
  3. ローカルクローン:開発やカスタマイズのためにリポジトリをクローンします。

サーバーを使いたいだけの場合は、オプション 1 が最も簡単で、スマートフォンからも利用できます。チーム向けにデプロイするメンテナーの方は、リモートデプロイガイドをご覧ください。

オプション 1:リモート(Cloudflare Workers)

エンドユーザー向け

チームでサーバーをデプロイした後は、次の手順で利用できます。

  1. https://<your-deployment>.workers.dev/setup を開きます。
  2. Tempo API トークン、Jira のベース URL、Jira API トークン、Jira のメールアドレスを貼り付けます。Generate MCP URL をクリックします。
  3. ページに https://<your-deployment>.workers.dev/mcp/u_<random> のような個人用 URL が表示されます。コピーします。
  4. Claude.ai → Settings → Connectors → Add custom connector で、URL を貼り付けます。
  5. コネクターはウェブ、デスクトップ、モバイル(iOS/Android)間で同期されます。

ChatGPT の場合:Settings → Apps → Advanced → Developer mode(Pro/Plus/Business+)を有効にしてから、URL をカスタム MCP サーバーとして追加します。Plus/Pro アカウントでは読み取りが可能です。書き込みツール(作業ログの作成/編集)を利用するには、OpenAI のプランに応じて Business+ が必要です。

URL には認証情報が含まれています。パスワードと同様に扱い、共有したりコミットしたりしないでください。

リモートデプロイ(Cloudflare Workers)

Cloudflare Workers の無料プランでホスティングできます。クローンから URL の公開まで約 5〜10 分です。誰でもフォークしてセルフホストでき、上流リポジトリとの調整は不要です。

前提条件
  • Cloudflare アカウント(無料プランで十分です)。
  • ローカル環境の Node.js 18+ と npm — wrangler CLI にのみ使用します。Worker ランタイム自体は Node を実行しません。
初回セットアップ
git clone https://github.com/ivelin-web/tempo-mcp-server.git
cd tempo-mcp-server
npm install

# 1. Log in to Cloudflare (opens browser).
npx wrangler login

# 2. Create your own KV namespace for per-user credentials.
npx wrangler kv namespace create USERS

⚠️ **リポジトリをフォークした場合:**コミット済みの wrangler.jsonc にある kv_namespaces[0].id は、上流メンテナーの Cloudflare アカウントに属しています。これを手順 2 で返された ID に置き換えてください。そうしないと、wrangler deploy は KV namespace … is not valid というエラーで失敗します。KV 名前空間 ID はアカウントごとに公開される識別子であり、秘密情報ではありませんが、アカウントごとに異なります。

# 3. Generate and store the encryption key.
#    Used to AES-GCM-encrypt per-user credentials in KV.
openssl rand -base64 48 | npx wrangler secret put ENCRYPTION_KEY

# 4. (Optional) Pin the CORS origin. Defaults to "*". Set it if you only
#    want browsers from a specific app to call the Worker.
echo "https://claude.ai" | npx wrangler secret put ALLOWED_ORIGIN

# 5. Deploy.
npm run remote:deploy
# → outputs https://tempo-mcp-server.<your-account>.workers.dev

デプロイされた URL の /setup にアクセスして、最初のユーザーを登録します。

既存のデプロイを更新する

upstream から新しいコミットをプルした後:

npm install              # picks up any new deps
npm run remote:deploy    # ships the new Worker bundle

シークレットと KV データはデプロイ後も保持されます。wrangler.jsonc の compatibility_date と compatibility_flags は固定されているため、Cloudflare がランタイムを変更しても、動作が予期せず変わることはありません。

ローカル開発
cp .dev.vars.example .dev.vars
# edit .dev.vars and put a real ENCRYPTION_KEY (any value works locally)
npm run remote:dev
# → http://localhost:8787 with a mock KV; data is wiped between sessions

その他の便利なスクリプト:

  • npm run remote:typecheck — Worker バンドルの型チェックを実行します(tsconfig.worker.json を使用)。
  • npm run remote:tail — デプロイ済み Worker のライブログをストリーミングします。
トラブルシューティング
  • KV namespace … is not valid — wrangler.jsonc の kv_namespaces[0].id が空(または誤り)です。npx wrangler kv namespace create USERS を実行し、新しい ID を貼り付けてください。
  • 実行時に ENCRYPTION_KEY is not defined が発生する — シークレットが設定されていません。手順 3 をもう一度実行してください。
  • Rate limit binding … not available — ご利用のアカウントのプランには Workers Rate Limiting API が含まれていません。プランをアップグレードするか、wrangler.jsonc の ratelimits ブロックと src/remote/worker.ts の SETUP_RATE_LIMITER.limit(...) 呼び出しを削除してください。
  • /mcp/u_… から 404 が返される — ユーザー ID が不明(または存在したことがありません)。Worker は無効な ID や存在しない ID に対して仕様上 404 を返します。ユーザーに /setup を再実行してもらってください。
  • 既存ユーザーが突然接続できなくなった — 最も可能性が高い原因は ENCRYPTION_KEY のローテーションです。既存の AES-GCM データは新しいキーでは復号できません。以下の警告を参照してください。
仕組み

認証情報の保存: /setup の POST ハンドラーはフォームデータを ENCRYPTION_KEY で AES-GCM 暗号化し、KV に user:u_<random> というキーで保存します。MCP リクエストごとにこのレコードを読み取って復号し、そのリクエスト専用の McpServer を構築して、Cloudflare 公式の createMcpHandler 経由で処理します。リクエスト間で認証情報をメモリに保持することはなく、Durable Objects も使用しません。

ENCRYPTION_KEY は長期間使用するものとして扱ってください。 ローテーションすると、既存のすべてのユーザーレコードが無効になり(AES-GCM タグが新しいキーでは検証できなくなります)、すべてのユーザーに /setup を再実行してもらう必要があります。openssl rand -base64 48 でキーを一度生成し、変更しないでください。

認証モデル: URL /mcp/u_<id> 自体が認証情報です。22 文字の base64url ID には約 128 ビットのエントロピーがあります。このパスでは 401 を返しません(Claude.ai web には 401 の後に OAuth フローを実行する場合の既知の不具合があるためです)。不明な ID には 404 を返します。これは Zapier MCP、Pipedream MCP などで使われている URL トークン方式と同じです。

すでに実装済みのセキュリティ強化:

  • Cloudflare のネイティブ Rate Limiting バインディングを使い、POST /setup に IP ごとのレート制限(5 リクエスト/分)を設定しています。
  • /setup のレスポンスに Cache-Control: no-store を設定しているため、MCP URL を含む成功ページも、トークンをそのまま表示するエラーページも、キャッシュに保存されることはありません。
  • すべての HTML ページに Referrer-Policy: no-referrer を設定しているため、MCP URL がリファラーヘッダーを通じて漏れることはありません。

把握しておくべき制限事項:

  • Workers の無料プラン:1 日あたり 10 万リクエスト、リクエストあたりの CPU 時間は 50ms です(この処理は I/O 待ちが中心なので、余裕があります)。
  • KV の無料プラン:1 日あたり 10 万回の読み取り、1,000 回の書き込みです。セットアップ時にユーザーごとに一度書き込み、MCP 呼び出しごとに読み取ります。
  • Worker は Jira の基本認証(従来の API トークンとメールアドレス)のみをサポートします。Bearer と OAuth 2.0 PKCE フローは stdio 専用です。Bearer には Worker がまだ対応していないゲートウェイ URL ルーティングが必要で、PKCE には Worker でホストできないブラウザーコールバックが必要です。

オプション 2:NPX の使用方法

このサーバーを使う最も簡単な方法は、インストールせずに npx 経由で実行することです。

Claude Desktop に接続する(NPX 方式)
  1. MCP クライアントの設定ファイルを開きます。

    • Claude Desktop(macOS):~/Library/Application Support/Claude/claude_desktop_config.json
    • Claude Desktop(Windows):%APPDATA%\Claude\claude_desktop_config.json
  2. 以下の設定を追加します。

{
  "mcpServers": {
    "Jira_Tempo": {
      "command": "npx",
      "args": ["-y", "@ivelin-web/tempo-mcp-server"],
      "env": {
        "TEMPO_API_TOKEN": "your_tempo_api_token_here",
        "JIRA_API_TOKEN": "your_jira_api_token_here",
        "JIRA_EMAIL": "[email protected]",
        "JIRA_BASE_URL": "https://your-org.atlassian.net"
      }
    }
  }
}
  1. Claude Desktop クライアントを再起動します。
Cursor 向けワンクリックインストール

MCP サーバーをインストール

オプション 3:ローカルリポジトリのクローン

インストール
# Clone the repository
git clone https://github.com/ivelin-web/tempo-mcp-server.git
cd tempo-mcp-server

# Install dependencies
npm install

# Build TypeScript files
npm run build
ローカルでの実行

サーバーをローカルで実行する方法は 2 つあります。

1. MCP Inspector を使用する(開発およびデバッグ用)
npm run inspect
2. Node を直接使用する

ビルド済みの JavaScript ファイルを指定して、Node でサーバーを直接実行できます。

Claude Desktop への接続(ローカル方式)
  1. MCP クライアントの設定ファイルを開きます。
  2. 次の設定を追加します。
{
  "mcpServers": {
    "Jira_Tempo": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/tempo-mcp-server/build/index.js"],
      "env": {
        "TEMPO_API_TOKEN": "your_tempo_api_token_here",
        "JIRA_API_TOKEN": "your_jira_api_token_here",
        "JIRA_EMAIL": "[email protected]",
        "JIRA_BASE_URL": "https://your-org.atlassian.net"
      }
    }
  }
}
  1. Claude Desktop クライアントを再起動します。

API トークンの取得

  1. Tempo API トークン:

    • Tempo > Settings > API Integration に移動します。
    • Custom access を選択し、最低限次の項目を選んで、新しい API トークンを作成します。
      • Worklogs(表示+管理)— すべての作業ログツールに必要です。
      • Schemes(表示)— getMissingWorklogDays に必要です(ユーザーのスケジュールを読み取ります)。
      • Accounts(表示)— 作業ログで Tempo アカウントを使用する場合にのみ必要です。
      • Teams(表示)— program / team フィルターを使用する場合にのみ必要です(Teams と Programs の両方を対象とします)。
    • Tempo では既存のトークンのスコープを編集できません。後からスコープを追加する必要がある場合は、新しいトークンを作成してください。
  2. Jira API トークン:

    • Atlassian API トークンに移動します。
    • 「Create API token」(従来のスコープなしの方法)をクリックします。これは basic 認証ですぐに使用できます。
    • 「Create API token with scopes」は使用しないでください。これらのトークンは、クラウド ID とともに Atlassian のゲートウェイ URL(https://api.atlassian.com/ex/jira/{cloudId}/...)経由で送信する必要がありますが、このサーバーの basic 認証経路は現在そこにルーティングされません。サイト URL に対して 401 エラーになります。スコープ付きトークンしか利用できない場合(たとえば、組織で従来のトークンが無効になっている場合)は、代わりにOAuth 2.0 PKCE 認証を使用してください。ゲートウェイ経由で自動的にルーティングされます。

環境変数

サーバーには次の環境変数が必要です。

TEMPO_API_TOKEN           # Your Tempo API token
JIRA_API_TOKEN            # Your Jira API token (required for basic and bearer auth)
JIRA_EMAIL                # Your Jira account email (required for basic auth)
JIRA_BASE_URL             # Your Jira instance URL (e.g., https://your-org.atlassian.net)
JIRA_AUTH_TYPE            # Optional: 'basic' (default), 'bearer', or 'oauth'
JIRA_OAUTH_CLIENT_ID      # OAuth 2.0 client ID (required for oauth auth)
JIRA_OAUTH_CLIENT_SECRET  # OAuth 2.0 client secret (required for oauth auth)
JIRA_TEMPO_ACCOUNT_CUSTOM_FIELD_ID     # Optional: Custom field ID for Tempo accounts

環境に設定するか、MCP クライアントの設定で指定できます。

認証方式

サーバーは Jira API に対して、次の 3 つの認証方式をサポートしています。

Basic 認証(デフォルト)

メールアドレスと API トークンを使用する、従来の方式です。

{
  "env": {
    "JIRA_API_TOKEN": "your_api_token",
    "JIRA_EMAIL": "[email protected]",
    "JIRA_AUTH_TYPE": "basic"
  }
}
Bearer トークン認証(OAuth 2.0)

セキュリティを強化するために、OAuth 2.0 スコープ付きトークンを使用したい場合の方式です。

{
  "env": {
    "JIRA_API_TOKEN": "your_oauth_access_token",
    "JIRA_AUTH_TYPE": "bearer"
  }
}

注:bearer 認証では、トークンからユーザーが特定されるため、JIRA_EMAIL は不要です。

OAuth 2.0 PKCE 認証

Atlassian の組織によっては、管理者ポリシーで API トークンへのアクセスが制限され、Basic 認証と Bearer 認証が失敗する場合があります。oauth タイプは、OAuth 2.0 認可コードフローを PKCE で完全に実装しており、API トークンの制限にかかわらず動作します。トークンの有効期間は短く、自動的に更新されるため、手動で管理する必要はありません。

初回使用時にブラウザーウィンドウが開き、アクセスを認可できます。トークンは ~/.tempo-mcp-server/tokens.json にローカル保存され、自動的に更新されます。

  1. read:jira-user と read:jira-work のスコープ、およびコールバック URL として http://localhost:7788/callback を指定し、Atlassian Developer Consoleで OAuth 2.0 アプリを作成します。

  2. サーバーを設定します。

{
  "env": {
    "JIRA_BASE_URL": "https://your-org.atlassian.net",
    "JIRA_AUTH_TYPE": "oauth",
    "JIRA_OAUTH_CLIENT_ID": "your_client_id",
    "JIRA_OAUTH_CLIENT_SECRET": "your_client_secret"
  }
}

注:oauth 認証を使用する場合、JIRA_API_TOKEN と JIRA_EMAIL は不要です。

Tempo アカウントの設定

Tempo インスタンスで作業ログをアカウントに紐付ける必要がある場合は、アカウント情報を含むカスタムフィールドの ID を設定してください。

JIRA_TEMPO_ACCOUNT_CUSTOM_FIELD_ID=10234

カスタムフィールド ID の確認方法:

  1. Jira の[設定]→[課題]→[カスタムフィールド]に移動します
  2. Tempo アカウントのフィールドを探し、URL またはフィールドの設定から ID を確認します

他のユーザーの作業ログの表示

読み取りツール(retrieveWorklogs、getWorklogAnalytics、getMissingWorklogDays)は、デフォルトではトークン所有者自身の作業ログを対象としますが、オプションのフィルターを指定して他のユーザーを対象にできます。管理者、PM、チームリーダーに便利です。

  • users — メールアドレス、表示名、または Jira の accountId の配列(例:["[email protected]", "Maria Petrova"])
  • program — Tempo Program の名前または ID。該当するプログラムのチームに現在所属するメンバー全員に展開されます
  • team — Tempo Team の名前または ID。該当するチームの現在のメンバー全員に展開されます

フィルターの対象は結合されます。Tempo は権限をサーバー側で適用します。トークン所有者に表示権限がない作業ログは、API によってエラーを返さずに除外されます。他のユーザーを表示するには、次の権限が必要です。

  1. トークン所有者に View Worklogs が付与された Tempo の Permission Role(Tempo > Settings > Permission Roles)— 全員を対象にする場合は「Full」、選択したチームのみを対象にする場合は「Restricted」
  2. 該当するプロジェクトに対する Jira の Browse Projects 権限
  3. program / team フィルターを使う場合は、Tempo API トークンの Teams スコープ

getWorklogAnalytics では groupBy: "user" も使用できます。program と組み合わせると、1 回の呼び出しでユーザーごとの時間レポートを生成できます。フィルターを指定した getMissingWorklogDays は、時間が不足している日をユーザーごとにレポートします(他のユーザーのスケジュールを表示する場合も権限が必要です)。

利用可能なツール

retrieveWorklogs

設定されたユーザー(またはフィルターで指定した他のユーザー)の、開始日から終了日までの作業ログを取得します。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id
createWorklog

指定した Jira 課題に新しい作業ログを作成します。

Parameters:
- issueKey: String (e.g., "PROJECT-123")
- timeSpentHours: Number (positive)
- date: String (YYYY-MM-DD)
- description: String (optional)
- startTime: String (HH:MM format, optional)
bulkCreateWorklogs

1 回の操作で複数の作業ログを作成します。

Parameters:
- worklogEntries: Array of {
    issueKey: String
    timeSpentHours: Number
    date: String (YYYY-MM-DD)
    description: String (optional)
    startTime: String (HH:MM format, optional)
  }
editWorklog

既存の作業ログを編集します。

Parameters:
- worklogId: String
- timeSpentHours: Number (positive)
- description: String (optional)
- date: String (YYYY-MM-DD, optional)
- startTime: String (HH:MM format, optional)
deleteWorklog

既存の作業ログを削除します。

Parameters:
- worklogId: String
getMissingWorklogDays

ユーザーが想定より少ない時間しか記録していない、指定期間内の営業日をレポートします。1 日あたりの想定時間はユーザーの Tempo スケジュールに基づくため、祝日、非営業日、パートタイムのスケジュールは自動的に考慮されます。users / program / team を指定すると、他のユーザーを確認し、不足時間が多い順に並べたユーザーごとのレポートを返します。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- minHoursPerDay: Number (optional) — override the per-day threshold;
                                      non-working days are still skipped
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id

必須の Tempo スコープ: TEMPO_API_TOKEN には Worklogs に加えて Schemes スコープ(Workload Schemes、Holiday Schemes、User Schedule を対象)が必要です。Tempo では既存トークンのスコープを変更できません。現在のトークンに Worklogs しか含まれていない場合は、Tempo > Settings > API Integration で新しいトークンを作成してください。

getWorklogAnalytics

指定期間内の作業ログを集計し、グループごとの時間、作業ログ数、割合を、時間の降順で返します。groupBy: "user" を program / team / users と組み合わせると、ユーザーごとのレポートを生成できます。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- groupBy: "issue" | "account" | "user" | "day" | "week" | "month" (optional, default "issue")
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id

プロジェクト構成

tempo-mcp-server/
├── src/                  # Source code
│   ├── authors.ts        # Author filter resolution (users/program/team → accountIds)
│   ├── config.ts         # Configuration management
│   ├── index.ts          # MCP server implementation
│   ├── jira.ts           # Jira API integration
│   ├── oauth.ts          # OAuth 2.0 PKCE flow and token management
│   ├── tools.ts          # Tool implementations
│   ├── types.ts          # TypeScript types and schemas
│   └── utils.ts          # Utility functions
├── build/                # Compiled JavaScript (generated)
├── tsconfig.json         # TypeScript configuration
└── package.json          # Project metadata and scripts

トラブルシューティング

問題が発生した場合は、次の点を確認してください。

  1. すべての環境変数が正しく設定されていることを確認します
  2. Jira と Tempo の API トークンに適切な権限があることを確認します
  3. コンソール出力にエラーメッセージがないか確認します
  4. インスペクターを使って実行してみます:npm run inspect

ライセンス

MIT

クレジット

このサーバーは、Anthropic が作成した Model Context Protocol 仕様を実装しています。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。