specguard-mcp 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -34,8 +34,8 @@ refuses to boot and takes the tools that needed no configuration down with it.
|
|
|
34
34
|
| --- | --- | --- | --- |
|
|
35
35
|
| `SPECGUARD_ENDPOINT` | `get_repository_overview`, `list_repositories`, `add_repository`, `registrable_repositories` | — | your SpecGuard instance's root URL, **including the scheme** — e.g. `https://specguard.example.com`, or `http://localhost:3000`. A value with no scheme is refused by name (`SPECGUARD_ENDPOINT is not a usable URL: "sg.example.com"`) rather than surfacing later as an opaque failure. `SPECGUARD_URL` is accepted as an alias, and is the name every message uses when it is the one you set. A blank value counts as unset, so leaving `SPECGUARD_ENDPOINT` empty in a templated config falls through to `SPECGUARD_URL` instead of suppressing it |
|
|
36
36
|
| `SPECGUARD_API_KEY` | `get_repository_overview`, `near_duplicate_clusters` (default calls) | — | an agent/CI API key (`sgk_…`) issued by that deployment — a **per-repository** key, which is the single repository those tools answer about by default |
|
|
37
|
-
| `SPECGUARD_USER_API_KEY` | `list_repositories` (fallback), `add_repository`, `registrable_repositories`, `remove_repository
|
|
38
|
-
| `SPECGUARD_AGENT_API_KEY` | `list_repositories` (preferred), `get_repository_overview` / `near_duplicate_clusters` **with** `repository` | — | an **agent** API key (`sga_…`), minted from that deployment's account page (Agent keys panel) with an explicit set of repositories and permissions. It speaks for nobody: its reach is exactly the set granted onto it, fixed at mint time, and every read is bounded by that set server-side. This is the credential to give an automated agent — one key, many repositories, none of a person's rights. When it and `SPECGUARD_USER_API_KEY` are both set, `list_repositories`
|
|
37
|
+
| `SPECGUARD_USER_API_KEY` | `list_repositories` (fallback), `add_repository`, `registrable_repositories`, `remove_repository` (fallback), `create_repository_api_key`, `revoke_repository_api_key`, `list_repository_agent_keys`, `revoke_repository_agent_key`, `list_repository_agent_keys_presented_revoked`, `list_repository_members`, `add_repository_member`, `update_repository_member_permissions`, `remove_repository_member`, `rename_repository` | — | a **user** API key (`sgu_…`), minted from that deployment's account page. A different credential from the one above, not a second place to put the same value: SpecGuard decides which of them a request may use from the token's prefix, before it reads anything, and answers `401` for the other one. Set whichever your tools need — both, if you use both |
|
|
38
|
+
| `SPECGUARD_AGENT_API_KEY` | `list_repositories` (preferred), `remove_repository` (preferred), `get_repository_overview` / `near_duplicate_clusters` **with** `repository` | — | an **agent** API key (`sga_…`), minted from that deployment's account page (Agent keys panel) with an explicit set of repositories and permissions. It speaks for nobody: its reach is exactly the set granted onto it, fixed at mint time, and every read is bounded by that set server-side. This is the credential to give an automated agent — one key, many repositories, none of a person's rights. When it and `SPECGUARD_USER_API_KEY` are both set, `list_repositories` and `remove_repository` use **this** one, so discovery stays inside the set the other tools can reach |
|
|
39
39
|
| `SPECGUARD_LINT_COMMAND` | `lint_intent_annotations` | `specguard-lint` | the command that runs the linter. Most Ruby projects need `bundle exec specguard-lint` |
|
|
40
40
|
| `SPECGUARD_TIMEOUT_MS` | HTTP tools | `30000` | how long a call to SpecGuard may take |
|
|
41
41
|
|
|
@@ -562,9 +562,13 @@ Authorization is the `repo.delete` capability at **either surface** — an owner
|
|
|
562
562
|
`repo.delete`, may remove the repository. A member without it is refused `403` with SpecGuard's own
|
|
563
563
|
sentence, verbatim. The repository's CI keys stop authenticating the moment it succeeds.
|
|
564
564
|
|
|
565
|
-
It reads
|
|
566
|
-
|
|
567
|
-
|
|
565
|
+
It reads either of two credentials, whichever is set — and a different one from the `sgk_…` key
|
|
566
|
+
`get_repository_overview` uses. `SPECGUARD_AGENT_API_KEY` (`sga_…`) when it is set: the call then
|
|
567
|
+
reaches only the repositories granted onto that key at mint time, and only where the grant carries
|
|
568
|
+
`repo.delete` — a repository outside that set is answered `404` in SpecGuard's own words.
|
|
569
|
+
`SPECGUARD_USER_API_KEY` (`sgu_…`) when no agent key is set: the same **person** key `add_repository`
|
|
570
|
+
reads. With both set the **agent** key wins, so the removal answers inside the same set
|
|
571
|
+
`list_repositories` reports.
|
|
568
572
|
|
|
569
573
|
### `create_repository_api_key`
|
|
570
574
|
|
|
@@ -78,12 +78,12 @@ import type { ToolDefinition } from "./types.js";
|
|
|
78
78
|
* carrying the same `{error, message}` contract — the identical defect, given
|
|
79
79
|
* the identical remedy.
|
|
80
80
|
*
|
|
81
|
-
* The
|
|
82
|
-
*
|
|
83
|
-
* unchanged and still binding,
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
81
|
+
* The registration gate was the newest user-scoped entry when it landed; the
|
|
82
|
+
* sections below record how the surface grew after it. The standing rule is
|
|
83
|
+
* unchanged and still binding, and what it keeps out today is what has not
|
|
84
|
+
* shipped — `/check-intent` has no backing endpoint (`routes.rb` mounts it as
|
|
85
|
+
* a comment only), so it stays unwrapped. What moved was the platform, not
|
|
86
|
+
* the bar.
|
|
87
87
|
*
|
|
88
88
|
* == Removal and the key lifecycle
|
|
89
89
|
*
|
package/dist/src/tools/index.js
CHANGED
|
@@ -94,12 +94,12 @@ import updateRepositoryMemberPermissions from "./update-repository-member-permis
|
|
|
94
94
|
* carrying the same `{error, message}` contract — the identical defect, given
|
|
95
95
|
* the identical remedy.
|
|
96
96
|
*
|
|
97
|
-
* The
|
|
98
|
-
*
|
|
99
|
-
* unchanged and still binding,
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
97
|
+
* The registration gate was the newest user-scoped entry when it landed; the
|
|
98
|
+
* sections below record how the surface grew after it. The standing rule is
|
|
99
|
+
* unchanged and still binding, and what it keeps out today is what has not
|
|
100
|
+
* shipped — `/check-intent` has no backing endpoint (`routes.rb` mounts it as
|
|
101
|
+
* a comment only), so it stays unwrapped. What moved was the platform, not
|
|
102
|
+
* the bar.
|
|
103
103
|
*
|
|
104
104
|
* == Removal and the key lifecycle
|
|
105
105
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deleteJson,
|
|
1
|
+
import { deleteJson, requireUserOrAgentApiConfig } from "../support/specguard-api.js";
|
|
2
2
|
import { requireString } from "./args.js";
|
|
3
3
|
/**
|
|
4
4
|
* `DELETE /api/v1/repositories/:id` as a tool — shipped in the platform
|
|
@@ -44,9 +44,15 @@ const removeRepository = {
|
|
|
44
44
|
"cannot be brought back. " +
|
|
45
45
|
"Takes `repository_id` — the numeric id `add_repository` and `list_repositories` " +
|
|
46
46
|
"report, not the `org/repo` handle. " +
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
47
|
+
"It authenticates with EITHER of this server's two repository-administration credentials, " +
|
|
48
|
+
"whichever is set: SPECGUARD_AGENT_API_KEY (an sga_… key — the call then reaches only the " +
|
|
49
|
+
"repositories granted onto that key at mint time, and only where the grant carries " +
|
|
50
|
+
"`repo.delete`; a repository outside that set answers 404 in SpecGuard's own words, never " +
|
|
51
|
+
"a probe here) and, when that is not set, SPECGUARD_USER_API_KEY (an sgu_… key, the same " +
|
|
52
|
+
"credential `add_repository` writes with). With both set the agent key wins, so the " +
|
|
53
|
+
"removal answers inside the same set `list_repositories` reports. " +
|
|
54
|
+
"Either way it is a DIFFERENT credential from the sgk_… repository key " +
|
|
55
|
+
"`get_repository_overview` uses; SpecGuard refuses each in the other's place.",
|
|
50
56
|
inputSchema: {
|
|
51
57
|
type: "object",
|
|
52
58
|
properties: {
|
|
@@ -66,7 +72,7 @@ const removeRepository = {
|
|
|
66
72
|
},
|
|
67
73
|
async run(args, context) {
|
|
68
74
|
const repositoryId = requireString(args["repository_id"], "repository_id");
|
|
69
|
-
const api =
|
|
75
|
+
const api = requireUserOrAgentApiConfig(context.config);
|
|
70
76
|
const body = await deleteJson(api, `/api/v1/repositories/${encodeURIComponent(repositoryId)}`, context.fetch);
|
|
71
77
|
// 204 with no body. Nothing upstream to pass through, so the result says
|
|
72
78
|
// what the verb did — in the tool's own words, because the deployment's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-repository.js","sourceRoot":"","sources":["../../../src/tools/remove-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"remove-repository.js","sourceRoot":"","sources":["../../../src/tools/remove-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,gBAAgB,GAAmB;IACvC,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EACT,iFAAiF;QACjF,sFAAsF;QACtF,8EAA8E;QAC9E,0DAA0D;QAC1D,mFAAmF;QACnF,sFAAsF;QACtF,uFAAuF;QACvF,kFAAkF;QAClF,0BAA0B;QAC1B,kFAAkF;QAClF,qCAAqC;QACrC,2FAA2F;QAC3F,2FAA2F;QAC3F,oFAAoF;QACpF,2FAA2F;QAC3F,0FAA0F;QAC1F,qFAAqF;QACrF,mEAAmE;QACnE,wEAAwE;QACxE,8EAA8E;IAChF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,aAAa,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,+EAA+E;oBAC/E,+EAA+E;oBAC/E,sEAAsE;aACzE;SACF;QACD,QAAQ,EAAE,CAAC,eAAe,CAAC;QAC3B,qEAAqE;QACrE,0EAA0E;QAC1E,yEAAyE;QACzE,gEAAgE;QAChE,oBAAoB,EAAE,KAAK;KAC5B;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO;QACrB,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC,CAAC;QAE3E,MAAM,GAAG,GAAG,2BAA2B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAExD,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,GAAG,EACH,wBAAwB,kBAAkB,CAAC,YAAY,CAAC,EAAE,EAC1D,OAAO,CAAC,KAAK,CACd,CAAC;QAEF,yEAAyE;QACzE,wEAAwE;QACxE,iCAAiC;QACjC,OAAO;YACL,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,uEAAuE,CAAC,CAAC,CAAC,IAAI;YAClG,UAAU,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE;SAC3D,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|