issuehub
MCP server that provides issue tracking tools for Jira, Redmine, GitHub, and GitLab via the Model Context Protocol, enabling agents to search, fetch, sync, and manage issues through natural language.
README
issuehub
issuehub is a standalone, provider-agnostic issue-tracker CLI. It caches,
indexes, syncs, searches, and exports issues from Jira, Redmine, GitHub, and
GitLab into a plain-file workspace that any tool can read. Attachment
metadata travels with each issue; bytes download only on explicit request
(issuehub attachments --fetch/--all), and always land under .state/,
never the workspace — see docs/FORMATS.md §Attachments.
The workspace also carries a per-issue memo, metadata, and (produced by an AI
backend on the other side of this CLI, never by this CLI itself)
translations/<lang>.md files — this CLI reads and full-text-indexes those,
and validates a language tag before it ever becomes a filename, but does not
generate them (see docs/FORMATS.md §Translations).
If you keep your workspace in a shared or public repository: translated
issue titles/descriptions, and analysis responses, are Git-tracked by
design (so a translation can be hand-corrected and an analysis kept for
reference) — so issue content you translate or analyze ends up in that
repository's history, not only in the local, git-ignored cache. Optionally
including comments in a translation also carries commenter names into the
tracked file. None of this is a bug; it just means "private tracker" and
"public repository" are two different choices, and it is worth picking the
one you mean. See docs/FORMATS.md §What lands in Git, and what leaves the
machine for the full picture.
Design stance
- One invocation per command. No daemon, no persistent process.
issuehubreads its inputs, does the work, prints a result, and exits. - Zero required external binaries. HTTP is in-process (
httpx) and the index uses the stdlibsqlite3module, not asqlite3CLI.gitis purely informational (the workspace is designed to be git-managed, not required to be) andrgis optional — without it,searchfalls back to a pure-Python scan, so its absence is a warning, never an error. - Machine-readable by default when asked. Every verb has a
--jsonmode producing stable, documented output, soissuehubcomposes into scripts, CI, and other tools without scraping human-oriented text. - The on-disk workspace is a published interface, not an implementation
detail — other tools may read and write the same files, so its format is a
compatibility contract (see
docs/FORMATS.md). - Credentials never reach argv, logs, or disk.
Install
pip install issuehub-cli
The PyPI distribution is named issuehub-cli, but the import package and the
console script are both still issuehub — that split is intentional and
common (the package you pip install need not match the name you import
or run), so after installing you still import issuehub and run
issuehub <verb>.
or, from a checkout:
pip install -e .
Requires Python 3.10+. See pyproject.toml for the optional analysis extra
(pandas-backed export aggregates), the optional mcp extra (fastmcp-backed
MCP server, issuehub mcp serve — see docs/MCP.md), and the dev extra
(test tooling).
Verification status
This CLI has been run against a live GitHub instance, which surfaced four
real bugs (now fixed — see docs/CORRECTNESS.md). The Jira, Redmine, and
GitLab providers, by contrast, have only been exercised against recorded
payloads in the shared conformance corpus (corpus/) — they have not been
run against a live Jira, Redmine, or GitLab instance. If you're picking this
tool for one of those three providers, treat it as conformance-tested but not
yet field-tested, and please report anything that doesn't match a live
server's behavior.
Usage
Point issuehub at a workspace directory (--workspace <path> or
$ISSUEHUB_WORKSPACE) and, if you have provider credentials, a config file
(--config <path>, $ISSUEHUB_CONFIG, or <workspace>/.issuehub/config.yaml
— see docs/CONTRACT.md §Config for the full shape):
# ~/notes/issuehub/.issuehub/config.yaml
workspace: ~/notes/issuehub
providers:
jira:
type: jira
url: https://your-org.atlassian.net
user: you@example.com
token_env: JIRA_TOKEN
export ISSUEHUB_WORKSPACE=~/notes/issuehub
issuehub health --json # readiness, no network I/O
issuehub reindex --json # rebuild the search index from the cache
issuehub list --provider jira --json # query the provider (one page by default)
issuehub get jira://PROJ-123 --json # one complete issue, cached unless --refresh
issuehub sync --json # re-fetch known issues, report what changed
issuehub fetch --provider jira --json # page a whole query into the cache, resumably
issuehub search "login bug" --json # local full-text search (cache + notes)
issuehub search 認証 --json # non-ASCII queries route around FTS5's tokeniser gap
issuehub changed --json # issues that moved since you last opened them
issuehub collection add sprint1 jira://PROJ-1 jira://PROJ-2
issuehub collection show sprint1 --json
issuehub export --source all --format csv -o issues.csv
issuehub import issues.csv --dry-run --json # merge edits back after spreadsheet triage
issuehub summarize --source all --by status --json
issuehub attachments jira://PROJ-123 --json # list attachment metadata (no network)
issuehub attachments jira://PROJ-123 --fetch 10001 # download one attachment's bytes
issuehub attachments jira://PROJ-123 --all --json # download every not-yet-downloaded attachment
Run issuehub --help (or see docs/CONTRACT.md) for the full verb list,
arguments, and exit-code conventions.
MCP server
issuehub mcp serve runs an MCP (Model Context Protocol) server over stdio
— the same verbs above, reached as tools/resources by an agent or any
MCP-aware host instead of shelling out to argv. Needs the optional mcp
extra:
pip install "issuehub-cli[mcp]"
issuehub mcp serve --workspace ~/notes/issuehub
Full design (stateless-by-construction, import's consent guardrails, why
fetch's progress becomes MCP notifications instead of stdout JSONL) is in
docs/MCP.md.
Corporate networks (proxy / TLS / client certs)
The full field list lives in docs/CONTRACT.md §Config; these are the three
situations people actually hit on their first run.
Behind an authenticating proxy:
http:
proxy: http://proxy.corp.example:8080
proxy_user: "DOMAIN\\you"
proxy_password_env: PROXY_PASSWORD # or proxy_password_cmd / proxy_password
proxy_auth: basic # the only scheme this CLI supports — see below
no_proxy: "localhost,.internal" # or "*" to bypass the proxy entirely for one provider
proxy_auth only accepts "basic" — this CLI talks HTTP in-process (httpx)
rather than shelling out to curl, so it never inherited curl's
NTLM/negotiate/digest support. Any other value is a loud validation error at
config load, never a silent fallthrough to a scheme it can't actually
perform. no_proxy also honours $NO_PROXY from the environment, and can be
set per-provider (providers.<name>.http.no_proxy) to override the global
value for just that one.
Behind an internal CA:
http:
cacert: ~/certs/root.pem # one CA bundle file
# or, if your CA is distributed as a hashed directory (e.g. /etc/ssl/certs):
capath: /etc/ssl/certs
Use cacert when you have a single root/intermediate bundle file; use
capath when your CA is distributed as a hashed certificate directory
instead — the shape corporate CA distribution often takes. ssl_verify: false also exists as an escape hatch, but it is deliberately noisy (it
prints a stderr warning on every use) and points you back at cacert/
capath as the real fix — reach for it only to unblock yourself
temporarily, not as the answer.
Needing a client certificate:
http:
client_cert: ~/certs/client.pem
client_key: ~/certs/client.key
client_key_password_env: CLIENT_KEY_PASSWORD # or client_key_password_cmd / client_key_password
For any of these, a literal value, a *_cmd (an argv list, stdout trimmed),
and a *_env (an environment variable name) are all accepted for the
password/secret fields, resolved in that order — literal wins if present.
Check it actually took effect: issuehub health --json reports a
network section (proxy/ssl_verify/cacert in effect) and, per provider,
whether its credential resolves — never the value itself. That turns "did
my proxy config work?" into one command instead of a failed request.
Documentation
The full spec of record lives in docs/:
docs/CONTRACT.md— the CLI interface: verbs, JSON, exit codes.docs/FORMATS.md— workspace and.state/on-disk formats.docs/PROVIDERS.md— per-provider specifics.docs/CORRECTNESS.md— the ledger of hard-won correctness decisions.docs/PLAN.md— implementation plan and golden-fixture testing method.docs/CONFORMANCE.md— the shared conformance corpus this repo and the reference implementation both run, and how to add a case.docs/MCP.md— the MCP stdio server (issuehub mcp serve).
Development
The shared conformance corpus under corpus/ (golden fixtures and recorded
provider payloads) is committed, so pytest runs standalone without any
external tooling. See tools/README.md if you need to regenerate the
harvested fixtures from the reference implementation — that path is dev-only
and not required to run the test suite.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。