forta-mcp 1.1.0 → 1.2.0
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/AGENTS.md +24 -1
- package/index.js +3 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -114,11 +114,26 @@ be a Forta **super-admin** — the token does not bypass that.
|
|
|
114
114
|
|-------|-------|
|
|
115
115
|
| Health & identity | `forta_health`, `forta_get_self` |
|
|
116
116
|
| Users | list, get, update, delete |
|
|
117
|
-
| Platforms | list, get, create, update, delete, rotate credentials |
|
|
117
|
+
| Platforms | list, get, create, update, delete, rotate credentials. `create`/`update` carry **`backchannel_logout_uri`** — see the warning below |
|
|
118
118
|
| Roles | list, get, create, update, delete |
|
|
119
119
|
| Grants | list, create, revoke, check |
|
|
120
120
|
| Tokens | introspect, list/create/revoke API tokens |
|
|
121
121
|
|
|
122
|
+
### Setting `backchannel_logout_uri` — order matters
|
|
123
|
+
|
|
124
|
+
Forta POSTs a signed `logout_token` to this URL the instant a grant is revoked, so the consumer
|
|
125
|
+
ends the session immediately instead of waiting up to five minutes for its introspection poll.
|
|
126
|
+
|
|
127
|
+
⚠️ **Only set it once the platform actually serves the endpoint.** Until then every notification
|
|
128
|
+
404s, is retried six times on a backoff, and is marked `exhausted` — which looks in the logs like
|
|
129
|
+
a broken receiver rather than one that was never built. Deploy first, register second.
|
|
130
|
+
|
|
131
|
+
Pass `null` to clear it. Absent is the normal state for a platform that has not implemented the
|
|
132
|
+
receiver, and it is never an error — such a platform is simply skipped by the sender.
|
|
133
|
+
|
|
134
|
+
`https` only; the emitter refuses anything else at send time and logs
|
|
135
|
+
`FORTA_BACKCHANNEL_BAD_ENDPOINT`.
|
|
136
|
+
|
|
122
137
|
### Two behaviours that are easy to get wrong
|
|
123
138
|
|
|
124
139
|
**1. `/oauth/introspect` is a resource-server endpoint, not an admin one.** It requires the
|
|
@@ -148,6 +163,12 @@ description says so; do not "fix" it by sending both.
|
|
|
148
163
|
|
|
149
164
|
- **Published to npm** as `forta-mcp` (public). `npx -y` resolves the latest, so **publishing
|
|
150
165
|
is deployment**.
|
|
166
|
+
- **Bump the version in TWO places before publishing** — `package.json` *and* the `McpServer({
|
|
167
|
+
version })` literal in `index.js`. npm refuses to republish an existing version, so forgetting
|
|
168
|
+
`package.json` fails loudly (`cannot publish over the previously published versions`), but
|
|
169
|
+
forgetting the one in `index.js` fails SILENTLY: the server then reports a version it is not,
|
|
170
|
+
and a client debugging "which build am I talking to" is misled by the only field that answers
|
|
171
|
+
that question.
|
|
151
172
|
- **Publishing requires 2FA via passkey** and must run from an interactive terminal — npm's web
|
|
152
173
|
auth flow needs a browser, and from a non-TTY subprocess it degrades to demanding an OTP a
|
|
153
174
|
passkey-only account cannot produce.
|
|
@@ -198,5 +219,7 @@ Update this AGENTS.md in the same change when you:
|
|
|
198
219
|
- **Change `api()` or its `opts`** → update *How code is written here*.
|
|
199
220
|
- **Discover a `forta-api` behaviour that contradicts a tool description** → fix both, and
|
|
200
221
|
record it under *Two behaviours that are easy to get wrong* if it is non-obvious.
|
|
222
|
+
- **Add/change a tool parameter** → bump the minor version in BOTH places (see *Operations*) in
|
|
223
|
+
the same change, so the commit that adds the capability is the commit that can be published.
|
|
201
224
|
- **Publish** → note the version and what changed.
|
|
202
225
|
- Also keep `README.md`'s tool tables in sync.
|
package/index.js
CHANGED
|
@@ -158,7 +158,7 @@ function body(obj) {
|
|
|
158
158
|
|
|
159
159
|
const server = new McpServer({
|
|
160
160
|
name: "forta",
|
|
161
|
-
version: "1.
|
|
161
|
+
version: "1.2.0",
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
// --- Health & identity ---
|
|
@@ -233,6 +233,7 @@ server.tool("forta_create_platform", "Register a new OAuth platform. Returns the
|
|
|
233
233
|
description: z.string().optional().describe("Description"),
|
|
234
234
|
redirect_uris: z.array(z.string()).optional().describe("Allowed OAuth redirect URIs"),
|
|
235
235
|
logout_redirect_uris: z.array(z.string()).optional().describe("Allowed post-logout redirect URIs"),
|
|
236
|
+
backchannel_logout_uri: z.string().nullable().optional().describe("OIDC Back-Channel Logout 1.0 endpoint on the platform (https only). Forta POSTs a signed logout_token here the moment a grant is revoked, instead of the consumer waiting up to 5 minutes for its introspection poll. Pass null to clear. ⚠️ Only set this once the platform actually serves the endpoint — until then every notification 404s, retries 6 times and is marked exhausted"),
|
|
236
237
|
allowed_origins: z.array(z.string()).optional().describe("Allowed CORS origins"),
|
|
237
238
|
is_first_party: z.boolean().optional().describe("First-party app (skips the consent screen)"),
|
|
238
239
|
internal_resource: z.boolean().optional().describe("Internal resource, hidden from the app launcher"),
|
|
@@ -254,6 +255,7 @@ server.tool("forta_update_platform", "Update a platform's configuration. Only th
|
|
|
254
255
|
platform_type: z.enum(["WEB", "SPA", "SERVICE", "MOBILE"]).optional(),
|
|
255
256
|
redirect_uris: z.array(z.string()).optional(),
|
|
256
257
|
logout_redirect_uris: z.array(z.string()).optional(),
|
|
258
|
+
backchannel_logout_uri: z.string().nullable().optional().describe("OIDC Back-Channel Logout 1.0 endpoint on the platform (https only). Forta POSTs a signed logout_token here the moment a grant is revoked, instead of the consumer waiting up to 5 minutes for its introspection poll. Pass null to clear. ⚠️ Only set this once the platform actually serves the endpoint — until then every notification 404s, retries 6 times and is marked exhausted"),
|
|
257
259
|
allowed_origins: z.array(z.string()).optional(),
|
|
258
260
|
is_first_party: z.boolean().optional(),
|
|
259
261
|
internal_resource: z.boolean().optional(),
|