Python toolkit that lets your LangChain agents automate Taiga: create, search, edit & comment on user stories, tasks and issues via the official REST API. v2 introduces the multi-tenant remote MCP mode (HTTP+OAuth) alongside the existing stdio transport. v2.5+ adds OAuth refresh-token rotation, attachment read/write tools (list/get/inline-base64 upload), and dropdown-choice discovery on list_custom_attributes_tool.
Project description
langchain-taiga
Taiga integration for LangChain and the Model Context Protocol.
The package ships three things in one install:
- 21 LangChain tools for Taiga (entities, wiki, custom attributes, members, sprint planning).
- A
TaigaToolkitthat bundles them for one-line LangChain agent setup. - An MCP server in two flavours:
- Stdio mode — single-user, local credentials in env vars. For Claude Desktop, Claude Code, VSCode local.
- Remote mode — multi-tenant HTTP server with OAuth 2.1 + PKCE + Dynamic Client Registration. For claude.ai Custom Connectors, VSCode Web, Claude Desktop with HTTP transport, etc. Each user signs in with their own Taiga credentials; the server stores no static API key.
The 21 tools:
create_entity_tool: Creates user stories, tasks and issues in Taiga.search_entities_tool: Searches for user stories, tasks and issues in Taiga. Returns{matches, count, max_results, truncated}. Supportsmax_resultsandinclude_custom_attributes(defaultFalse— opt-in to avoid an N+1 fetch storm). Date filters are tz-aware.get_entity_by_ref_tool: Gets a user story, task or issue by reference. For user stories, the response also includes apointsfield ({role_name: value}shape, symmetric toset_userstory_points_tool's input) so a read + write round-trip stays in the same vocabulary.update_entity_by_ref_tool: Updates a user story, task or issue by reference.add_comment_by_ref_tool: Adds a comment to a user story, task or issue.add_attachment_by_ref_tool: Adds an attachment to a user story, task or issue by downloading a public URL (the server fetches it viarequests.get).add_attachment_inline_by_ref_tool: Uploads a local file as an attachment by inlining its bytes as base64. Symmetric toget_attachment_by_ref_tool. Use when the file lives on the calling client (Claude Code, claude.ai) and shouldn't be exposed via a public URL. Refuses payloads whose decoded size exceedsTAIGA_MAX_INLINE_ATTACHMENT_BYTES(default 10 MB).list_attachments_by_ref_tool: List all attachments on an entity with fresh signed download URLs. URL tokens from the Taiga UI/webhook diff expire after ~6 min; this tool re-mints them on every call.get_attachment_by_ref_tool: Fetch a specific attachment by ID and return its content base64-encoded inline. Refuses files larger thanTAIGA_MAX_INLINE_ATTACHMENT_BYTES(default 10 MB) — for larger files uselist_attachments_by_ref_toolandcurlthedownload_urlout-of-band.promote_issue_to_userstory_tool: Promotes an issue to a user story, preserving comments and history.list_custom_attributes_tool: Lists custom-attribute definitions for a project + entity type, including dropdownchoices(parsed) and the rawextrafield — so an agent can discover the valid options for a dropdown attribute before writing viaset_custom_attributes_tool.set_custom_attributes_tool: Sets custom-attribute values on a user story, task or issue.get_custom_attributes_tool: Reads custom-attribute values from a user story, task or issue.sort_kanban_by_rice_tool: Re-orders Kanban swimlanes using a RICE-style score. Closed status columns (Done, Cancelled, …) are skipped — re-ranking already-completed work has no value. Each entry incolumns_updatedcarriesstatus_namealongsidestatus_idso consumers don't need to round-trip through Taiga to translate the id.set_userstory_points_tool: Sets Taiga story points on a user story for one or more roles (Developer, UX, Design, …). Resolves role names + point values to internal IDs at runtime so it adapts to per-project scales. The only programmatic path to set the field thatsort_kanban_by_rice_toolreads as effort. The target role must be configured as computable in the project (Taiga admin → Members → Roles → "Compute story points for this role"); non-computable roles are rejected upfront with a 400 +non_computable_rolesdiagnostic, instead of letting Taiga's PATCH endpoint return its crypticInvalid role idserver-side rejection (which would otherwise surface as a generic 500 via this tool's exception wrapper).list_wiki_pages_tool: Lists wiki pages in a project.get_wiki_page_tool: Reads a wiki page by slug.create_wiki_page_tool: Creates a wiki page.update_wiki_page_tool: Updates a wiki page.whoami_tool: Returns the currently authenticated Taiga user.list_project_members_tool: Lists all members of a project with their roles (email opt-in).
Installation
pip install -U langchain-taiga
Environment Variables
For direct LangChain tool use, the toolkit, and stdio MCP mode (single-user, local credentials):
export TAIGA_URL="https://taiga.xyz.org/"
export TAIGA_API_URL="https://taiga.xyz.org/"
export TAIGA_USERNAME="username"
export TAIGA_PASSWORD="pw"
export OPENAI_API_KEY="..." # used by some tools' LLM-powered helpers
If TAIGA_USERNAME / TAIGA_PASSWORD are not set, the tools raise ValueError on call.
Remote MCP mode is different — see the Remote Mode section. There, end-users supply their own Taiga credentials interactively at the <mcp-path>/oauth/login form (e.g. https://your-server/mcp/oauth/login); only TAIGA_API_URL, TAIGA_URL, TAIGA_MCP_BASE_URL, and OPENAI_API_KEY are server-side env.
Usage
Direct Tool Usage
Each tool is a @tool-decorated function callable via .invoke({...}). A few representative examples:
from langchain_taiga.tools.taiga_tools import (
create_entity_tool,
search_entities_tool,
whoami_tool,
)
# Create — write
create_entity_tool.invoke({
"project_slug": "shikenso-development",
"entity_type": "us",
"subject": "Add /metrics endpoint",
"status": "New",
"description": "Prometheus-scrape-friendly text format.",
"tags": ["backend", "observability"],
})
# Search — natural-language query, server-side caps + truncation flag in response
search_entities_tool.invoke({
"project_slug": "shikenso-development",
"query": "open issues created after 2026-03-01",
"entity_type": "issue",
"max_results": 50,
})
# Whoami — verify auth wiring end-to-end
whoami_tool.invoke({})
For the full set of 21 tools see the list at the top of this README, the docstrings in taiga_tools.py, or just grab them all via the toolkit below.
Using the Toolkit
You can also use TaigaToolkit to automatically gather both tools:
from langchain_taiga.toolkits import TaigaToolkit
toolkit = TaigaToolkit()
tools = toolkit.get_tools()
MCP Server
The package ships an MCP server powered by fastmcp. All 21 tools above are exposed as MCP tools without changing their behaviour. There are two transport modes with different auth models:
| Mode | Transport | Auth | Use case |
|---|---|---|---|
| Stdio | stdin/stdout | env-var credentials | One developer running locally — Claude Desktop, Claude Code, VSCode local |
| Remote | HTTP (streamable) | OAuth 2.1 + PKCE + DCR | Multi-tenant — claude.ai Custom Connectors, VSCode Web, hosted teams |
Stdio Mode (single-user, local)
Run the server:
python -m langchain_taiga.mcp_server
Or without installing into your project (using uv):
uv run --with langchain-taiga python -m langchain_taiga.mcp_server
The Taiga credentials come from the TAIGA_USERNAME / TAIGA_PASSWORD env vars set in the wrapping process. All requests use the same single user.
VSCode
Add the following to your .vscode/mcp.json (or via the VSCode MCP settings UI):
{
"servers": {
"taiga": {
"command": "uv",
"args": [
"run",
"--with",
"langchain-taiga",
"python",
"-m",
"langchain_taiga.mcp_server"
],
"env": {
"TAIGA_API_URL": "${input:taiga_api_url}",
"TAIGA_URL": "${input:taiga_url}",
"TAIGA_USERNAME": "${input:taiga_username}",
"TAIGA_PASSWORD": "${input:taiga_password}"
}
}
},
"inputs": [
{
"id": "taiga_api_url",
"type": "promptString",
"description": "Taiga API URL (e.g. https://api.taiga.io)",
"password": false
},
{
"id": "taiga_url",
"type": "promptString",
"description": "Taiga Web URL (e.g. https://tree.taiga.io)",
"password": false
},
{
"id": "taiga_username",
"type": "promptString",
"description": "Taiga Username",
"password": false
},
{
"id": "taiga_password",
"type": "promptString",
"description": "Taiga Password",
"password": true
}
]
}
Claude Code
Add the Taiga MCP server via the CLI:
claude mcp add taiga -- uv run --with langchain-taiga python -m langchain_taiga.mcp_server
This adds the server to your project's .claude/mcp.json. Make sure the Taiga environment variables are set in your shell, or pass them explicitly:
claude mcp add taiga -e TAIGA_API_URL=https://api.taiga.io -e TAIGA_URL=https://tree.taiga.io -e TAIGA_USERNAME=your_user -e TAIGA_PASSWORD=your_pass -- uv run --with langchain-taiga python -m langchain_taiga.mcp_server
Alternatively, add the entry manually to .claude/mcp.json:
{
"mcpServers": {
"taiga": {
"command": "uv",
"args": [
"run",
"--with",
"langchain-taiga",
"python",
"-m",
"langchain_taiga.mcp_server"
],
"env": {
"TAIGA_API_URL": "https://api.taiga.io",
"TAIGA_URL": "https://tree.taiga.io",
"TAIGA_USERNAME": "your_user",
"TAIGA_PASSWORD": "your_pass"
}
}
}
}
Claude Desktop / GitHub Copilot Chat
Add a similar entry to your MCP configuration, pointing to
uv run --with langchain-taiga python -m langchain_taiga.mcp_server.
Remote Mode (multi-tenant, OAuth)
Run the server as a long-lived HTTP service:
TAIGA_API_URL=https://taiga.example.org \
TAIGA_URL=https://taiga.example.org \
TAIGA_MCP_BASE_URL=https://mcp.example.org/mcp \
OPENAI_API_KEY=sk-... \
langchain-taiga-mcp-remote
The server speaks MCP over the streamable-HTTP transport at the URL given by TAIGA_MCP_BASE_URL and implements:
- OAuth 2.1 + PKCE (S256) —
/authorize,/token - OAuth 2.1 refresh-token rotation with reuse-detection (2.5.0+) — connected MCP clients (claude.ai, VSCode, Claude Desktop) stay authenticated across hours without forcing the user back through the OAuth flow. Each refresh rotates the token; a replayed refresh token revokes the entire token family per OAuth 2.1 best practice for public clients.
- RFC 7591 Dynamic Client Registration —
/register - RFC 8414 / RFC 9728 discovery docs —
/.well-known/oauth-authorization-server[/<mcp-path>]and/.well-known/oauth-protected-resource[/<mcp-path>] - A login form at
<mcp-path>/oauth/loginwhere each user signs in with their own Taiga credentials. The Taiga JWT is then carried per-request via the MCPAccessTokenclaims and used by every tool call — so two users connected to the same server see only their own projects.
OAuth state lives in-process (per-pod in-memory dict). For production, run a single replica; users re-authorize after a Helm deploy or pod restart (refresh tokens are wiped along with everything else).
Connecting clients to a remote server
| Client | How to connect |
|---|---|
| claude.ai | Settings → Connectors → Add custom connector → URL https://your-server/mcp → sign in with Taiga creds. Anthropic docs. |
| VSCode (stable + Insiders + Web) | MCP UI → "Add server" → HTTP → https://your-server/mcp. DCR runs automatically; the redirect URIs (vscode.dev/redirect, insiders.vscode.dev/redirect, 127.0.0.1:<port>) are pre-allowed by the server's allowlist. |
| Claude Desktop | MCP config: "transport": {"type": "http", "url": "https://your-server/mcp"} |
| MCP Inspector | npx @modelcontextprotocol/inspector → URL https://your-server/mcp → "Quick OAuth Flow" |
Production deployment
For Shikenso's deployment to OVH MKS, see the taiga repo's deployment/helm/taiga-mcp chart and Jenkinsfile. Bump the chart's TAIGA_MCP_VERSION parameter after each langchain-taiga release.
Tests
The CI-aligned command (matches make test in CI):
make test
# expands to:
poetry run pytest --disable-socket --allow-unix-socket tests/unit_tests/
The --disable-socket flag blocks real network calls — the unit tests rely on it being on. Running pytest without it can hide tests that accidentally talk to live services.
For Shikenso's conda env (alternative local setup): source ~/miniconda3/etc/profile.d/conda.sh && conda activate langchain_taiga && python -m pytest --disable-socket --allow-unix-socket tests/unit_tests/.
License
Further Documentation
AGENTS.mdin this repo — onboarding for AI coding assistants and humans (test command, CI flow, MCP-SDK gotchas, architecture pointers).- Tool docstrings in
langchain_taiga/tools/taiga_tools.py. TaigaToolkit.- Remote OAuth bridge entry point:
langchain_taiga/remote_server.py. - Official Taiga Developer Docs: https://docs.taiga.io/api.html.
- LangChain GitHub for general LangChain usage.
- Model Context Protocol spec.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_taiga-2.8.0.tar.gz.
File metadata
- Download URL: langchain_taiga-2.8.0.tar.gz
- Upload date:
- Size: 74.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
995aae1635913a5fefbd62053d1357a75bb9920285299a9bc041a280f38237f8
|
|
| MD5 |
b0139024909b5759cef66face320f5c3
|
|
| BLAKE2b-256 |
4cf22bc008780384c699747e395e04806ebb50a5b480438cd1b6365526e0c849
|
Provenance
The following attestation bundles were made for langchain_taiga-2.8.0.tar.gz:
Publisher:
ci_publish.yml on Shikenso-Analytics/langchain-taiga
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_taiga-2.8.0.tar.gz -
Subject digest:
995aae1635913a5fefbd62053d1357a75bb9920285299a9bc041a280f38237f8 - Sigstore transparency entry: 1607249390
- Sigstore integration time:
-
Permalink:
Shikenso-Analytics/langchain-taiga@882a4c400920f662c6a11673a4b006b13478dd2a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Shikenso-Analytics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci_publish.yml@882a4c400920f662c6a11673a4b006b13478dd2a -
Trigger Event:
push
-
Statement type:
File details
Details for the file langchain_taiga-2.8.0-py3-none-any.whl.
File metadata
- Download URL: langchain_taiga-2.8.0-py3-none-any.whl
- Upload date:
- Size: 75.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
562ad922fc49dd059e8f854761a09f94f4d5ef6935529bfd30adccb5dbbc775a
|
|
| MD5 |
f9b96f7fbcea0506cc984b0f67b5a7c3
|
|
| BLAKE2b-256 |
448337a1b586307dd078956670c2c3903247f460628ae8aa013f6313293db9d4
|
Provenance
The following attestation bundles were made for langchain_taiga-2.8.0-py3-none-any.whl:
Publisher:
ci_publish.yml on Shikenso-Analytics/langchain-taiga
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_taiga-2.8.0-py3-none-any.whl -
Subject digest:
562ad922fc49dd059e8f854761a09f94f4d5ef6935529bfd30adccb5dbbc775a - Sigstore transparency entry: 1607249481
- Sigstore integration time:
-
Permalink:
Shikenso-Analytics/langchain-taiga@882a4c400920f662c6a11673a4b006b13478dd2a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Shikenso-Analytics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci_publish.yml@882a4c400920f662c6a11673a4b006b13478dd2a -
Trigger Event:
push
-
Statement type: