Taiga MCP Server
Taiga MCP Server
Model Context Protocol (MCP) server for Taiga project management, written in TypeScript and built on the Model Context Protocol SDK over stdio transport (with an optional streamable HTTP transport for remote and web-based clients). It connects LLM clients to Taiga instances to inspect and manage projects, work items (issues, user stories, tasks, epics), sprints, comments, attachments, and wiki pages.
The server consolidates all capabilities into 6 op-dispatching tools designed for minimal token overhead and dense, human- and LLM-readable text responses.
Contents
Features · Requirements · Quick Start · Local checkout · HTTP transport & web clients · Docker
Install: Claude Code · Claude Desktop · VS Code / Copilot · Cursor · Windsurf · Cline / Roo / Kilo · Continue.dev · Zed · JetBrains · Gemini CLI · Codex CLI · opencode · Amp · Pi · Oh My Pi
Tools: Conventions · Why six tools · Tool reference:
projects·work·sprints·comments·attachments·wikiOperations: Reliability · Security · FAQ · Troubleshooting · Development · Contributing · Changelog · License
Features
Six tools, twenty-eight operation pairs across projects, work items, sprints, comments, attachments, and wiki pages — the entire
tools/listpayload is ~10,493 characters (~2,800 tokens).Human-friendly identifiers everywhere: projects by ID or slug, work items by database ID or
#reference, members by ID, username, full name, or"me"; statuses, priorities, severities, issue types, and sprint names resolve server-side.Dense text output: one line per record in listings, clean key-value detail views; empty collections are reported as data, not errors.
Batch creation of up to 20 work items in a single call; deletions are deliberately single-target.
Reliability rails: rate-limit retries honoring
Retry-After, 30-second HTTP timeouts, a 60-second metadata cache, and no automatic 5xx retries (mutating requests may have landed).Attachment safety: hostname-pinned downloads, 10 MB cap, overwrite protection, and no bearer token sent to media hosts.
Dual transport: stdio by default; streamable HTTP on loopback when
TAIGA_HTTP_PORTis set.
Requirements and Configuration
Node.js >= 20.11
A Taiga account on taiga.io or a self-hosted Taiga instance
Three environment variables configured:
Variable | Description | Default |
| Base URL of the Taiga REST API (must include |
|
| Taiga username or email | Required |
| Taiga account password | Required |
Optional transport variables:
Variable | Description | Default |
| When set, serve MCP over streamable HTTP instead of stdio | (unset: stdio) |
| Bind host for the HTTP transport |
|
Quick Start
The fastest setup is Claude Desktop with npx (no checkout required):
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}All harness configurations below follow this shape; only the file location and wrapper syntax differ.
Credentials and
.env: a local checkout automatically loads.envfrom the repository root (see.env.example). An npx install does not: dotenv resolves relative to the package's install location inside the npm cache, so credentials passed via npx MUST be set in each harness'senvblock as shown above.
Running From a Local Checkout
git clone https://github.com/negoro26/mcp-taiga.git
cd mcp-taiga && npm ci && npm run build
cp .env.example .env # fill in TAIGA_USERNAME / TAIGA_PASSWORDThen point any harness at the compiled entrypoint instead of npx:
{
"mcpServers": {
"taiga": {
"command": "node",
"args": ["/absolute/path/to/mcp-taiga/dist/src/index.js"]
}
}
}No env block needed here — the server loads your repo-root .env itself. This repository also ships a ready-made .mcp.json so coding agents opened inside the checkout can use the local build directly.
Installation and Configuration
Per-harness setup using the published npm package. Each snippet passes credentials inline; substitute your own values.
Claude Code
Project scope (checked into the repo, shared with your team):
// .mcp.json at repository root
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Or add from the CLI (user scope with -s user, local scope by default):
claude mcp add taiga \
-e TAIGA_USERNAME=your_username \
-e TAIGA_PASSWORD=your_password \
-- npx -y mcp-taigaVerify with claude mcp list or /mcp inside a session.
Claude Desktop
Edit the config file — claude_desktop_config.json via Claude Desktop → Settings → Developer → Edit Config, located at %APPDATA%\Claude\claude_desktop_config.json on Windows or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS — and restart the desktop app:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}On Windows, invoke npx through cmd /c if the direct form fails: "command": "cmd", "args": ["/c", "npx", "-y", "mcp-taiga"].
VS Code and GitHub Copilot
VS Code supports MCP servers natively (1.99+); Copilot Chat picks them up automatically.
// .vscode/mcp.json (workspace) or use Command Palette: "MCP: Add Server"
{
"servers": {
"taiga": {
"type": "stdio",
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Start it from the Extensions view (mcp.json shows a Start button) or run MCP: List Servers in the Command Palette. Inputs can reference secrets with the "inputs" field instead of hardcoding passwords.
Cursor
Via CLI (mirrors the Claude Code interface):
cursor mcp add taiga -e TAIGA_USERNAME=your_username -e TAIGA_PASSWORD=your_password -- npx -y mcp-taigaOr edit ~/.cursor/mcp.json (global):
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Enable the server under Cursor Settings → MCP & Integrations if it does not activate immediately.
Windsurf
Edit ~/.codeium/windsurf/mcp_config.json (or Windsurf Settings → Cascade → MCP Servers → Manage MCPs → View Raw Config) and refresh the MCP panel afterwards:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Cline, Roo Code, and Kilo Code
All three VS Code extensions read an equivalent JSON settings file, editable through each extension's MCP Servers panel (the pencil icon opens the raw file):
Extension | Settings file (Linux paths; macOS uses |
Cline |
|
Roo Code |
|
Kilo Code |
|
Add the server inside the top-level "mcpServers" object:
{
"mcpServers": {
"taiga": {
"disabled": false,
"timeout": 60,
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Approve the server's tool use when the extension prompts; per-tool auto-approval can be configured in the same panel.
Continue.dev
Continue reads MCP servers either from mcpServers: blocks in its config or from standalone YAML files in .continue/mcpServers/ (it also accepts Claude/Cursor/Cline JSON configs dropped into that directory unchanged):
# ~/.continue/config.yaml (or .continue/mcpServers/taiga.yaml with
# name/version/schema metadata fields added)
name: Assistant
version: 1.0.0
schema: v1
mcpServers:
- name: Taiga
type: stdio
command: npx
args:
- -y
- mcp-taiga
env:
TAIGA_USERNAME: your_username
TAIGA_PASSWORD: your_passwordMCP tools are available in agent mode.
Zed
Add a custom context server in settings.json (zed: open settings):
{
"context_servers": {
"taiga": {
"command": {
"path": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}
}JetBrains IDEs
Open Settings → Tools → AI Assistant → MCP (or the dedicated MCP settings page in newer releases), click Add, choose As JSON, and paste:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Requires the AI Assistant plugin with MCP support enabled.
Gemini CLI
Edit ~/.gemini/settings.json and restart the CLI. Tools require confirmation per call unless you allowlist them:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
},
"includeTools": ["projects", "work", "sprints", "comments", "attachments", "wiki"]
}
}
}Check registration with /mcp list inside the CLI.
Codex CLI
Add a server table to ~/.codex/config.toml:
[mcp_servers.taiga]
command = "npx"
args = ["-y", "mcp-taiga"]
[mcp_servers.taiga.env]
TAIGA_USERNAME = "your_username"
TAIGA_PASSWORD = "your_password"Verify with codex mcp list; tools appear as taiga_* inside sessions.
opencode
Add to opencode.json (project root or ~/.config/opencode/opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"taiga": {
"type": "local",
"command": ["npx", "-y", "mcp-taiga"],
"environment": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
},
"enabled": true
}
}
}Note the singular environment key and array-form command, which differ from the Claude-style schema.
Amp
Prefer the CLI for user-scope servers:
amp mcp add taiga -- npx -y mcp-taigaOr declare amp.mcpServers in ~/.config/amp/settings.json (workspace .amp/settings.json variants require running amp mcp approve taiga first):
{
"amp.mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Pi
Pi reads Claude-style MCP config from two scopes: ~/.pi/agent/mcp.json (user) and .mcp.json or mcp.json in the working directory (project). Edit the user file:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}Remote servers use "url" plus "transport": "http". Manage servers with /mcp inside a session (/mcp add, /mcp list, enable/disable per server).
This repository ships its own .mcp.json, so launching pi inside a local checkout picks up the local build automatically (no credentials needed there — the server loads the repo .env).
Oh My Pi
omp shares pi's agent core but has its own config root. Edit ~/.omp/agent/mcp.json:
{
"mcpServers": {
"taiga": {
"command": "npx",
"args": ["-y", "mcp-taiga"],
"env": {
"TAIGA_USERNAME": "your_username",
"TAIGA_PASSWORD": "your_password"
}
}
}
}MCP servers bind when the session is constructed — restart omp after editing. Tools surface as taiga_* entries; project-level configs follow pi's discovery (including this repo's checked-in .mcp.json).
Remote and Web Clients (HTTP Transport)
Set TAIGA_HTTP_PORT to expose the same six tools over streamable HTTP instead of stdio — useful for clients that cannot spawn local processes, or for running one shared instance:
TAIGA_HTTP_PORT=3000 npx -y mcp-taiga
# serves http://127.0.0.1:3000/mcpProperties: stateless mode (no session headers), bound to 127.0.0.1 unless TAIGA_HTTP_HOST overrides it (non-loopback binds print a plaintext-HTTP warning to stderr), DNS-rebinding protection enabled for the advertised host, malformed JSON rejected with -32700, non-POST methods on /mcp answered 405.
Clients connect by URL rather than command:
{
"mcpServers": {
"taiga": {
"url": "http://127.0.0.1:3000/mcp"
}
}
}Continue.dev equivalent: type: streamable-http with url:; opencode: type: "remote" with url:. Because the process is launched manually rather than by the client, export TAIGA_USERNAME/TAIGA_PASSWORD in that shell (or use a systemd unit, container, etc.).
Containers
The included two-stage Dockerfile uses Node 22 Alpine with a non-root node user. The build stage compiles the TypeScript source, and the runtime stage packages only the compiled dist/src output and production dependencies.
Build the container image:
docker build -t mcp-taiga .Run the container attached to standard I/O:
docker run --rm -i --env-file .env mcp-taigaPodman works by direct substitution: replace docker with podman in the commands above.
Point an MCP client configuration at the container runner:
{
"mcpServers": {
"taiga": {
"command": "docker",
"args": ["run", "--rm", "-i", "--env-file", "/absolute/path/to/.env", "mcp-taiga"]
}
}
}For an HTTP deployment, publish the port instead: docker run --rm -p 127.0.0.1:3000:3000 -e TAIGA_HTTP_PORT=3000 --env-file .env mcp-taiga and point URL-based clients at http://127.0.0.1:3000/mcp.
There is deliberately no compose file. An MCP stdio server must be spawned attached directly to its client's stdin and stdout streams, and exits when that stdin stream closes. Process supervisors or compose setups that attempt to keep long-running background services alive cause infinite restart loops and container name conflicts.
Conventions
Projects: Project arguments accept a numeric project ID (e.g.
19) or a slug (e.g."acme-web").Work Items: Work items accept a numeric database ID (e.g.
1888) or a reference prefixed with hash (e.g."#70"). A#referencerequires theprojectargument to resolve.People: Member arguments accept a numeric user ID, username (e.g.
"jdoe"), full name (e.g."Jane Doe"), or the literal"me".Taxonomies: Statuses, priorities, severities, issue types, and sprint names accept human-readable names and are resolved to numeric IDs server-side.
Multi-Assignee User Stories: Taiga user stories support multiple assignees via
assigned_users. Filtering byassigneeonwork list type:storymatches co-assignees, and listings display all assignees rather than only the primary.Dense Text Results: Results are plain text formatted with one dense line per record or clean key-value blocks for detail views. No consumer reads
structuredContent, so results are text only. An empty collection is reported as<items> in <project>: 0rather than an error.Full Collections: List endpoints return complete collections because the client sends the
x-disable-pagination: truerequest header, eliminating multi-page roundtrips.
Why Six Tools
Single-purpose tool proliferation creates substantial context window overhead before any tool is invoked. Consolidating functionality into 6 op-dispatching domain tools keeps the tools/list payload to about 10,493 characters (~2,800 tokens).
Output schemas are deliberately absent from tool registrations: MCP client bridges concatenate text content and ignore outputSchema and structuredContent, so omitting output schemas eliminates unnecessary token overhead on session startup.
Tool Reference
The server exposes 6 tools covering 28 operation pairs.
1. projects
List or inspect Taiga projects and verify credentials.
Op | What it does | Required args | Optional args |
| List projects where authenticated user is a member | (none) | (none) |
| Inspect project metadata, owner, member count, active modules |
| (none) |
| Verify credentials and show current user info | (none) | (none) |
2. work
Manage issues, user stories, tasks, and epics (type: issue, story, task, epic).
Op | What it does | Required args | Optional args |
| List work items with server-side filters |
|
|
| Get complete details and description for a work item |
|
|
| Create a single work item or batch items |
|
|
| Update fields on an existing work item |
|
|
| Link a user story to an epic |
|
|
| Remove a user story from an epic |
|
|
| Permanently delete a single work item |
|
|
3. sprints
Manage sprints (milestones) and inspect progress statistics.
Op | What it does | Required args | Optional args |
| List sprints in a project |
| (none) |
| Get sprint details and assigned user stories |
|
|
| Create a new sprint milestone |
|
|
| Get sprint progress statistics and completion metrics |
|
|
Sprint deletion is intentionally not exposed: removing a milestone detaches every story and task on it, making it a board-wide edit that belongs in the Taiga UI.
4. comments
List, add, edit, or delete comments on work items and wiki pages (type: issue, story, task, epic, wiki).
Op | What it does | Required args | Optional args |
| List comments oldest first |
|
|
| Add a comment to an item |
|
|
| Edit an existing comment by UUID |
|
|
| Soft-delete a comment by UUID |
|
|
5. attachments
Manage file attachments on work items and wiki pages (type: issue, story, task, epic, wiki).
Op | What it does | Required args | Optional args |
| List attachments on an item |
|
|
| Upload a file from local path or base64 |
|
|
| Fetch attachment metadata; optionally writes file to disk |
|
|
| Permanently delete an attachment |
| (none) |
6. wiki
Manage wiki pages and page subscriptions within a project.
Op | What it does | Required args | Optional args |
| List all wiki pages in a project |
| (none) |
| Inspect wiki page metadata and Markdown content |
|
|
| Create a new wiki page |
|
|
| Update wiki page content |
|
|
| Permanently delete a wiki page |
|
|
| Watch or unwatch a wiki page |
|
|
Reliability and Safety
Rate Limiting (429): The server retries HTTP 429 responses at most twice, honoring the server
Retry-Afterheader. If the required wait exceeds the 5-second ceiling (MAX_THROTTLE_WAIT_MS), it throws immediately with a retry message instead of sleeping.5xx Errors Never Retried: 5xx responses are never retried automatically because mutating requests (such as POST) may have already been applied on the server; repeating them risks creating duplicate records.
Metadata Cache: Project metadata (slug lookups, user memberships, and taxonomy lists for statuses, priorities, severities, and issue types) is cached for 60 seconds (
METADATA_TTL_MS) viagetMetadata. Work items, comments, and attachments are never cached.Timeouts: HTTP requests enforce a 30-second timeout (
REQUEST_TIMEOUT_MS).HTTPS Enforcement: The server emits a warning to stderr if
TAIGA_API_URLuses unencrypted HTTP to a non-loopback host.Restricted Attachment Downloads: Attachment downloads are restricted strictly to the configured Taiga hostname with no redirects allowed (
maxRedirects: 0), bounded to a maximum file size of 10 MB (MAX_ATTACHMENT_BYTES). The download request does not send the Taiga bearer token to media hosts.File Overwrite Protection: Attachment download with
savePathrefuses to overwrite an existing local file.Single-Target Deletions: Deletion operations accept exactly one target at a time. Batch operations are create-only (up to 20 items), preventing accidental board-wide deletions.
Security Considerations
Credentials travel via environment variables or harness config files, never command-line arguments (which leak through process lists) and never the repository. Keep harness config files containing inline passwords out of version control;
.gitignorealready excludes.env*except.env.example.The optional HTTP transport binds to loopback by default and enables DNS-rebinding protection; binding to a routable address prints a warning because traffic is unencrypted.
Attachment downloads never carry your bearer token off the Taiga hostname, refuse redirects, cap file size, and refuse to overwrite existing files.
Deletion surfaces are single-target by design; there are no batch deletes.
FAQ
Which MCP clients can use it? Anything that speaks stdio MCP — the installation guide covers seventeen of them with copy-paste configs — plus URL-based clients through the HTTP transport.
Does it work with self-hosted Taiga?
Yes. Set TAIGA_API_URL to your instance including the /api/v1 suffix (e.g. https://taiga.example.com/api/v1). Everything else behaves identically; if requests 404, see Troubleshooting.
Can I connect more than one Taiga account or instance?
Not within one server process — it holds exactly one credential set, read from the environment at startup. Register additional entries under mcpServers (e.g. "taiga-work") with their own env values; each becomes an independent tool namespace like mcp__taiga-work__work.
Where does my password go? From your env block into memory, and from there only to the configured Taiga host during the login exchange — never to command lines (which leak via process lists), logs, tool results, or attachment download hosts. See Security Considerations.
Is it read-only? No: full create, update, link/unlink, and delete across work items, sprints, comments, attachments, and wiki pages. Sprint deletion and batch deletion are deliberately absent — see Reliability and Safety.
Why only six tools when other MCP servers expose dozens? Context-window economics: every tool definition is paid on every session start. See Why Six Tools.
Something broke — where do I start? Troubleshooting covers the common failure modes; beyond that, open a GitHub issue with the failing tool call and the server's stderr output.
Troubleshooting
Authentication failures — run the
projectstool withop: whoami; it reports exactly which credential exchange failed. Check for stray whitespace in env values and that the account works in the Taiga web UI.Self-hosted instance returns 404s —
TAIGA_API_URLmust include/api/v1, e.g.https://taiga.example.com/api/v1.Server starts but npx client sees no tools — confirm Node.js >= 20.11 runs in the harness's environment; GUI launchers often inherit a different PATH than your shell.
Credentials ignored under npx — npx installs do not load
.env; put credentials in the harnessenvblock (only local checkouts auto-load.env).HTTP mode port conflicts — another process owns the port; pick another
TAIGA_HTTP_PORT. The server exits nonzero with a listen error rather than retrying.Empty result sets — listings report
<items> in <project>: 0; that is a successful response, not an error.Cursor/Windsurf server present but idle — toggle the server enabled switch in the respective settings panel after editing config files; both cache state until refreshed.
Development
File Layout
src/index.ts # Entrypoint: createServer() factory, stdio vs HTTP transport selection
src/http.ts # Streamable HTTP transport (node:http, stateless, DNS-rebinding protected)
src/api.ts # Authenticated axios transport, generic HTTP helpers (get, post, patch, del), token management, retry policy, metadata cache
src/taiga.ts # Domain helpers: resolution (projects, items, members, taxonomies, sprints) and optimistic concurrency patch
src/types.ts # Taiga payload interfaces, tool definitions, and type contracts
src/format.ts # Dense pipe-separated single-line renderers and detail views
src/utils.ts # MCP response builders (createSuccessResponse, createErrorResponse, guard) and formatting helpers
src/constants.ts # Endpoints, limits (batch size, attachment size), status labels, error messages
src/tools/index.ts # Tool registry aggregating all tools and registering with McpServer
src/tools/projects.ts # projects tool (list, get, whoami)
src/tools/work.ts # work tool (list, get, create, update, link, unlink, delete across issues, stories, tasks, epics)
src/tools/sprints.ts # sprints tool (list, get, create, stats)
src/tools/comments.ts # comments tool (list, add, edit, delete)
src/tools/attachments.ts # attachments tool (list, upload, download, delete)
src/tools/wiki.ts # wiki tool (list, get, create, update, delete, watch)
test/unitTest.ts # Offline unit tests for pure helpers, formatting functions, response builders, and tool invariants
test/protocolTest.ts # Protocol tests verifying MCP stdio handshake, server capabilities, tool count, and tools/list budget
test/httpTest.ts # Transport tests verifying the streamable HTTP endpoint: handshake, tools/list, routing rejections
test/apiContractTest.ts # Contract tests driving every tool op against an in-process mock Taiga HTTP server, asserting outgoing HTTP requests
test/integration.ts # Live integration smoke test against a real Taiga instance (read-only, skips without credentials)NPM Scripts
npm run build: Compiles TypeScript fromsrc/andtest/intodist/viatsc.npm run check: Type-checks TypeScript code without emitting output (tsc --noEmit).npm run lint: Runs oxlint acrosssrc/andtest/.npm start: Runs the compiled server (node dist/src/index.js).npm test: Compiles and runs unit, protocol, contract, and HTTP transport test suites in sequence.npm run test:unit: Compiles and runs offline unit tests.npm run test:protocol: Compiles and runs MCP protocol tests over stdio.npm run test:http: Compiles and runs streamable HTTP transport tests.npm run test:contract: Compiles and runs API contract tests against the mock Taiga server.npm run test:integration: Compiles and runs live integration tests against a live instance.npm run prepublishOnly: Runs type check, linting, and full test suite before publishing.
Test Suites
Unit Tests (
test/unitTest.ts): Offline unit tests asserting pure formatting functions, response builders, identifier resolution helpers, and tool-definition invariants without network calls or credentials.Protocol Tests (
test/protocolTest.ts): Protocol tests asserting the real MCP stdio handshake, server version and capabilities, tool schemas, and thetools/listcharacter budget against a spawned server process.HTTP Tests (
test/httpTest.ts): Spawns the compiled server withTAIGA_HTTP_PORTand asserts the real streamable HTTP handshake, protocol-version echo, stateless behavior,tools/listcontents, and 400/404/405 routing rejections over localhost.Contract Tests (
test/apiContractTest.ts): Contract tests asserting that every tool and op sends the expected outgoing HTTP requests (method, endpoint, query parameters, headers, and payload) and processes responses against an in-process mock Taiga HTTP server.Integration Tests (
test/integration.ts): Live integration smoke tests asserting read-only tool operations against a real Taiga instance over stdio (skipped when credentials are not configured).
Contributing
Pull requests target dev; see CONTRIBUTING.md for the branch model (dev → staging → main), commit conventions, and the release process.
Changelog
See CHANGELOG.md.