@heizen-labs/studio-mcp
v1.1.2
Published
Model Context Protocol server for Heizen Studio — list and manage your bugs and tasks from Claude Code, Cursor, or any MCP client.
Readme
Heizen Studio MCP Server
A Model Context Protocol server for Heizen Studio. It exposes your bugs, tasks, time logs, QA test cases, wiki pages, and project resources as tools for Claude Code, Cursor, Claude Desktop, Windsurf, and other MCP clients.
Quick start
# 1. Sign in (caches your token locally in ~/.heizen)
npx @heizen-labs/studio-mcp login
# 2. Register with Claude Code
claude mcp add heizen-studio -- npx -y @heizen-labs/studio-mcp
# 3. Open a NEW Claude Code session and ask: "list my open bugs"No secrets go in your client config — login caches your credentials locally and the server reads them.
Connect it to your client
Claude Code
claude mcp add heizen-studio -- npx -y @heizen-labs/studio-mcpCursor / Claude Desktop / Windsurf
Add to the client's MCP config (~/.cursor/mcp.json, Claude Desktop's claude_desktop_config.json, …):
{
"mcpServers": {
"heizen-studio": {
"command": "npx",
"args": ["-y", "@heizen-labs/studio-mcp"]
}
}
}Restart the client, then try:
- "List my open bugs."
- "Show me bug 384 in detail."
- "Mark bug
<id>as FIXED and comment that the PR is up." - "Create a test case for admin login in the Auth suite."
Sign in
npx @heizen-labs/studio-mcp loginThis opens studio.heizen.work in your browser. Sign in normally (Google, etc.) — the token is sent back to the CLI automatically and cached. No copying, no DevTools. The token covers everything, including file uploads.
No browser? (CI / remote / headless) — use login --manual to paste a token by hand (DevTools →
Network → any request → Request Headers → Authorization, the value after Bearer ), or set
HEIZEN_TOKEN, or pass it directly: login <token>.
You don't have to run this yourself: ask the agent to "sign in to Heizen" and it calls the authenticate
tool, which runs the same browser flow. When a token expires mid-session, tools return a clear message and
the agent can re-run authenticate to recover without restarting.
Tools
Account & projects
| Tool | What it does |
| ---------------------- | ------------------------------------------------------------------------------------------------------------ |
| authenticate | Sign in / re-authenticate from the client — opens the browser and captures the token (no npx login needed) |
| whoami | Show the signed-in user and the active project (run this first if anything errors) |
| list_projects | Your projects (active + archived); the default is marked ★ |
| get_project | Project details: type, model, client requirements, monitoring URLs |
| list_project_members | People on a project (name, email, role); scope to one/several/allProjects |
| set_default_project | Pin the project used by other tools, by id or name (remembered) |
| list_sprints | A project's sprints (name, status, dates, id); scope to one/several/allProjects |
| check_for_updates | Check npm for a newer version of this server and how to update |
Bugs
| Tool | What it does |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| list_bugs | Bugs for anyone, scoped to one project, a list of projects, or allProjects; filter by assignee (name/email/"me"/"unassigned"), status, priority, search, paging. E.g. { allProjects, assignee: "pavan" } = Pavan's bugs everywhere |
| get_bug | Full bug detail by id or number (report, expected, evidence, PRs, comments) |
| create_bug | Report a new bug in a project (write) |
| update_bug | Edit a bug's title, report text, or priority (write) |
| delete_bug | Delete a bug (write) |
| update_bug_status | Move a bug to a new status (write) |
| assign_bug | Set/clear a bug's assignee (write) |
| convert_bug_to_story | Turn a bug into a user story (write) |
| add_bug_comment | Comment on a bug, optionally threaded (write) |
| update_bug_comment | Edit a bug comment (write) |
| delete_bug_comment | Delete a bug comment (write) |
| upload_bug_attachment | Attach local files (evidence) to a bug (write) |
| remove_bug_attachment | Remove a bug attachment by URL (write) |
Stories, epics & sprints
| Tool | What it does |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| list_stories | Stories for anyone, scoped to one project, a list of projects, or allProjects; filter by assignee (name/email/"me"/"unassigned"), status, search, paging. E.g. { allProjects, assignee: "pavan" } = Pavan's stories everywhere |
| get_story | Full story detail by id or number (description, acceptance criteria, status, PRs, test cases) |
| create_story | Create a story under an epic (write) |
| update_story | Change a story's status, reassign it, or edit fields (write) |
| delete_story | Delete a story (write) |
| list_epics | A project's epics (tasks) with story counts and ids |
| create_epic | Create an epic to group stories (write) |
| update_epic | Edit an epic's title, description, or type (write) |
| delete_epic | Delete an epic (write) |
| move_story_to_epic | Reparent a story under a different epic (write) |
| get_sprint | The stories in a sprint by id (from list_sprints); filter by assignee, status, search |
| create_sprint | Create a sprint (title, dates) (write) |
| update_sprint | Edit a sprint's name, status, or dates (write) |
| delete_sprint | Delete a sprint (write) |
Wiki
| Tool | What it does |
| ------------------ | ------------------------------------------------------------------------------------- |
| list_wiki_pages | Wiki page tree (docs, specs, requirements, notes); scope to one/several/allProjects |
| get_wiki_page | Read a page's full Markdown content by id |
| create_wiki_page | Create a page with a title and Markdown content (write) |
| update_wiki_page | Edit a page's title and/or Markdown content (write) |
| delete_wiki_page | Delete a wiki page (write) |
| comment_on_wiki | Comment on a wiki page, optionally threaded (write) |
Resources
| Tool | What it does |
| ------------------------- | ------------------------------------------------------------------------ |
| list_project_resources | Linked resources (docs, Figma, URLs); scope to one/several/allProjects |
| get_project_resource | One resource's detail by id (name, type, URL, tags, status) |
| add_project_resource | Link a resource to a project by name, URL, and type (write) |
| update_project_resource | Edit a resource's name, URL, or type (write) |
| remove_project_resource | Unlink a resource from a project (write) |
Time logs
| Tool | What it does |
| ---------------- | ----------------------------------------------------------- |
| list_worklogs | Your time entries (filter by project/date), with total |
| log_time | Record hours worked, optionally on a bug or story (write) |
| update_worklog | Edit a time entry (write) |
| delete_worklog | Delete a time entry (write) |
QA / test cases
| Tool | What it does |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| list_test_suites | Test suites (repositories) in a project, each with its cases |
| create_test_suite | Create a test suite (write) |
| update_test_suite | Edit a test suite (write) |
| delete_test_suite | Delete a test suite (write) |
| list_test_cases | Test cases in a specific suite |
| get_test_case | A single test case in full |
| create_test_case | Create a complete test case: steps, preconditions, expected, attachments (write) |
| record_test_case | Record mode — open a real browser (one or several sites), click through the flow, and it captures the steps to draft into a test case |
| update_test_case | Edit an existing test case (write) |
| delete_test_case | Delete a test case (write) |
| generate_test_cases_from_story | Auto-generate test cases from a story's acceptance criteria (write) |
| list_test_plans | Test plans in a project |
| get_test_plan | A single test plan's details |
| create_test_plan | Create a test plan (write) |
| update_test_plan | Edit a test plan (write) |
| delete_test_plan | Delete a test plan (write) |
| list_test_environments | A project's test environments and their {{variables}} (URL, EMAIL, …) for use in steps |
| create_test_environment | Create a test environment, with variables (write) |
| update_test_environment | Edit a test environment / merge variables (write) |
| delete_test_environment | Delete a test environment (write) |
| run_tests | Run a whole suite or plan against an environment; returns an executionId (write) |
| run_test_case | Run a single test case against an environment (write) |
| get_test_execution | Watch a running/finished execution — overall status + each case run |
| get_test_run | One run's full detail |
| set_test_run_status | Mark a run's result (PASSED / FAILED / …) (write) |
| list_case_runs | A test case's run history |
| list_plan_runs | Runs under a plan (what's running / recently run) |
| qa_dashboard | QA summary; scope to one/several/allProjects to roll up across projects |
Two ways to author a case: auto — the agent writes it from the codebase (create_test_case); or
record — record_test_case opens a real Chromium window (pass urls to open several sites at once,
e.g. the admin app and the org view), you click through the scenario, mark assertions with the on-page
“+ Add check” button, hit “✓ Finish”, and the agent drafts the captured steps into a case for your
approval. Record mode needs a display (not headless CI) and npx playwright install chromium.
Files & screenshots
| Tool | What it does |
| -------------------- | ---------------------------------------------------------------------------------- |
| capture_screenshot | Screenshot a URL with headless Chromium (run npx playwright install chromium) |
| upload_attachment | Upload local files (≤50 MB) and get URLs to use as test-case attachments (write) |
| get_signed_url | Get a temporary (~1h) signed link for a stored file |
create_test_case / update_test_case also accept attachmentPaths (local files) directly — they
upload and attach in one step.
Prompts
Invoke these from your client's prompt picker for guided workflows:
write_test_case— draft and create a thorough test case, grounded in the codebasebuild_test_suite— create a suite and a set of cases covering a feature areaqa_from_story— generate and refine test cases from a user storyplan_feature— read the requirement/codebase, then create an epic + scoped storiescross_project_status— summarize work across every project, paging through resultstriage_my_bugs— review your assigned bugs and plan what to tacklelog_work— record your time against a bug/story
Configuration
All optional — login handles auth and a single project is auto-selected.
| Variable | Purpose |
| ---------------------- | ------------------------------------------------------------------ |
| HEIZEN_TOKEN | Use this token instead of the cached login |
| HEIZEN_PROJECT | Default project id (otherwise auto-selected / pinned) |
| HEIZEN_CONFIG_DIR | Where credentials are cached (default ~/.heizen) |
| HEIZEN_PROJECT_DIR | Where the per-folder project pin is stored (default current dir) |
| HEIZEN_CLI_AUTH_PATH | Studio page the browser login opens (default /auth/cli-callback) |
| HEIZEN_CALLBACK_PORT | Local port for the login callback server (default 9876) |
| HEIZEN_AUTO_APPROVE | true to skip the confirm prompt on writes/deletes |
| HEIZEN_TIMEOUT_MS | Per-request timeout (default 30000) |
| HEIZEN_LOG_LEVEL | debug | info | warn | error | silent (default info) |
Your login token is cached globally in ~/.heizen. The default project is pinned per folder:
set_default_project writes .heizen/project.json in the current directory, so each folder remembers its
own Heizen project. Add .heizen/ to your .gitignore.
Skipping write confirmations. Writes and deletes ask for confirmation (via MCP elicitation) when your
client supports it. To bypass that for a trusted setup, set HEIZEN_AUTO_APPROVE=true, or add
"autoApprove": true to .heizen/project.json next to the project id:
{ "projectId": "…", "autoApprove": true }With auto-approve on, mutating tools run immediately without prompting. (Clients that don't support elicitation already proceed without a prompt; the client's own tool-approval still applies.)
Troubleshooting
- "Not authenticated" / 401 — token missing or expired. Run
npx @heizen-labs/studio-mcp login. - "You have multiple projects" — pass
project, or pin one withset_default_project. - Upload rejected (400) — files must be ≤50 MB; executable/script types are blocked.
capture_screenshotfails — runnpx playwright install chromiumonce.
License
MIT
