Atlas / MCP servers / nerpatech / trac-mcp-server

trac-mcp-serverBLOCK

mcp/nerpatech/trac-mcp-server

A MCP (Model Context Protocol) server that provides AI assistants with tools to interact with Trac project management instances — managing tickets, wiki pages, and milestones

Verdict
BLOCK
Grade
D
Trust score
63 /100
Exposed tools
25 14r · 7w · 4d
Transport
sse · stdio · streamable-http
License
MIT
Stars
4
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Standalone MCP server that gives AI agents full access to Trac project management -- tickets, wiki, milestones, and search -- via the Model Context Protocol.

Quick Start

Requires Python 3.10 or later.

pip install .

Set your Trac connection:

export TRAC_URL="https://trac.example.com"
export TRAC_USERNAME="your-username"
export TRAC_PASSWORD="your-password"

Run the server:

trac-mcp-server
Using auto-pm? When trac-mcp-server is driven through auto-pm, auto-pm reads its connection settings from .auto_pm/config.yml in your project root (rather than the environment variables above). Run auto-pm setup in your project directory to generate the file; the resulting .auto_pm/config.yml carries trac.url, trac.username, a ${TRAC_PASSWORD} reference, and component mappings.

Configuration

Configuration via environment variables, .env file, or YAML config file (.trac_mcp/config.yaml):

Read from source at commit e3af4997ffc7OBSERVED · 2026-10-11
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add trac-mcp-server --env TRAC_MCP_AUTH_TOKEN=${TRAC_MCP_AUTH_TOKEN} --env TRAC_PASSWORD=${TRAC_PASSWORD} --env TRAC_PASSWORD_2=${TRAC_PASSWORD_2} -- uvx trac-mcp-server
claude-desktop
{
  "mcpServers": {
    "trac-mcp-server": {
      "command": "uvx",
      "args": [
        "trac-mcp-server"
      ],
      "env": {
        "TRAC_MCP_AUTH_TOKEN": "${TRAC_MCP_AUTH_TOKEN}",
        "TRAC_PASSWORD": "${TRAC_PASSWORD}",
        "TRAC_PASSWORD_2": "${TRAC_PASSWORD_2}"
      }
    }
  }
}
03

Exposed tools (25)

14 read · 7 write · 4 destructive. Blast radius: 4 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
get_server_timereadGet current Trac server time for temporal reasoning and coordination. Returns server timestamp in both ISO 8601 and Unix timestamp formats.
milestone_createwriteCreate a new milestone. Requires TICKET_ADMIN permission. Attributes: due (ISO 8601 date), completed (ISO 8601 date or 0), description (string).
milestone_deletedestructiveDelete a milestone by name. Requires TICKET_ADMIN permission. Warning: This cannot be undone.
milestone_getreadGet milestone details by name. Returns name, due date, completion date, and description as stored: TracWiki, byte-for-byte. Requires TICKET_VIEW permission.
milestone_listreadList all milestone names. Returns array of milestone names (e.g., [
milestone_updatewriteUpdate an existing milestone. Requires TICKET_ADMIN permission. Attributes: due (ISO 8601 date), completed (ISO 8601 date or 0), description (string).
pingreadTest Trac MCP server connectivity and return API version
ticket_actionsreadGet valid workflow actions for a ticket
ticket_attachment_listreadList attachments on a Trac ticket.
ticket_batch_createwriteCreate multiple tickets in a single batch operation. Best-effort: all items attempted, per-item results reported. Bounded by TRAC_MAX_PARALLEL_REQUESTS semaphore. Descriptions are TracWiki and are stored byte-for-byte.
ticket_batch_deletedestructiveDelete multiple tickets in a single batch operation. Best-effort: all items attempted, per-item results reported. Requires TICKET_ADMIN permission.
ticket_batch_updatewriteUpdate multiple tickets in a single batch operation. Best-effort: all items attempted, per-item results reported. Comments are TracWiki and are stored byte-for-byte.
ticket_changelogreadGet ticket change history. Use this to investigate who changed what and when. Comment content is returned as stored: TracWiki, byte-for-byte.
ticket_createwriteCreate a new ticket. The description is TracWiki and is stored byte-for-byte -- nothing is converted, so hand-authored markup survives exactly as written.
ticket_deletedestructiveDelete a ticket permanently. Warning: This cannot be undone. Requires TICKET_ADMIN permission and
ticket_fieldsreadGet all ticket field definitions (standard + custom fields). Returns field metadata including name, type, label, options (for select fields), and custom flag. Use to discover instance-specific ticket schema.
ticket_searchreadSearch tickets with filtering by status, owner, and keywords. Returns ticket IDs with summaries.
whoamireadReturn the in-flight request
wiki_createwriteCreate a new wiki page. Content is TracWiki and is stored byte-for-byte -- nothing is converted, so hand-authored markup survives exactly as written. Fails if the page exists (use wiki_update instead).
wiki_deletedestructiveDelete a wiki page. Warning: This cannot be undone. Requires WIKI_DELETE permission.
wiki_getreadGet wiki page content as stored: TracWiki, byte-for-byte. Returns full content with metadata (version, author, modified date).
wiki_get_historyreadGet wiki page revision history newest-first. Returns list of revisions with version, author, lastModified, and comment (commit message). Useful for detecting prior edits or scanning attribution markers in change comments.
wiki_recent_changesreadGet recently modified wiki pages. Returns pages sorted by modification date (newest first). Useful for finding stale or recently updated documentation.
wiki_searchreadSearch wiki pages by content with relevance ranking. Returns snippets showing matched text, as stored: TracWiki, byte-for-byte.
wiki_updatewriteUpdate an existing wiki page with optimistic locking (requires version for conflict detection). Content is TracWiki and is stored byte-for-byte -- nothing is converted, so hand-authored markup survives exactly as written.
04

Trust audit

BLOCKgrade D · trust 63/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
declared (10 observation(s))
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (25)

HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/agent_scenarios.py:342
server_args.append("--insecure")
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/agent_scenarios.py:493
"--insecure",
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
src/trac_mcp_server/mcp/server.py:500
"--insecure",
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
tests/fixtures/convert_preview/row01_intertrac_wiki.html:2
<a class="ext-link" href="http://192.168.10.4:8000/auto_pm/intertrac/wiki%3ARules/trac/RenderVerify" title="wiki:Rules/trac/RenderVerify in Automated Project Manager"><span class="icon"></span>auto_pm
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
tests/fixtures/convert_preview/row01_pre_fix.html:2
<a class="ext-link" href="http://192.168.10.4:8000/auto_pm/intertrac/wiki%3ARules/trac/%21RenderVerify" title="wiki:Rules/trac/!RenderVerify in Automated Project Manager"><span class="icon"></span>aut
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
tests/fixtures/convert_preview/row02_intertrac_wiki_bcs.html:2
<a class="ext-link" href="http://192.168.10.4:8000/bcs/intertrac/wiki%3Ab-node/bench/BoardIdentity" title="wiki:b-node/bench/BoardIdentity in Backyard Control System (b-node)"><span class="icon"></spa
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
tests/fixtures/convert_preview/row03_bracket_intertrac.html:2
<a class="ext-link" href="http://192.168.10.4:8000/auto_pm/intertrac/wiki%3APage" title="wiki:Page in Automated Project Manager"><span class="icon"></span>label</a>
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
tests/fixtures/convert_preview/row05_intertrac_index.html:2
<a class="ext-link" href="http://192.168.10.4:8000/auto_pm/intertrac/wiki%3AIndex" title="wiki:Index in Automated Project Manager"><span class="icon"></span>auto_pm:wiki:Index</a>
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
deploy.sh:79
resp="$(curl -sf "http://127.0.0.1:${port}/healthz")"
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
milestone_delete, ticket_batch_delete, ticket_delete, wiki_delete
Why it matters. 4 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
tests/test_config_bootstrap.py:563
server = yaml.load(
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/deployment.md:282
curl -s http://127.0.0.1:8080/healthz
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/deployment.md:290
claude mcp add --transport http trac http://127.0.0.1:8080/mcp \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/reference/cli.md:176
| `--url URL` | MCP endpoint, e.g. `http://192.0.2.10:8091/mcp` |
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/reference/http-transport.md:21
The endpoint must be reached at exactly the configured path (e.g. `http://127.0.0.1:8080/mcp`, no trailing slash) -- it is not a path *prefix*, so there is no redirect to `/mcp/`.
LOWNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/test_trac.py:2636
server_args.append("--insecure")
Why it matters. certificate verification is disabled
Fix. leave verification on
LOWNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/test_trac.py:2732
"--insecure",
Why it matters. certificate verification is disabled
Fix. leave verification on
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/trac_mcp_server/cli/client.py:409
data = base64.b64decode(_payload(result, "content_base64"))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/trac_mcp_server/core/client.py:270
return base64.b64decode(data_value or "")
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/trac_mcp_server/mcp/tools/file_io.py:162
data = base64.b64decode(encoded, validate=True)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/trac_mcp_server/mcp/tools/wiki_read.py:171
cursor_bytes = base64.b64decode(cursor.encode("utf-8"))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
tests/test_mcp/tools/test_file_io.py:305
base64.b64decode(result.structuredContent["content_base64"])
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
tests/test_mcp/tools/test_write_gate.py:101
'<span class="icon"></span>bcs:#99999</a> and also '
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/reference/http-transport.md:16
| `POST/GET/DELETE <path>` (default `/mcp`) | Yes, if `auth_token` is configured | The MCP JSON-RPC endpoint (streamable HTTP: `POST` for requests, `GET` for the SSE stream, `DELETE` to end a session)
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/reference/http-transport.md:19
Sessions are **stateful** (the SDK default): the server returns an `Mcp-Session-Id` response header on `initialize`, and clients send it back on subsequent requests. Each session gets its own MCP prot
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha e3af4997ffc7full audit observations/trust-audit/mcp-server/nerpatech__trac-mcp-server.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11e3af4997ffc7BLOCKD63first audit
06

Questions

What is the trac-mcp-server MCP server?

A MCP (Model Context Protocol) server that provides AI assistants with tools to interact with Trac project management instances — managing tickets, wiki pages, and milestones

What tools does trac-mcp-server expose?

25 in total: 14 read-only, 7 that write, and 4 that can delete or overwrite (milestone_delete, ticket_batch_delete, ticket_delete, wiki_delete). Every one is listed on this page with its risk.

Is trac-mcp-server safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (63/100) and found 8 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 4 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does trac-mcp-server need?

It reads TRAC_MCP_AUTH_TOKEN, TRAC_PASSWORD and TRAC_PASSWORD_2 from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does trac-mcp-server run?

It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as trac-mcp-server.

How current is this page?

The grade is for one exact copy of the source (e3af4997ffc7), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement