mcpField
T
taiga-mcp-server

taiga-mcp-server

ローカル
github.com生産性01 日前に更新

taiga-mcp-server について

taiga-mcp-serverは、AIエージェントからTaigaのプロジェクト作業を読み取り、管理するためのサーバーです。プロジェクト内の名前でステータスやメンバー、スプリントを解決し、期間を指定した活動履歴も扱えます。

主な機能

  1. 01担当作業とプロジェクトデータの取得
  2. 02ユーザーストーリー、タスク、課題、エピックの作成・更新
  3. 03担当者、見積もり、コメント、スプリントの管理
  4. 04名前によるカタログ値の解決
  5. 05期間内のプロジェクト活動の集約

活用シーン

  1. 01チームメンバーの担当項目を確認
  2. 02作業項目のステータスを変更
  3. 03Taigaの作業項目を作成して割り当て
  4. 04プロジェクトで先週起きた変更を確認

MCP 対応

このリポジトリにはtaiga-api-mcp-serverが含まれ、Taigaのプロジェクトデータと管理操作をMCPクライアント向けのツールとして公開します。Taiga APIクライアントを使用し、アカウントの権限範囲で動作します。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"xhisusx-taiga": {
"command": "npx",
"args": [
"-y",
"taiga-api-mcp-server"
],
"env": {
"TAIGA_URL": "<TAIGA_URL>",
"TAIGA_USERNAME": "<TAIGA_USERNAME>",
"TAIGA_PASSWORD": "<TAIGA_PASSWORD>",
"TAIGA_APP_TOKEN": "<TAIGA_APP_TOKEN>",
"TAIGA_PROJECT": "<TAIGA_PROJECT>",
"TAIGA_MCP_READ_ONLY": "<TAIGA_MCP_READ_ONLY>",
"TAIGA_MCP_ALLOW_DELETE": "<TAIGA_MCP_ALLOW_DELETE>"
}
}
}
}
起動コマンドnpx -y taiga-api-mcp-server
設定が必要な環境変数
TAIGA_URLTaiga instance root, without /api/v1. Taiga Cloud: https://api.taiga.io
TAIGA_USERNAMETaiga username or email, used together with TAIGA_PASSWORD
TAIGA_PASSWORDシークレットPassword for TAIGA_USERNAME
TAIGA_APP_TOKENシークレットLong-lived Application token, instead of a username and password
TAIGA_PROJECTDefault project (id, slug or name) for tool calls that omit one
TAIGA_MCP_READ_ONLYSet to 1 to register the read tools only
TAIGA_MCP_ALLOW_DELETESet to 1 to also register taiga_delete_item

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

パッケージ
npmtaiga-api-mcp-server0.5.0

ツール

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

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

詳細

taiga-api-client

npm version npm downloads bundle size types license CI GitHub stars

🇬🇧 英語版 — 現在表示中 · 🇷🇺 ロシア語版

Taiga REST API 用の TypeScript クライアントです。実行時の依存関係はなく、ESM と CJS の両方に対応し、Node ≥18、Bun ≥1.0、およびグローバルな fetch が使えるあらゆる環境で動作します。

  • 🔐 トークンの自動更新と同時更新の重複排除に対応した Bearer 認証
  • 📦 完全な型付け:すべてのリソース、ペイロード、パラメーターの型を提供
  • 🚫 実行時の依存関係はゼロ
  • 🔄 ページネーション用の非同期イテレーター
  • ⚠️ 型付きエラー(TaigaApiError、TaigaAuthError、TaigaRateLimitError、TaigaNetworkError)
  • 🚀 .d.ts / .d.cts 型マップを含む ESM + CJS の両対応ビルド

インストール

npm install taiga-api-client
# or
bun add taiga-api-client
# or
pnpm add taiga-api-client

クイックスタート

import { TaigaClient } from "taiga-api-client";

// baseUrl is the only required option.
const client = new TaigaClient({ baseUrl: "https://api.taiga.io" });

// Log in (the `username` field accepts both username and email).
await client.auth.login({ username: "[email protected]", password: "secret" });

// Fetch projects you are a member of.
const me = await client.users.me();
const projects = await client.projects.list({ member: me.id });

// Create a user story.
const story = await client.userStories.create({
  project: projects[0].id,
  subject: "Add OAuth login",
  description: "Support GitHub OAuth in addition to password login",
});

// Iterate over every issue in the project (auto-pagination).
for await (const issue of client.issues.paginate({ project: projects[0].id })) {
  console.log(`#${issue.ref} ${issue.subject}`);
}

🤖 MCP サーバー:AI エージェント向け Taiga

このリポジトリには、taiga-api-mcp-server も含まれています。このクライアントを基盤とする Model Context Protocol サーバーです。MCP クライアント(Claude Code、Claude Desktop、Cursor など)を Taiga アカウントに接続すると、あなたに割り当てられた項目の確認、項目のステータス変更、ユーザーストーリー、タスク、課題、エピックの作成、メンバーの割り当て、見積もり、コメント、スプリントの計画を行えます。権限はあなた自身のものに限られ、それ以上の権限はありません。

ステータス、メンバー、スプリントは名前で指定します。サーバーがプロジェクト固有のカタログから該当する項目を解決するため、エージェントが数値 ID を推測する必要はありません。

さらに、taiga_activity を 1 回呼び出すだけで、**「先週は何をしましたか」**という質問にも答えます。このツールはプロジェクトのタイムラインをたどり、期間内に変更されたカードごとに、実際に起きたこと(ステータスの変更、クローズ(数日後に入力されたものを含む)、コメント、スプリント間の移動、添付ファイル)を返します。Taiga の一覧エンドポイントには日付フィルターがないため、期間を指定して作業内容を取得するにはこれが唯一の方法です。ストーリーが完了したかどうかは、そのタスク(tasks_done と tasks_total)から判断し、クローズされたかどうかはプロジェクト固有のステータスから判断します。日付とクローズフラグは手動で入力され、入力されていないこともよくあります。カードが 3 日後に Done へ移動した場合、それは先週の作業ではないため、どちらの判定も今日時点と期間終了時点の両方で回答します。

claude mcp add taiga   --env TAIGA_URL=https://api.taiga.io   --env [email protected]   --env TAIGA_PASSWORD=...   -- npx -y taiga-api-mcp-server

📖 セットアップ、ツールリファレンス、使用例:mcp/README.md

💡 カタログ ID を調べるには?filters_data を使いましょう

書き込み操作の多くでは、プロジェクト固有のカタログ値(ステータス、タイプ、重要度、優先度、担当者など)の数値 ID が必要です。カタログを個別に取得する必要はありません。すべてのリソースには filters_data メソッドがあり、プロジェクトの範囲に限定されたカタログ値をすべて1 回のリクエストで返します。

const data = await client.issues.filtersData({ project: 42 });
const inProgress = (data.statuses as Array<{ id: number; name: string }>)
  .find((s) => s.name === "In progress");

await client.issues.create({ project: 42, subject: "...", status: inProgress!.id });

📖 詳細ガイド:docs/filters-data.md — キャッシュ、リソースごとに利用できるエンドポイント、およびこの方法では不十分な場合について説明しています。

クライアントの作成

最小構成:

const client = new TaigaClient({ baseUrl: "https://api.taiga.io" });

baseUrl だけが必須のオプションです。それ以外はすべて省略できます。

完全な例:

