Skip to main content
Glama

ticket-writer MCP

An MCP server for MagOneAI. A reporter drops a feature request in as free text; the workflow asks the few questions needed to make it actionable, then files a ticket that states the problem, what needs to be done, the acceptance criteria and any architecture decisions.

Jira, GitHub, GitLab and Linear come out of the same code path.

The server never calls a tracker. It renders the create-issue request and hands it back; the workflow's own HTTP node sends it.


How the workflow runs

free text  ──▶  check_request  ──"needs_clarification"──▶  ask the reporter ──┐
                     │                                                        │
                     │◀──────────────────── answers ─────────────────────────┘
                  "ready"
                     │
                     ▼
                render_ticket  ──"possible_duplicate"──▶  human confirms ──┐
                     │                                                     │
                     │◀────────── confirm_not_duplicate ───────────────────┘
              "ready_to_send"
                     │
                     ▼
          HTTP node: POST request.url  ◀── the only write in the workflow
                     │
                     ▼
              issue key + url back to the reporter

WORKFLOW.md has the node-by-node contract: exact input and output JSON, and every field that ends up on the ticket.


Related MCP server: ProduckAI MCP Server

Why it does not connect to Jira itself

The first draft had a Jira REST client in it. That version needed credentials on this box, gained a failure mode where the ticket rendered fine and the POST failed, and locked the workflow to one tracker.

Rendering a request instead means:

  • no credentials here — headers carry {{PLACEHOLDER}} names the API node substitutes from MagOne's secret store

  • any tracker — a new one is a dict entry in src/targets.py

  • reuse what MagOne already has — if a tracker MCP is connected, use target="generic" and pass the fields to its create tool

  • an approval step fits — nothing is written until after the render call

  • testable with pytest and nothing else — no network in the whole repo

It does not write the ticket prose either. The workflow agent is a language model and is better at turning a rambling Slack message into a problem statement than any rubric in this repo would be. What this server owns is the part that must behave identically on every run: the checklist, the question wording, the body format, and the duplicate guard.


Tools

Tool

Purpose

check_request

Is this enough to file? If not, what to ask.

render_ticket

The create-issue request, formatted for one tracker.

list_targets

Trackers, config keys, which credential the API node needs.

duplicate_search_query

Optional. Builds the search query for the dup check.

All four are read-only. Every response carries a status the canvas switches on:

status

Workflow action

ready

proceed to render_ticket

needs_clarification

ask questions, loop

possible_duplicate

show candidates, get a human answer

ready_to_send

pass request to the API node

error

read hint — usually a missing config key


What makes a ticket complete

check_request blocks on four fields, asked in this order, at most three per round:

  1. problem — what hurts today, who is affected

  2. goal — what should exist when it is done, as behaviour

  3. acceptance_criteria — how a reviewer accepts or rejects it

  4. architecture_notes — decisions made, constraints to respect ("none known" is valid when the design is still open)

affected_users and out_of_scope are collected when offered but never block. An answer under 25 characters, or one that echoes the question back, does not count as answered.

To change the checklist, edit SLOTS in src/ticket.py — the questions, the ranking and the cap all follow from that list.


Targets

target

config

Credential the API node supplies

jira

base_url, project_key

{{JIRA_BASIC_AUTH}} — base64 email:api_token

github

owner, repo

{{GITHUB_TOKEN}} — PAT with Issues read/write

gitlab

project_id, host?

{{GITLAB_TOKEN}} — token with api scope

linear

team_id, project_id?

{{LINEAR_API_KEY}}

generic

none — hand fields to that tracker's own MCP

Differences the renderer absorbs so the agent never has to:

  • Jira wants ADF, not markdown, in description. Passing a markdown string is the most common way a hand-wired Jira node fails.

  • GitLab wants labels as a comma string; GitHub and Jira want a list.

  • GitHub has no priority field, so priority becomes a priority-* label.

  • Linear is GraphQL — one endpoint, mutation in the body.

Adding a tracker: one TARGETS entry with a build() returning (url, headers, body). That is the whole change.


Duplicate guard

This server cannot search, so the workflow feeds it: duplicate_search_query builds the query, a search node runs it, the hits go back into render_ticket as existing_issues=[{key, summary, url}]. Summaries scoring ≥ 0.6 token overlap come back as possible_duplicate.

No search node, no check — the ticket still renders. That is the trade for not owning a search client per tracker.


Run it

python -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest -q          # 47 tests, no network, no account

Local MCP over stdio, for Claude Desktop:

MCP_TRANSPORT=stdio .venv/bin/python -m src.server

Deploy:

docker build -t ticket-writer .
docker run -p 8000:8000 -e TICKET_WRITER_TOKEN=$(openssl rand -hex 32) ticket-writer
curl localhost:8000/health

Register https://your-host/mcp in MagOneAI with header Authorization: Bearer $TICKET_WRITER_TOKEN, exactly as the Outlook MCP is configured. TICKET_WRITER_TOKEN is the only environment variable the server requires; MCP_TRANSPORT, HOST, PORT and LOG_LEVEL have working defaults. Set max_iterations around 12.


File a real ticket to check it

scripts/send.py does exactly what the API node does — render, substitute the placeholder from the environment variable of the same name, POST:

.venv/bin/python scripts/send.py --target jira \
  --config base_url=https://you.atlassian.net project_key=KAN --dry   # payload only

export JIRA_BASIC_AUTH=$(printf '%s' 'you@mail.com:API_TOKEN' | base64)
.venv/bin/python scripts/send.py --target jira \
  --config base_url=https://you.atlassian.net project_key=KAN         # 201 + issue key

TESTING.md covers what each suite proves, the live run against Jira Cloud, and the error table.


Security

  • Bearer token from an env var, never through a workflow node — a token that transits the canvas ends up in run logs.

  • No tracker credential ever reaches this server. Headers are placeholders; config takes locations, not secrets. A test asserts it.

  • /health is unauthenticated for platform probes; everything else is not. The server refuses to start over HTTP with no token set.

  • Non-root container user.

  • Reporter text is data, not instructions. It is stored verbatim in a blockquote and never interpreted. The tool docstrings say so, because that is what the agent reads.

  • The duplicate guard and the completeness check are what stand between a chatty Slack channel and a hundred junk tickets. Do not add a flag that skips both.


Layout

src/server.py    MCP surface: tool defs, transport, auth
src/ticket.py    pure: rubric, questions, body in markdown + ADF, dup scoring
src/targets.py   pure: what each tracker's API wants — one entry per tracker
tests/           47 tests: the rules, the tool surface, HTTP and auth
scripts/send.py  stands in for the API node, for end-to-end checks
WORKFLOW.md      node-by-node input/output contract
TESTING.md       what is covered, what is not

ticket.py knows nothing about any tracker; targets.py knows nothing about what makes a ticket good. If adding a required field means editing targets.py, the split has leaked.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Turns vague automation requests into tool stacks, prompts, QA checks, and human boundaries.

  • Decision intelligence for product teams. Turn scattered feedback into signal you can act on.

  • Manage feature requests, votes, roadmaps, and changelogs from any MCP client.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AlanAAG/ticket-writer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server