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.
Files changed (3) hide show
  1. package/AGENTS.md +24 -1
  2. package/index.js +3 -1
  3. 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.1.0",
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(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forta-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server for the Forta OAuth2 identity provider",
5
5
  "type": "module",
6
6
  "main": "index.js",