const client = new TaigaClient({
  baseUrl: "https://api.taiga.io", // ← required

  // Authentication — pick one (or none, if you will call client.auth.login later):
  token: "...", // a previously obtained bearer token (session restore)
  refreshToken: "...", // its paired refresh token
  applicationToken: "...", // a static Application token, used instead of bearer

  // Behavior:
  autoRefresh: true, // auto-refresh the bearer token on 401 (default true)
  timeoutMs: 30000, // request timeout in ms (default 30000)
  userAgent: "my-app/1.0",
  acceptLanguage: "en",
  apiPrefix: "/api/v1", // change only for self-hosted with a non-default prefix
  fetch: customFetch, // dependency-injected fetch (proxies, mocks)

  // Token persistence hook:
  onTokenChange: async (tokens) => {
    if (tokens) await db.saveTokens(tokens);
    else await db.clearTokens();
  },
});
TaigaClientOptions
オプション必須?型デフォルト説明
baseUrl✅ はいstring—Taiga インスタンスのルート URL(/api/v1 を含めません)。Taiga Cloud の場合:https://api.taiga.io。
tokenいいえstring | nullnullベアラートークンです。既存のセッションを復元するには、これを渡します。
refreshTokenいいえstring | nullnull対応するリフレッシュトークンです。
applicationTokenいいえstring | nullnull静的なアプリケーショントークンです(ベアラーとは相互排他です)。
autoRefreshいいえbooleantrue401 時にベアラートークンを自動的に更新します。
timeoutMsいいえnumber30000リクエストごとのタイムアウト(ミリ秒)です。
userAgentいいえstring—User-Agent ヘッダーです。
acceptLanguageいいえstring—Accept-Language ヘッダーです(レスポンス文字列の i18n)。
apiPrefixいいえstring/api/v1API パスのプレフィックスです。標準以外のセルフホスト環境の場合のみ変更してください。
fetchいいえtypeof fetchglobalカスタムの fetch 実装です(プロキシ、モック、MSW)。
onTokenChangeいいえ(tokens | null) => void | Promise—login の後、および自動更新の成功後に呼び出されるコールバックです。トークンの永続化に使用します。

認証

次の 3 つのモードがサポートされています。

モード使用する場面ヘッダー
ベアラー+リフレッシュ標準的な対話型ログインAuthorization: Bearer X
セッションの復元プロセスの再起動時 — 保存済みトークンをコンストラクターに渡しますAuthorization: Bearer X
アプリケーショントークンインテグレーション/ボット、長期間有効な静的トークンAuthorization: Application X
トークンの自動更新

autoRefresh: true(デフォルト)の場合、クライアントは 401 レスポンスを透過的にインターセプトし、POST /auth/refresh を呼び出して、元のリクエストを 1 回だけ再試行します。同時に発生した 401 は重複排除されます。10 件のリクエストが同時に失敗しても、/auth/refresh は 1 回だけ呼び出されます。リフレッシュ自体が失敗すると、トークンがクリアされ、TaigaAuthError がスローされます。

プロセスの再起動をまたいだトークンの永続化
const client = new TaigaClient({
  baseUrl: "https://api.taiga.io",
  token: await db.loadToken(),
  refreshToken: await db.loadRefreshToken(),
  onTokenChange: async (tokens) => {
    if (tokens) await db.saveTokens(tokens);
    else await db.clearTokens();
  },
});

onTokenChange は次のタイミングで呼び出されます。

  • client.auth.login(...) の後 — 新しいトークンペアが渡されます。
  • 自動更新の成功後 — 新しいペアが渡されます。
  • client.auth.logout() の後 — null が渡されます。

返された Promise はリクエストの再試行前に待機されるため、次のリクエストが送信される前にトークンの永続化が確実に完了します。

リソースとメソッド

すべてのリソースは BaseResource を継承し、標準的な CRUD を提供します。各リソースはさらに独自のメソッドを追加します。

