13 Commits

Author SHA1 Message Date
sysadmin 0e2840b76c Merge pull request 'Release v1.1.0' (#64) from chore/issue-63-v1.1.0 into master 2026-07-02 14:48:34 -05:00
sysadmin d8269fc704 chore: add #73/#76/#79/#80 docs merges to v1.1.0 release notes (#63)
Master moved during release prep: PRs #89 (#79), #90 (#80), #92 (#76), and
#93 (#73) merged. Sync the branch with master (ba6064e) and record all four
in the v1.1.0 Documentation section. CHANGELOG.md only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 15:47:32 -04:00
sysadmin 0d6d31d341 Merge remote-tracking branch 'prgs/master' into chore/issue-63-v1.1.0 2026-07-02 15:46:45 -04:00
jcwalker3 ba6064e51e Merge pull request 'docs: extend profile model for multi-service MCP boundaries (#76)' (#92) from docs/issue-76-multi-service-profile-model into master 2026-07-02 14:44:35 -05:00
jcwalker3 fac10dd6cc docs: GlitchTip read-only error/event tools design (#73) (#93)
Co-authored-by: jcwalker3 <jcwalker3@yahoo.com>
Co-committed-by: jcwalker3 <jcwalker3@yahoo.com>
2026-07-02 14:27:09 -05:00
sysadmin 0cdbf63660 chore: refresh v1.1.0 release notes with all work merged since v1.0.1 (#63)
Merge current master (4f5b732) into the release branch and expand the
CHANGELOG v1.1.0 section to cover every merge since the v1.0.1 tag:
identity/eligibility tooling (#9, #11, #13, #14), gated review/merge
workflows (#15, #16), execution profiles (#12, #19), audit logging (#18),
Retry-After backoff (#27), API pagination + failure handling (#67),
release-tag helper (#50), status:in-progress automation (#56, #58),
LLM-Agent-SHA Phase 0 (#86), provenance helper (#3), manage_labels modes
(#6), and documentation (#8, #70, #72, #77).

PRs #82 (#68 release SOP) and #84 (#69 Linux portability) were closed
without merging and are intentionally NOT listed.

No feature code changed; CHANGELOG.md only. No tag created.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 15:22:52 -04:00
sysadmin 6f9699b51a docs: extend profile model for multi-service MCP boundaries (#76) 2026-07-02 15:22:43 -04:00
sysadmin 58e4bcd157 docs: propose labels for Jenkins/GlitchTip workflow (#80) (#90)
Co-authored-by: Jason Walker <913443@dadeschools.net>
Co-committed-by: Jason Walker <913443@dadeschools.net>
2026-07-02 14:21:58 -05:00
sysadmin 0a61e8a92d docs: update safety and boundary docs for Jenkins/GlitchTip (#79) (#89)
Co-authored-by: Jason Walker <913443@dadeschools.net>
Co-committed-by: Jason Walker <913443@dadeschools.net>
2026-07-02 14:21:49 -05:00
sysadmin fd68c439b2 Merge branch 'master' into chore/issue-63-v1.1.0 2026-07-02 15:21:22 -04:00
sysadmin 4f5b732741 Merge pull request 'docs: Jenkins repo/branch/PR to job mapping design (#77)' (#91) from docs/issue-77-jenkins-job-mapping-design into master 2026-07-02 14:15:58 -05:00
sysadmin 1bc2f20623 docs: Jenkins repo/branch/PR to job mapping design (#77)
Add docs/architecture/jenkins-job-mapping-design.md: declarative versioned
mapping config (exact-match repo/branch entries, no globs, fail-closed load
on malformed/duplicate entries), resolution semantics for multibranch/
single/parameterized-view job types with URL-encoded branch and PR-<n>
addressing, branch-pinned-over-repo-wide precedence, fork PRs resolving via
base repo only, explicit machine-checkable no-match payload (never guess or
probe job names), config location in the jenkins-mcp package (no secrets,
env-overridable path), a read-only jenkins_resolve_job tool surface, and a
mocked-config/mocked-Jenkins testing strategy.

Design only; no implementation, no code behavior changed, no Jenkins write
actions introduced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:09:48 -04:00
sysadmin afa57fa65c chore: version bump and release notes for v1.1.0 (fixes #63) 2026-07-02 06:29:49 -04:00
8 changed files with 493 additions and 2 deletions
+41
View File
@@ -0,0 +1,41 @@
# Changelog
All notable changes to this project will be documented in this file.
## [v1.1.0] - 2026-07-02
### Added
- Read-only identity and eligibility tooling: `gitea_whoami` authenticated-user lookup (#11), `gitea_get_profile` runtime-profile discovery (#13), and `gitea_check_pr_eligibility` fail-closed PR eligibility checks (#14).
- Identity lookup aliases (`gitea_get_authenticated_user` and `gitea_get_current_user`) for common MCP/LLM tool discovery (#9).
- Gated PR review actions (`gitea_submit_pr_review`) reusing the eligibility gates (#15).
- Gated PR merge workflow (`gitea_merge_pr`) with explicit `MERGE PR <n>` confirmation, head-SHA and changed-file pinning, and self-merge blocking as the only merge path (#16).
- Task-scoped Gitea MCP execution profiles: documented profile model (#12) and runtime profiles via environment config with `allowed_operations` (#19).
- Audit logging for all mutating MCP actions with execution-profile metadata and secret redaction (#18).
- Shared API pagination (`api_get_all`) and hardened failure handling in `gitea_auth.api_request`: request timeouts, clear network/DNS errors, explicit 502/503/504 upstream errors, malformed-JSON handling, and redacted error text (#67).
- `scripts/release-tag` SemVer-gated annotated-tag helper (safe-by-default, master-only, tests required) (#50).
- Automatic `status:in-progress` release on issue close and PR close/merge (#56, #58).
- `LLM-Agent-SHA` opaque agent attribution convention (Phase 0): documentation, handoff/review templates, and negative tests proving the SHA can never bypass self-review/self-merge gates (#86).
- macOS `com.apple.provenance` cleanup helper tool and documentation (#3).
- `manage_labels.py` refactored into reusable modes (`--create-labels`, `--apply-mapping`, `--add-label`) (#6).
### Changed
- HTTP 429 responses now honor `Retry-After` with jittered exponential backoff (#27).
- Read-only list tools (`gitea_list_issues`, `gitea_list_prs`, `gitea_list_labels`) now paginate across pages with bounded page caps (#67).
- Automatic `status:in-progress` cleanup on issue/PR close and merge.
- Label cleanup now utilizes safe targeted label deletion behavior rather than replacing the entire label set.
### Documentation
- MCP security model and trust-boundary documentation (#8).
- Developer testing guidelines (#70).
- Jenkins read-only build-status tools design (#72).
- Jenkins repo/branch/PR → job mapping design (#77).
- Safety and boundary docs updated for Jenkins/GlitchTip: `glitchtip-mcp` boundary, read-only-first policy, mutation gating (#79).
- Proposed label taxonomy for Jenkins/GlitchTip workflows (#80).
- GlitchTip read-only error/event tools design (#73).
- Multi-service MCP profile model extension (#76).
## [v1.0.1]
- Fix Recent Timesheets Remove button text clipping and copy theme/whats_new in build.
## [v1.0.0]
- Initial versioned release.
@@ -0,0 +1,174 @@
# GlitchTip Read-Only Error/Event Tools — Design Notes
- **Status:** Design (implementation-ready notes; **no implementation in this repo**)
- **Issue:** #73 (umbrella: #75; boundary decision: ADR-0001, #71)
- **Related:** #74 (GlitchTip→Gitea filing workflow — composes these read tools),
#78 (dedup/linking, child of #74), #76 (per-service profile schema)
- **Date:** 2026-07-02
## 1. Purpose and scope
Define the minimum **read-only** GlitchTip MCP tool set that lets an LLM answer:
*"What unresolved errors does project X have (by environment/release), and what
is this specific error?"* — with privacy-safe output suitable for LLM context,
issue bodies, and audit logs.
Strictly read-only, per ADR-0001:
- **No mutation tools** — no resolving/ignoring/assigning issues, no comment
posting, no project/team/key administration, no deletes.
- **No automatic GlitchTip→Gitea filing** (that is #74's *orchestrated,
explicitly-invoked* workflow; it composes these read tools and Gitea write
tools — never one dual-credential server).
- **This server never holds Gitea write credentials.**
## 2. Boundary placement (namespace pending)
These tools belong to the GlitchTip observability boundary of the MCP Control
Plane — `glitchtip-mcp` (ADR-0001's recommendation), `observability-mcp`, or
folded into `ops-mcp`. **ADR-0001 open owner decision #2 picks the name; this
design does not assume it.** Tool names below use the `glitchtip_` prefix for
readability and rename mechanically with the decision.
Fixed regardless of the name (per `tool-boundaries.md`,
`credential-isolation.md`):
- Own server process, own `.env`, GlitchTip credentials only.
- No Gitea, Jenkins, or Ops tokens in this runtime; no GlitchTip token
anywhere else.
## 3. API surface note (Sentry compatibility)
GlitchTip implements a Sentry-compatible REST API (`/api/0/...` — organizations,
projects, issues, events). The design targets **GlitchTip's documented subset**
only; Sentry-only endpoints must not be assumed. The implementation should pin
against a tested GlitchTip version and treat missing endpoints/fields as
degraded-but-safe (omit field, never crash).
## 4. Minimum read-only tool set
| Tool | Purpose |
|---|---|
| `glitchtip_whoami` | Verify authenticated identity + active profile (mirror of `gitea_whoami`; fail-closed identity proof) |
| `glitchtip_list_projects` | Projects visible to the token (org-scoped), with pagination bounds |
| `glitchtip_list_unresolved` | Unresolved issues for a project, filterable (§6), sorted by last-seen |
| `glitchtip_get_issue` | Safe detail of one issue (fields §5) |
| `glitchtip_recent_events` | Recent events for an issue (summaries only, §5) |
| `glitchtip_search` | Issue search within a project (query + filters §6) |
All tools are `GET`-only. No tool issues PUT/POST/DELETE.
## 5. Privacy: field-level allowlist (the core rule)
Error events routinely contain PII and secrets (request bodies, cookies,
headers, tokens, user emails/IPs, local variables). Therefore: **allowlist
projection only — raw event/issue payloads are never passed through.**
### Issue-level safe fields (`glitchtip_list_unresolved`, `glitchtip_get_issue`, `glitchtip_search`)
| Field | Notes |
|---|---|
| `issue_id` | GlitchTip issue ID (dedup key for #78) |
| `fingerprint` | When available (dedup key for #78) |
| `title` / `culprit` | Error type + short message/transaction — redactor-passed |
| `project` | Slug |
| `level` | error/warning/… |
| `status` | unresolved/… |
| `environment` | When filtered/available |
| `release` | Version string |
| `first_seen` / `last_seen` | ISO-8601 UTC |
| `event_count` / `user_count` | Numbers only — never user identities |
| `permalink` | GlitchTip web URL (the "link, not dump" principle) |
### Event-level safe fields (`glitchtip_recent_events`)
`event_id`, `timestamp`, `level`, `environment`, `release`, redactor-passed
`message`, and a **stack summary** only: top N (default 5) frames as
`module/filename:function:line` — in-app frames preferred.
### Redact / omit — never returned
Request headers; cookies; auth/session fields; user emails, usernames, IPs;
request/form bodies; query strings; local variables; full raw stack frames
(source context lines); SDK/device metadata beyond platform name; breadcrumbs;
any `extra`/`context` blobs.
Full raw frames or request context require a **separate, explicitly approved**
operation (`glitchtip.event.read_raw`) that is absent from default profiles —
same pattern as `jenkins.console.read` in the #72 design. Even then, output
passes the shared secret redactor; redaction failure ⇒ error, never raw text.
**Default output = fingerprint / release / summary + permalink.** The
permalink carries the human to the full data in GlitchTip's own UI, where its
access control applies — the MCP layer does not re-serve raw payloads.
## 6. Filtering and pagination
Filters (all optional, combinable): `project` (required for issue/event
queries), `environment`, `release`, `fingerprint`, free-text `query`
(GlitchTip search syntax, e.g. `is:unresolved`).
Pagination: cursor-based per the API. Bounds: per-page cap 50; default overall
cap 100 items; hard cap `max_pages` (default 10) against runaway loops —
mirroring `gitea_auth.api_get_all`. Truncation is **explicit** in the return
(`"truncated": true`) — never silent.
## 7. Credentials and profile requirements
Per-service profile model (`gitea-execution-profiles.md`, extended by #76):
- Env/config: `GLITCHTIP_URL`, `GLITCHTIP_ORG`, `GLITCHTIP_TOKEN_SOURCE_NAME`
(secret **name** only; value resolved at runtime, never logged/committed).
- Profile: e.g. `glitchtip-readonly` with namespaced
`allowed_operations: ["glitchtip.read", "glitchtip.event.read"]`
(+ `glitchtip.event.read_raw` only with explicit approval);
`forbidden_operations: ["glitchtip.issue.mutate", "glitchtip.admin"]`
belt-and-braces though no mutating tool exists.
- Missing URL/org/token/profile ⇒ **fail closed** before any network call.
- Read-only ⇒ no confirmation gates; identity (`glitchtip_whoami`) must work so
workflows can prove which account they read as.
## 8. Failure behavior (fail closed, clear, safe)
| Condition | Behavior |
|---|---|
| Unknown project/issue | Explicit `{"found": false, ...}` — no fuzzy matching |
| GlitchTip unreachable (DNS/timeout) | `"network error contacting GlitchTip: <redacted reason>"` — mirror `gitea_auth.api_request` conversion |
| 502/503/504 | "GlitchTip upstream unavailable" |
| 401/403 | "GlitchTip auth failed / insufficient permissions" — no credential echo |
| 429 | Honor Retry-After with capped jittered backoff (as `gitea_auth`) |
| Malformed JSON | "malformed JSON response from GlitchTip" — no raw-body dump |
| Missing profile/creds | Fail closed before any network call (§7) |
All error text passes the shared secret redactor.
## 9. Testing strategy (mocked; for the implementing package)
Mocked-GlitchTip unit tests only, per `docs/developer-testing-guidelines.md`:
- Assert method is always `GET`; URL/filter/cursor shape correct.
- **Projection tests:** response fixtures containing emails, IPs, cookies,
headers, request bodies, locals, full frames ⇒ none appear in output
(explicit negative assertions per §5's redact list).
- Stack summary: top-N frame cap enforced; source-context lines absent.
- Pagination: per-page/overall/max-pages caps; explicit `truncated` flag.
- Filters: environment/release/fingerprint/query passed through correctly.
- Failure matrix of §8 incl. no-token-in-error assertions.
- Profile gate: missing/insufficient profile ⇒ no network call
(`mock_api.assert_not_called()` pattern).
- `read_raw` op absent ⇒ raw-frame request refused without an API call.
## 10. Implementation-readiness checklist
Ready to implement once:
1. ADR-0001 owner decision #2 (namespace/placement) is made — mechanical
rename of the `glitchtip_` prefix if needed.
2. ADR-0001 owner decision #1 (repo home) is made.
3. #76 profile schema exists (or a minimal `glitchtip-readonly` profile is
hand-rolled to the same rules).
4. A pinned GlitchTip version is chosen for API-subset testing (§3).
Explicitly **not** unlocked by this document: any GlitchTip mutation, any
automatic Gitea filing (#74 designs that as a gated, explicitly-invoked
orchestrated workflow), any Gitea credentials in this boundary.
@@ -0,0 +1,165 @@
# Jenkins Repo/Branch/PR → Job Mapping — Design Notes
- **Status:** Design (implementation-ready notes; **no implementation in this repo**)
- **Issue:** #77 (parent: #72 read-only tools design; umbrella: #75; boundary: ADR-0001, #71)
- **Related docs:** [`jenkins-readonly-build-status-design.md`](jenkins-readonly-build-status-design.md)
- **Date:** 2026-07-02
## 1. Purpose
The #72 tool set addresses Jenkins jobs by **explicit fully-qualified job
path**. This document designs the layer above it: how a *(repository, branch,
PR)* tuple — the vocabulary of Gitea workflows — resolves deterministically to
a Jenkins job path, so an LLM can ask "did the build for `Gitea-Tools`
`master` pass?" without knowing Jenkins internals.
Hard constraints inherited from #72 / ADR-0001:
- **No silent guessing of job names.** Unmapped input returns an explicit
"no mapping" result — never a fuzzy match, never a constructed-and-probed
name.
- **Read-only.** Mapping introduces no Jenkins write actions.
- Lives in the **`jenkins-mcp`** boundary; no Gitea credentials involved.
## 2. Mapping format
Declarative, versioned config (TOML or JSON — match whatever config format
`jenkins-mcp` adopts; illustrated here as TOML):
```toml
version = 1
[[mapping]]
# Source side (what the caller supplies)
repo = "Scaled-Tech-Consulting/Gitea-Tools" # org/repo, exact
# Target side (where it lives in Jenkins)
job = "scaled-tech/gitea-tools" # foldered job path
type = "multibranch" # "multibranch" | "single" | "parameterized-view"
[[mapping]]
repo = "Scaled-Tech-Consulting/Timesheet"
branch = "master" # optional: branch-specific override
job = "scaled-tech/timesheet-master"
type = "single"
```
Field semantics:
| Field | Required | Meaning |
|---|---|---|
| `repo` | yes | Exact `org/repo` (case-insensitive compare, stored canonical) |
| `branch` | no | Exact branch name this entry pins; absent = all branches |
| `job` | yes | Fully-qualified Jenkins job path, folders `/`-joined |
| `type` | yes | How branch/PR resolves under the job (§3) |
Rules:
- **Exact matching only** on `repo` and `branch`. No globs in v1 (globs invite
accidental over-matching; add later behind an explicit `pattern = true` flag
if ever needed).
- Unknown `type` or malformed entry ⇒ config load fails closed with a clear
error naming the entry — a broken mapping file must not half-load.
- Duplicate `(repo, branch)` keys ⇒ load error (ambiguity is refused, not
resolved).
## 3. Resolution semantics by job type
Given caller input `(repo, branch?, pr?)`:
- **`multibranch`** — branch job addressed as `<job>/<url-encoded-branch>`
(e.g. `feature/x``feature%2Fx`). PRs addressed as `<job>/PR-<number>`
(Jenkins multibranch PR-discovery naming). Both per #72 §8.
- **`single`** — the job path is used as-is; `branch`/`pr` input beyond the
entry's pinned branch is a **no-mapping** result (a single job cannot answer
for arbitrary branches).
- **`parameterized-view`** — read-only variant for jobs that encode branch as
a build parameter: resolution returns the base job path plus a
`branch_param` filter hint the status tools may apply client-side when
scanning recent builds. It never triggers anything (read-only rule).
## 4. Precedence
Most-specific entry wins, evaluated in this order:
1. `(repo, branch)` exact entry — branch-pinned override.
2. `(repo)` entry — repo-wide (multibranch typical).
3. Nothing → **no mapping** (§5).
PR input resolves through the same chain: a PR belongs to its **base repo**'s
mapping; forks never introduce their own mapping (a fork's head repo is not
consulted — CI runs live under the base repo's job). If the base repo is
unmapped, the PR is unmapped.
Ties are impossible by construction (duplicate keys refused at load).
## 5. No-match behavior
```json
{
"mapped": false,
"repo": "org/unknown-repo",
"branch": "master",
"error": "no Jenkins job mapping for this repo/branch",
"hint": "add an entry to the jenkins-mcp mapping config"
}
```
- Deterministic, explicit, machine-checkable (`mapped: false`).
- **Never** falls back to name construction ("repo name probably equals job
name"), never probes Jenkins for candidates, never string-similarity ranks.
- The hint names the config, not a guessed job.
## 6. Where the mapping config lives
- **In the `jenkins-mcp` package/deployment** (e.g. `jenkins-mcp/mapping.toml`),
version-controlled next to the server that consumes it — *not* in Gitea-Tools
and *not* in per-user env vars (mappings are shared team facts, not
credentials).
- Path overridable via env (`JENKINS_MCP_MAPPING_FILE`) for tests/containers.
- Contains **no secrets** — job paths and repo names only — so it is safe to
commit and review like any other config.
- Reloaded at server start; a hot-reload tool is out of scope (restart is the
documented path).
## 7. Exposed tool surface (read-only)
One addition to the #72 tool set:
| Tool | Purpose |
|---|---|
| `jenkins_resolve_job` | `(repo, branch?, pr?)``{mapped, job, addressed_path, type}` or the §5 no-match result. Pure config lookup — **no Jenkins API call at all.** |
Status tools (`jenkins_latest_build` etc.) accept either an explicit job path
(as designed in #72) **or** `(repo, branch)` which they resolve via the same
mapping layer first. Resolution failure surfaces the §5 payload rather than
querying Jenkins.
## 8. Testing strategy (mocked; for the implementing package)
Config-layer tests (no network at all):
- Exact-match hit: repo-wide and branch-pinned entries.
- Precedence: branch-pinned beats repo-wide.
- Multibranch encoding: `feature/x``<job>/feature%2Fx`; PR → `<job>/PR-7`.
- `single` type with non-pinned branch ⇒ no-mapping.
- Fork PR resolves through base repo; unmapped base ⇒ no-mapping.
- Unknown repo/branch ⇒ §5 payload, and **no Jenkins client call**
(`mock_api.assert_not_called()`).
- Malformed config / duplicate keys / unknown type ⇒ load fails closed with
entry-naming error.
- No-secret check: mapping load/error paths never touch or print credentials.
Integration with mocked Jenkins API (per #72 §9): resolved path is used
verbatim in the GET URL; no write verbs anywhere.
## 9. Standalone-worthiness and readiness
#77 was split from #72 on the condition it stays "standalone only if mapping
is nontrivial." The precedence rules, fork/PR semantics, three job types, and
fail-closed config loading above are the nontrivial part; this document is the
justification.
Ready to implement in `jenkins-mcp` when #72's readiness checklist clears
(ADR-0001 owner decision #1; profile schema per #76 or hand-rolled
`jenkins-readonly`). Nothing here unlocks build triggers, deploys, or
parameterized launches.
@@ -0,0 +1,68 @@
# Multi-Service MCP Profile and Configuration Model
- **Status:** Design (no implementation in this repo yet)
- **Issue:** #76 (parent umbrella: #75; boundary decision: ADR-0001, #71)
- **Date:** 2026-07-02
## 1. Purpose and Scope
Extend the existing Gitea execution-profile model (`docs/gitea-execution-profiles.md`) into a generic **per-service** MCP profile/config model. This supports integrating Jenkins and GlitchTip into the MCP Control Plane while strictly preserving isolation and fail-closed safety.
**Crucial Constraints:**
* The shared profile/config model is a **schema / library**, **not a shared credential pool**.
* Tokens remain **service-local**; profiles are **per service**.
* Orchestrators **must not** directly hold every service credential.
## 2. Profile Schema (Per Service)
The schema reuses the proven Gitea field model, adapted per service.
```json
{
"profile_name": "readonly-metrics",
"service": "glitchtip",
"token_source_name": "GLITCHTIP_API_TOKEN_READONLY",
"allowed_operations": [
"glitchtip.event.read",
"glitchtip.issue.read"
],
"forbidden_operations": [
"glitchtip.issue.resolve",
"glitchtip.issue.delete"
]
}
```
### Schema Rules
* `allowed_operations` are **namespaced** (e.g., `gitea.issue.create`, `jenkins.build.read`, `glitchtip.event.read`).
* `forbidden_operations`, if present, **always override** `allowed_operations`.
* `token_source_name` records the source **name only, never the value**. Tokens must never be printed, logged, or included in telemetry.
## 3. Fail-Closed Behavior
The model enforces strict fail-closed constraints before any network call occurs:
* **Missing Profile:** If a requested profile is undefined for the target service, the operation fails immediately.
* **Missing Credentials:** If the `token_source_name` cannot be resolved to a valid token at runtime, the operation fails immediately without retrying or prompting.
## 4. Environment Overrides
Profiles can be dynamically overridden or injected via environment variables, following the established hierarchy:
1. **Explicit Environment Variable:** (Highest precedence) e.g., `MCP_GLITCHTIP_TOKEN` overrides any JSON profile.
2. **Profile Mapping in JSON:** Resolved via `token_source_name` (e.g., `GLITCHTIP_API_TOKEN_READONLY`) mapping to an environment variable or secret store.
3. **No Auth:** Fails closed.
## 5. Audit Logging
To maintain accountability across multi-service workflows, all mutating actions must include the audit identity and source:
* The audit log must record the `profile_name`, the orchestrator source (e.g., `sysadmin`, `jenkins-mcp`), and the action taken.
* The audit system must sanitize all output to ensure tokens are stripped (see `safety-model.md`).
## 6. Backward Compatibility
The existing Gitea profile behavior (`gitea_whoami`, etc.) remains strictly backward compatible. The generic profile library will parse existing Gitea profile objects without requiring them to migrate their schemas, defaulting the `service` attribute to `gitea`.
## 7. Implementation Boundary
Per the namespace decisions in #71 and #75, this generic model belongs in the `common` package or library. It will be imported by `gitea-mcp` (this repo), `jenkins-mcp`, and `glitchtip-mcp` without forcing a monolithic architecture.
+1 -1
View File
@@ -5,5 +5,5 @@ This document describes how credentials and sensitive environment variables are
## Separate Credentials ## Separate Credentials
Even though multiple MCP servers share the same monorepo, they **must** have separate credentials and runtimes. Even though multiple MCP servers share the same monorepo, they **must** have separate credentials and runtimes.
- **No Shared Environments**: Each MCP server (`gitea-mcp`, `jenkins-mcp`, `ops-mcp`, etc.) must be instantiated as an independent service with its own dedicated `.env` configuration file. - **No Shared Environments**: Each MCP server (`gitea-mcp`, `jenkins-mcp`, `glitchtip-mcp`, `ops-mcp`, etc.) must be instantiated as an independent service with its own dedicated `.env` configuration file.
- **Strict Isolation**: A server will only have access to the credentials required for its specific trust boundary. For instance, `gitea-mcp` has no access to Jenkins or Ops authentication tokens. - **Strict Isolation**: A server will only have access to the credentials required for its specific trust boundary. For instance, `gitea-mcp` has no access to Jenkins or Ops authentication tokens.
+34
View File
@@ -0,0 +1,34 @@
# Label Taxonomy
This document catalogs the issue labels used for MCP workflows, including Jenkins and GlitchTip (observability).
> **Approval Required:** Do not create or apply new labels in `manage_labels.py` without explicit owner approval of this document.
## Existing Labels
* **`jenkins`**
* Description: Jenkins integration
* Color: `d93f0b`
* Use: Used to mark issues, PRs, or tasks that involve the `jenkins-mcp` boundaries, CI/CD designs, or build failures.
* **`glitchtip`**
* Description: GlitchTip integration
* Color: `b60205`
* Use: Used to mark issues related to the `glitchtip-mcp` boundary and observability integration.
## Proposed / Missing Labels
* **`observability`**
* Proposed Description: Observability, metrics, and monitoring tasks
* Proposed Color: `5319e7`
* Use: Broader than GlitchTip alone; covers logging, metrics, traces, and general observability pipeline improvements.
* **`source:glitchtip`**
* Proposed Description: Issue filed automatically by GlitchTip orchestration
* Proposed Color: `b60205`
* Use: Applied automatically by the orchestrator when a GlitchTip error event is converted into a Gitea issue.
* **`status:triage`**
* Proposed Description: Issue needs human or orchestrator triage
* Proposed Color: `fbca04`
* Use: Used for incoming issues (especially automated ones like `source:glitchtip`) that have not yet been evaluated for priority or resolution.
+8
View File
@@ -13,3 +13,11 @@ To maintain a secure environment, all secrets, tokens, passwords, and sensitive
- System and application logs - System and application logs
- Tool return values/outputs - Tool return values/outputs
- Any form of persistent storage or console output - Any form of persistent storage or console output
## 4. Read-Only First Policy
By default, MCP servers (such as `jenkins-mcp` and `ops-mcp`) operate in a **read-only** mode. Mutation capabilities are deny-by-default and fail-closed.
## 5. Mutation Gating
Any mutating action (e.g., Gitea issue creation from GlitchTip, or Jenkins builds) must be explicitly allowed by the execution profile.
- **Jenkins build triggers** are explicitly deferred for phase 1.
- **GlitchTip to Gitea issue filing** is documented as a gated, orchestrated workflow, not a direct unprompted automatic action.
+2 -1
View File
@@ -2,7 +2,7 @@
This document defines the strict boundaries between the different MCP server packages within the monorepo. This document defines the strict boundaries between the different MCP server packages within the monorepo.
The project is named **MCP Control Plane** and lives in the `mcp-control-plane` repository. It groups the following packages: `common`, `gitea-mcp`, `jenkins-mcp`, `ops-mcp`, and `release-mcp`. The project is named **MCP Control Plane** and lives in the `mcp-control-plane` repository. It groups the following packages: `common`, `gitea-mcp`, `jenkins-mcp`, `glitchtip-mcp`, `ops-mcp`, and `release-mcp`.
## 1. Architectural Philosophy ## 1. Architectural Philosophy
- **One MCP Server per Trust Boundary**: While the packages share a monorepo, their runtime services must remain entirely separate. There is no single "everything" server. - **One MCP Server per Trust Boundary**: While the packages share a monorepo, their runtime services must remain entirely separate. There is no single "everything" server.
@@ -10,4 +10,5 @@ The project is named **MCP Control Plane** and lives in the `mcp-control-plane`
## 2. Package-Specific Boundaries ## 2. Package-Specific Boundaries
- **gitea-mcp**: Restricted to source-control and work-item capabilities (issues, PRs, comments). This package **must not** have Jenkins or Ops credentials, nor can it execute deploy operations. - **gitea-mcp**: Restricted to source-control and work-item capabilities (issues, PRs, comments). This package **must not** have Jenkins or Ops credentials, nor can it execute deploy operations.
- **jenkins-mcp**: Focused on CI/CD capabilities. This package **must not** have Ops credentials unless explicitly configured for a specific, isolated pipeline later. - **jenkins-mcp**: Focused on CI/CD capabilities. This package **must not** have Ops credentials unless explicitly configured for a specific, isolated pipeline later.
- **glitchtip-mcp**: Dedicated to observability and error reporting. This package **must not** have Gitea write credentials or Jenkins deploy capabilities.
- **ops-mcp**: Dedicated to live environment and host checks. In its initial state, this package starts as strictly read-only (e.g., health checks, status checks, log reading). - **ops-mcp**: Dedicated to live environment and host checks. In its initial state, this package starts as strictly read-only (e.g., health checks, status checks, log reading).