GITEA_MCP_TOKEN is defined in ~/.op-env (op://HomeLab) and authenticates against nothing:
https://koala.tail30472e.ts.net:8446/mcp (gitea-mcp via Tailscale Serve) → 401
https://git-mcp.d-ma.be/mcp (the public gitea-mcp hostname, from plugin 0.4.1's config) → 401
Meanwhile DMABE_GITEA_API_TOKEN returns 200 on both paths, because gitea-mcp is pass-through-authenticated (#33).
So the variable is dead weight with an actively misleading name: it reads as the credential for gitea-mcp, and it is the first thing anyone reaches for. It cost time today during an unrelated MCP investigation.
To decide: is the underlying 1Password item a revoked Gitea PAT, or a static token for some other consumer? If nothing consumes it, revoke the item and drop the line from ~/.op-env. If something does, rename it after that consumer.
Note bin/check-mcp-env (v0.19.0) cannot catch this class — it verifies a variable is defined, not that its value still authenticates. That is deliberate: checking values would mean sending credentials from a gate. The gap is real and worth stating rather than closing.
`GITEA_MCP_TOKEN` is defined in `~/.op-env` (`op://HomeLab`) and authenticates against nothing:
- `https://koala.tail30472e.ts.net:8446/mcp` (gitea-mcp via Tailscale Serve) → **401**
- `https://git-mcp.d-ma.be/mcp` (the public gitea-mcp hostname, from plugin 0.4.1's config) → **401**
Meanwhile `DMABE_GITEA_API_TOKEN` returns 200 on both paths, because gitea-mcp is pass-through-authenticated (#33).
So the variable is dead weight with an actively misleading name: it reads as *the* credential for gitea-mcp, and it is the first thing anyone reaches for. It cost time today during an unrelated MCP investigation.
**To decide:** is the underlying 1Password item a revoked Gitea PAT, or a static token for some other consumer? If nothing consumes it, revoke the item and drop the line from `~/.op-env`. If something does, rename it after that consumer.
Note `bin/check-mcp-env` (v0.19.0) cannot catch this class — it verifies a variable is *defined*, not that its value still authenticates. That is deliberate: checking values would mean sending credentials from a gate. The gap is real and worth stating rather than closing.
The issue asked whether the underlying item is a revoked PAT or a live token for some other consumer. It is neither — nothing reads it. Every k8s workload sources a different item:
dispatch/externalsecret.yaml:21 even carries the history: "infra#345: was key: GITEA_MCP_TOKEN, a separate HomeLab item that…" — so the migration away from it already happened and the HomeLab item was left behind.
The two remaining key: GITEA_MCP_TOKEN hits (credential-probe-cronjob.yaml:114, agent-runner/deployment.yaml:79) are secretKeyRef.key — the key inside the k8s Secret, whose value comes from gitea-mcp-shared-token. Not the 1Password item.
Done here
Dropped the line from ~/.op-env (48 → 47 lines, backup at ~/.op-env.bak-2026-09-28), and confirmed op run still resolves everything else.
One thing worth knowing
The variable is also exported in the ambient session shell — not from ~/.op-env, and not from .zshrc/.zshenv/.profile. So it survives in running shells until they restart, which is how a dead credential keeps being the first thing anyone reaches for. It clears on the next shell.
Left open, because it is yours
Revoke the 1Password item. HomeLab is the user-governed vault, and scripts/op-safe.sh (just shipped, local-dev#32) deliberately has no delete — a read-safety wrapper is the wrong place for destructive vault operations.
Worth folding into the same pass as infra#445, since that is already a queued credential session. This issue closes when the item is revoked.
Note the issue's own closing observation still stands and is worth keeping: bin/check-mcp-env verifies a variable is defined, never that it still authenticates, and closing that gap would mean sending credentials from a gate. The check above is the manual version — cheap, and only safe because it prints nothing but a status code.
## Verified still true, and the "to decide" is now answered
Checked by side-effect rather than by reading values — status codes only, per the `secret-hygiene` skill:
```
GITEA_MCP_TOKEN -> 401 https://git-mcp.d-ma.be/mcp
DMABE_GITEA_API_TOKEN -> 200 https://git-mcp.d-ma.be/mcp
GITEA_MCP_TOKEN -> 401 https://koala.tail30472e.ts.net:8446/mcp
DMABE_GITEA_API_TOKEN -> 200 https://koala.tail30472e.ts.net:8446/mcp
```
Unchanged since filing, 21 days on.
## Nothing consumes the 1Password item
The issue asked whether the underlying item is a revoked PAT or a live token for some other consumer. It is neither — **nothing reads it.** Every k8s workload sources a *different* item:
```
k3s/apps/gitea-mcp/gitea-mcp-static-token-externalsecret.yaml key: gitea-mcp-shared-token
k3s/apps/agentsquad-serve/gitea-mcp-token-externalsecret.yaml key: gitea-mcp-shared-token
k3s/apps/agent-runner/gitea-mcp-token-externalsecret.yaml key: gitea-mcp-shared-token
k3s/apps/dispatch/externalsecret.yaml key: gitea-mcp-shared-token
```
`dispatch/externalsecret.yaml:21` even carries the history: *"infra#345: was `key: GITEA_MCP_TOKEN`, a separate HomeLab item that…"* — so the migration away from it already happened and the HomeLab item was left behind.
The two remaining `key: GITEA_MCP_TOKEN` hits (`credential-probe-cronjob.yaml:114`, `agent-runner/deployment.yaml:79`) are `secretKeyRef.key` — the key *inside* the k8s Secret, whose value comes from `gitea-mcp-shared-token`. Not the 1Password item.
## Done here
Dropped the line from `~/.op-env` (48 → 47 lines, backup at `~/.op-env.bak-2026-09-28`), and confirmed `op run` still resolves everything else.
## One thing worth knowing
The variable is *also* exported in the ambient session shell — not from `~/.op-env`, and not from `.zshrc`/`.zshenv`/`.profile`. So it survives in running shells until they restart, which is how a dead credential keeps being the first thing anyone reaches for. It clears on the next shell.
## Left open, because it is yours
**Revoke the 1Password item.** HomeLab is the user-governed vault, and `scripts/op-safe.sh` (just shipped, `local-dev#32`) deliberately has no `delete` — a read-safety wrapper is the wrong place for destructive vault operations.
Worth folding into the same pass as `infra#445`, since that is already a queued credential session. This issue closes when the item is revoked.
Note the issue's own closing observation still stands and is worth keeping: `bin/check-mcp-env` verifies a variable is *defined*, never that it still authenticates, and closing that gap would mean sending credentials from a gate. The check above is the manual version — cheap, and only safe because it prints nothing but a status code.
---
_Created via git-mcp on behalf of @mathias_
Item deleted from 1Password 2026-09-29. Verified nothing broke — by side-effect, not by assertion.
op-safe shape HomeLab GITEA_MCP_TOKEN → read failed (item gone)
op-safe shape HomeLab DMABE_GITEA_API_TOKEN → present (41 chars) ← control: the tooling still works
DMABE_GITEA_API_TOKEN → 200 https://git-mcp.d-ma.be/mcp
DMABE_GITEA_API_TOKEN → 200 https://koala.tail30472e.ts.net:8446/mcp
skills: check OK — 45 skills, manifest matches tag
check-mcp-env: 2 interpolated variables, all defined
Both MCP paths re-tested after the deletion:
pluginmcp__plugin_skills_gitea__* — this comment was posted with it
claude.ai connectormcp__claude_ai_gitea__* — repo_get returned live data
The control item matters more than the failure: op-safe erroring on a deleted item proves nothing on its own, since a broken op would look identical. A live item resolving in the same breath is what makes the first result mean something.
What the investigation actually found
The issue asked whether the underlying item was a revoked PAT or a live token for another consumer. Neither — nothing read it. Every k8s workload sources gitea-mcp-shared-token; dispatch/externalsecret.yaml:21 even carries the migration note ("infra#345: was key: GITEA_MCP_TOKEN…"), so the move happened long ago and the item was simply left behind.
The only config mentioning it was a _comment in skills/.mcp.jsondocumenting that it 401s — the header itself uses ${DMABE_GITEA_API_TOKEN}, because gitea-mcp is pass-through-authenticated and validates any real Gitea PAT.
Mathias raised the one thing I had not checked: the claude.ai connector, stored server-side where I cannot read it. Resolved by calling it — it works, and since GITEA_MCP_TOKEN 401s against that same endpoint it cannot have been using it.
Left standing, deliberately
The issue's own closing observation: bin/check-mcp-env verifies a variable is defined, never that its value still authenticates, and closing that gap would mean sending credentials from a gate. The four-line status-code check used here is the manual version — safe only because it prints nothing but an HTTP code.
That is a real limit of the estate's tooling and is worth keeping visible rather than closing over.
**Item deleted from 1Password 2026-09-29. Verified nothing broke — by side-effect, not by assertion.**
```
op-safe shape HomeLab GITEA_MCP_TOKEN → read failed (item gone)
op-safe shape HomeLab DMABE_GITEA_API_TOKEN → present (41 chars) ← control: the tooling still works
DMABE_GITEA_API_TOKEN → 200 https://git-mcp.d-ma.be/mcp
DMABE_GITEA_API_TOKEN → 200 https://koala.tail30472e.ts.net:8446/mcp
skills: check OK — 45 skills, manifest matches tag
check-mcp-env: 2 interpolated variables, all defined
```
Both MCP paths re-tested **after** the deletion:
- **plugin** `mcp__plugin_skills_gitea__*` — this comment was posted with it
- **claude.ai connector** `mcp__claude_ai_gitea__*` — `repo_get` returned live data
The control item matters more than the failure: `op-safe` erroring on a deleted item proves nothing on its own, since a broken `op` would look identical. A live item resolving in the same breath is what makes the first result mean something.
## What the investigation actually found
The issue asked whether the underlying item was a revoked PAT or a live token for another consumer. **Neither — nothing read it.** Every k8s workload sources `gitea-mcp-shared-token`; `dispatch/externalsecret.yaml:21` even carries the migration note (*"infra#345: was `key: GITEA_MCP_TOKEN`…"*), so the move happened long ago and the item was simply left behind.
The only config mentioning it was a `_comment` in `skills/.mcp.json` **documenting that it 401s** — the header itself uses `${DMABE_GITEA_API_TOKEN}`, because gitea-mcp is pass-through-authenticated and validates any real Gitea PAT.
Mathias raised the one thing I had not checked: the claude.ai connector, stored server-side where I cannot read it. Resolved by calling it — it works, and since `GITEA_MCP_TOKEN` 401s against that same endpoint it cannot have been using it.
## Left standing, deliberately
The issue's own closing observation: `bin/check-mcp-env` verifies a variable is **defined**, never that its value still authenticates, and closing that gap would mean sending credentials from a gate. The four-line status-code check used here is the manual version — safe only because it prints nothing but an HTTP code.
That is a real limit of the estate's tooling and is worth keeping visible rather than closing over.
---
_Created via git-mcp on behalf of @mathias_
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
GITEA_MCP_TOKENis defined in~/.op-env(op://HomeLab) and authenticates against nothing:https://koala.tail30472e.ts.net:8446/mcp(gitea-mcp via Tailscale Serve) → 401https://git-mcp.d-ma.be/mcp(the public gitea-mcp hostname, from plugin 0.4.1's config) → 401Meanwhile
DMABE_GITEA_API_TOKENreturns 200 on both paths, because gitea-mcp is pass-through-authenticated (#33).So the variable is dead weight with an actively misleading name: it reads as the credential for gitea-mcp, and it is the first thing anyone reaches for. It cost time today during an unrelated MCP investigation.
To decide: is the underlying 1Password item a revoked Gitea PAT, or a static token for some other consumer? If nothing consumes it, revoke the item and drop the line from
~/.op-env. If something does, rename it after that consumer.Note
bin/check-mcp-env(v0.19.0) cannot catch this class — it verifies a variable is defined, not that its value still authenticates. That is deliberate: checking values would mean sending credentials from a gate. The gap is real and worth stating rather than closing.Verified still true, and the "to decide" is now answered
Checked by side-effect rather than by reading values — status codes only, per the
secret-hygieneskill:Unchanged since filing, 21 days on.
Nothing consumes the 1Password item
The issue asked whether the underlying item is a revoked PAT or a live token for some other consumer. It is neither — nothing reads it. Every k8s workload sources a different item:
dispatch/externalsecret.yaml:21even carries the history: "infra#345: waskey: GITEA_MCP_TOKEN, a separate HomeLab item that…" — so the migration away from it already happened and the HomeLab item was left behind.The two remaining
key: GITEA_MCP_TOKENhits (credential-probe-cronjob.yaml:114,agent-runner/deployment.yaml:79) aresecretKeyRef.key— the key inside the k8s Secret, whose value comes fromgitea-mcp-shared-token. Not the 1Password item.Done here
Dropped the line from
~/.op-env(48 → 47 lines, backup at~/.op-env.bak-2026-09-28), and confirmedop runstill resolves everything else.One thing worth knowing
The variable is also exported in the ambient session shell — not from
~/.op-env, and not from.zshrc/.zshenv/.profile. So it survives in running shells until they restart, which is how a dead credential keeps being the first thing anyone reaches for. It clears on the next shell.Left open, because it is yours
Revoke the 1Password item. HomeLab is the user-governed vault, and
scripts/op-safe.sh(just shipped,local-dev#32) deliberately has nodelete— a read-safety wrapper is the wrong place for destructive vault operations.Worth folding into the same pass as
infra#445, since that is already a queued credential session. This issue closes when the item is revoked.Note the issue's own closing observation still stands and is worth keeping:
bin/check-mcp-envverifies a variable is defined, never that it still authenticates, and closing that gap would mean sending credentials from a gate. The check above is the manual version — cheap, and only safe because it prints nothing but a status code.Created via git-mcp on behalf of @mathias
Item deleted from 1Password 2026-09-29. Verified nothing broke — by side-effect, not by assertion.
Both MCP paths re-tested after the deletion:
mcp__plugin_skills_gitea__*— this comment was posted with itmcp__claude_ai_gitea__*—repo_getreturned live dataThe control item matters more than the failure:
op-safeerroring on a deleted item proves nothing on its own, since a brokenopwould look identical. A live item resolving in the same breath is what makes the first result mean something.What the investigation actually found
The issue asked whether the underlying item was a revoked PAT or a live token for another consumer. Neither — nothing read it. Every k8s workload sources
gitea-mcp-shared-token;dispatch/externalsecret.yaml:21even carries the migration note ("infra#345: waskey: GITEA_MCP_TOKEN…"), so the move happened long ago and the item was simply left behind.The only config mentioning it was a
_commentinskills/.mcp.jsondocumenting that it 401s — the header itself uses${DMABE_GITEA_API_TOKEN}, because gitea-mcp is pass-through-authenticated and validates any real Gitea PAT.Mathias raised the one thing I had not checked: the claude.ai connector, stored server-side where I cannot read it. Resolved by calling it — it works, and since
GITEA_MCP_TOKEN401s against that same endpoint it cannot have been using it.Left standing, deliberately
The issue's own closing observation:
bin/check-mcp-envverifies a variable is defined, never that its value still authenticates, and closing that gap would mean sending credentials from a gate. The four-line status-code check used here is the manual version — safe only because it prints nothing but an HTTP code.That is a real limit of the estate's tooling and is worth keeping visible rather than closing over.
Created via git-mcp on behalf of @mathias