BaseResource<T> — 共通の CRUD
メソッドHTTP戻り値説明
list(params?)GET /resourceT[]最初のページ(または disablePagination が有効な場合はレスポンス全体)。
paginate(params?)GET /resource?page=NAsyncIterable<T>x-pagination-next リンクをたどる遅延評価の非同期イテレーター。
listPage(params?, page?)GET /resource?page=N{ data, pagination }指定したページとページネーションのメタデータ。
get(id)GET /resource/:idTID で指定した単一のリソース。
create(payload)POST /resourceT作成します。
update(id, payload)PUT /resource/:idT全体を置き換えます。必須フィールドをすべて指定する必要があります。
patch(id, payload, version?)PATCH /resource/:idT部分更新します。version を指定すると、楽観的同時実行制御が有効になります。
delete(id)DELETE /resource/:idvoid削除します。
client.auth — 認証
メソッド戻り値説明
login({ username, password })Promise<AuthResponse>POST /auth。username にはユーザー名とメールアドレスの両方を指定できます。
refresh()Promise<string>手動で更新します。通常は 401 の発生時に自動的に呼び出されます。
logout()Promise<void>トークンをローカルで消去し、onTokenChange(null) を呼び出します。
setTokens(tokens | null)Promise<void>トークンを手動で設定します(例:データベースから復元した後)。
getTokens()AuthTokens | nullメモリ上にある現在のトークン。
getCurrentUser()AuthUser | null最後に成功した login() で取得したユーザープロフィール。
onTokenChange(handler)void実行時に永続化コールバックを置き換えます。
const auth = await client.auth.login({ username: "u", password: "p" });
console.log(auth.auth_token, auth.refresh, auth.full_name);
client.users — ユーザー

基本 CRUD に加えて、次の機能があります。

メソッドHTTP説明
me()GET /users/me現在認証されているユーザー。
updateMe(payload)PUT /users/:id (own id)update(me.id, …) を簡単に呼び出すためのメソッド。
changePassword(currentPassword, newPassword)POST /users/change_passwordパスワードを変更します。
stats(id)GET /users/:id/statsユーザーの統計情報。

⚠️ users.create() は意図的に例外をスローします。登録には専用のエンドポイントを使用します(v0.1 の対象外)。

const me = await client.users.me();
await client.users.updateMe({ bio: "TypeScript fan", lang: "en" });
await client.users.changePassword("oldPwd!", "newPwd!");
client.projects — プロジェクト

基本的なCRUDに加えて:

メソッドHTTP説明
getBySlug(slug)GET /projects/by_slug?slug=...idの代わりにスラッグでプロジェクトを取得します。
stats(id)GET /projects/:id/statsプロジェクトの統計情報(ポイント、マイルストーン)。
modulesConfig(id)GET /projects/:id/modulesインテグレーション設定(GitHub、GitLab、Bitbucket、Gogs)。
setModulesConfig(id, config)PATCH /projects/:id/modulesインテグレーション設定を更新します。
const proj = await client.projects.create({ name: "Demo", description: "" });
const sameProj = await client.projects.getBySlug(proj.slug);
const updated = await client.projects.patch(proj.id, { description: "Updated" }, /* version */ 1);
const stats = await client.projects.stats(proj.id);
await client.projects.delete(proj.id);
client.memberships — プロジェクトのメンバーシップ

基本的なCRUDに加えて:

メソッドHTTP説明
bulkCreate(payload)POST /memberships/bulk_create1回の呼び出しで複数のユーザーを招待します。
resendInvitation(id)POST /memberships/:id/resend_invitation招待メールを再送します。
await client.memberships.bulkCreate({
  project_id: proj.id,
  bulk_memberships: [
    { role_id: 1, username: "[email protected]" },
    { role_id: 2, username: "[email protected]" },
  ],
  invitation_extra_text: "Welcome to the team",
});
client.userStories — ユーザーストーリー

基本的なCRUDに加えて:

メソッドHTTP説明
bulkCreate(payload)POST /userstories/bulk_create改行区切りの文字列から複数のストーリーを作成します。
bulkUpdateBacklogOrder(payload)POST /userstories/bulk_update_backlog_orderバックログ内のストーリーの順序を変更します。
bulkUpdateKanbanOrder(payload)POST /userstories/bulk_update_kanban_orderカンバンボード上のストーリーの順序を変更します。
bulkUpdateSprintOrder(payload)POST /userstories/bulk_update_sprint_orderスプリント内のストーリーの順序を変更します。
filtersData({ project })GET /userstories/filters_data?project=...UIで利用可能なフィルター:ステータス、タグ、担当者。
const story = await client.userStories.create({
  project: proj.id,
  subject: "User can log in via GitHub",
  description: "OAuth flow",
});

// Bulk create from a multi-line string (the way the Taiga UI does it):
await client.userStories.bulkCreate({
  project_id: proj.id,
  bulk_stories: "Story 1\nStory 2\nStory 3",
});

// Iterate over every story in the project:
for await (const s of client.userStories.paginate({ project: proj.id })) {
  console.log(s.subject);
}
client.tasks — タスク

基本的なCRUDに加えて:

メソッドHTTP説明
bulkCreate(payload)POST /tasks/bulk_create複数のタスクを一度に作成します。
filtersData({ project })GET /tasks/filters_data?project=...利用可能なフィルター。
const task = await client.tasks.create({
  project: proj.id,
  subject: "Implement OAuth callback",
  user_story: story.id, // link to a user story
});
client.issues — 課題

基本的な CRUD に加えて:

メソッドHTTP説明
filtersData({ project })GET /issues/filters_data?project=...利用可能なフィルター(タイプ、重大度、優先度)。
voters(id)GET /issues/:id/voters課題に賛成票を投じたユーザー。
upvote(id)POST /issues/:id/upvote課題に賛成票を投じます。
downvote(id)POST /issues/:id/downvote自分の賛成票を取り消します。
watchers(id)GET /issues/:id/watchers課題をウォッチしているユーザー。
watch(id)POST /issues/:id/watch通知を購読します。
unwatch(id)POST /issues/:id/unwatch購読を解除します。
const issue = await client.issues.create({
  project: proj.id,
  subject: "Login button doesn't work in Safari",
  description: "Reproduces on macOS Safari 17.x",
});
await client.issues.upvote(issue.id);
await client.issues.watch(issue.id);
client.epics — エピック

基本的な CRUD に加えて:

メソッドHTTP説明
bulkCreate(payload)POST /epics/bulk_create改行区切りの文字列から複数のエピックを作成します。
filtersData({ project })GET /epics/filters_data?project=...UI で利用可能なフィルター。
relatedUserStories(id)GET /epics/:id/related_userstoriesエピックに関連付けられたユーザーストーリー。
addRelatedUserStory(id, { user_story })POST /epics/:id/related_userstories既存のユーザーストーリーをエピックに関連付けます。
removeRelatedUserStory(id, usId)DELETE /epics/:id/related_userstories/:usIdユーザーストーリーとエピックの関連付けを解除します。
voters(id)GET /epics/:id/votersエピックに賛成票を投じたユーザー。
upvote(id)POST /epics/:id/upvoteエピックに賛成票を投じます。
downvote(id)POST /epics/:id/downvote自分の賛成票を取り消します。
watchers(id)GET /epics/:id/watchersエピックをウォッチしているユーザー。
watch(id)POST /epics/:id/watch通知を購読します。
unwatch(id)POST /epics/:id/unwatch購読を解除します。
const epic = await client.epics.create({
  project: proj.id,
  subject: "Q1 roadmap",
  color: "#ff8800",
});
await client.epics.addRelatedUserStory(epic.id, { user_story: story.id });
for (const link of await client.epics.relatedUserStories(epic.id)) {
  console.log(link.user_story);
}

ℹ️ これらのエンドポイントを使用するには、プロジェクトでエピックを有効にする必要があります(is_epics_activated: true)。

client.milestones — スプリント

基本的な CRUD に加えて:

メソッドHTTP説明
stats(id)GET /milestones/:id/statsバーンダウンデータとポイント単位の完了進捗。
const sprint = await client.milestones.create({
  project: proj.id,
  name: "Sprint 1",
  estimated_start: "2026-01-01",
  estimated_finish: "2026-01-14",
});
const burndown = await client.milestones.stats(sprint.id);

ページネーション

list() は常にレスポンスの最初のページを返します。全データを取得するには、次の 3 つの方法があります。

// 1. Async iterator (recommended): lazy, walks the next links.
for await (const story of client.userStories.paginate({ project: 42 })) {
  await processStory(story);
}

// 2. A specific page plus metadata.
const page = await client.userStories.listPage({ project: 42 }, 3);
console.log(page.data, page.pagination); // { count, perPage, current, next, prev }

// 3. Disable pagination entirely (returns the full set as one array).
const all = await client.http.get("/userstories", {
  query: { project: 42 },
  disablePagination: true,
});

⚠️ disablePagination は x-disable-pagination: True ヘッダーを送信します。小規模なコレクションでのみ使用してください。大規模なコレクションの場合、Taiga がエラーを返すか、タイムアウトする可能性があります。

エラー

すべてのエラーは抽象クラス TaigaError を継承します。

クラス発生する状況役立つフィールド
TaigaApiError4xx/5xx の失敗status、code、detail、body
TaigaAuthError401 / 403TaigaApiError のすべてのフィールドに加えて
TaigaRateLimitError429retryAfter(Retry-After から解析された秒数)
TaigaNetworkErrorネットワーク障害、中断、タイムアウトcause(基となる fetch / AbortError)
import {
  TaigaApiError,
  TaigaAuthError,
  TaigaRateLimitError,
  TaigaNetworkError,
} from "taiga-api-client";

try {
  await client.projects.get(99999);
} catch (err) {
  if (err instanceof TaigaRateLimitError) {
    await sleep((err.retryAfter ?? 1) * 1000);
  } else if (err instanceof TaigaAuthError) {
    // Session is dead — log in again
  } else if (err instanceof TaigaApiError) {
    console.error(`Taiga ${err.status}: ${err.detail ?? err.message}`);
  } else if (err instanceof TaigaNetworkError) {
    // Network / timeout
  }
}

楽観的同時実行制御(OCC)

Taiga は version フィールドを使って、複数ユーザーによる同時更新で変更が失われるのを防ぎます。patch() を呼び出す際は、オブジェクトとともに受け取ったバージョンを渡してください。先に誰かが更新していた場合、Taiga は 400 / 412 を返し、競合が発生したことがわかります。

const story = await client.userStories.get(42);
const updated = await client.userStories.patch(
  story.id,
  { subject: "Renamed" },
  story.version, // ← OCC
);

低レベルアクセス

まだリソースとしてラップされていないエンドポイントには、client.http を直接使用してください。

const result = await client.http.get<{ id: number }[]>("/wiki", {
  query: { project: 1 },
});
console.log(result.data, result.pagination, result.headers);

利用可能なメソッドは get、post、put、patch、delete です。すべて同じ RequestOptions を受け取ります:{ query, body, headers, signal, disablePagination, skipAuth }。

対応範囲

実装済み:

  • 認証:ログイン、更新、ログアウト、アプリケーショントークン、セッション復元、重複排除による自動更新
  • ユーザー:プロフィール、一覧、更新、パスワード変更、統計
  • プロジェクト:CRUD、by_slug、統計、モジュール設定
  • メンバーシップ:CRUD、bulk_create、招待の再送信
  • ユーザーストーリー:CRUD、bulk_create、すべてのボードでの bulk_update_order、filters_data
  • タスク:CRUD、bulk_create、filters_data
  • イシュー:CRUD、filters_data、投票者、ウォッチャー、賛成票/反対票、ウォッチ/ウォッチ解除
  • マイルストーン:CRUD、統計
  • エピック (v0.2 で新規追加):CRUD、bulk_create、filters_data、関連するユーザーストーリー(一覧/追加/削除)、投票者、ウォッチャー、賛成票/反対票、ウォッチ/ウォッチ解除

未実装(今後のリリースで対応予定): wiki、webhooks、添付ファイル、カスタム属性、履歴/コメント、インポーター(Trello/Jira/GitHub)、プロジェクトテンプレート、GitHub OAuth フロー。

必要なエンドポイントが対応範囲に含まれていない場合は、client.http にフォールバックするか、イシューを作成してください。

互換性

ランタイム最小バージョン備考
Node.js18グローバルの fetch は Node 18 で導入されました。
Bun1.0完全にサポートされています。
Deno1.x動作するはずです(グローバルの fetch を利用できます)。
ブラウザー最新のモダンブラウザーTaiga 側で CORS の設定が必要です。

ライセンス

MIT

コメント

MCP は初めてですか?

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

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