addrbookFor publishers
← The evidence ledger

Evidence row 263666

Observed , by probe.mcp/1.

Kind
mcp.tools
About
endpoint bdf1a3c4-3446-4bf4-b16e-4b7218b055d5
Recorded
Previous row
None: the first of its kind about this subject
Body SHA-256
c34d07187aed060d9c2f29f0832556a71785b8743c99825b4c087d5265d2675f
Leaf
0x7a1d46e6ede32957b18b41a6d4d12eddad22ef5f464f9c3acc52dbdc7881cbf9

What was observed

{
  "count": 18,
  "tools": [
    {
      "description": "**Browser redirect endpoint** used after hosted `/app/sessions/login`. No `Authorization` header.\n\n1. Verifies **`firebaseToken`** (Firebase ID token).\n2. Ensures **`client_redirect_uri`** is allowlisted for **`app_id`** (same rules as `validate-redirect`).\n3. **Create vs renew:** If **`session_token`** is absent, **reuses the newest active session** for\n   **`(workspace_name, Firebase UID, app_id)`** or **creates** one (`get-or-create`). Optional\n   **`payload`** (URL-encoded JSON **object**, default `{}`) is stored **only on create** — ignored when\n   reusing an existing session. If **`session_token`** is present (previous session JWT, may be expired),\n   **renews** that session; **`payload`** must **not** be sent on the same request. Optional\n   **`ttl_seconds`** applies to both paths (default **0** = unlimited; otherwise **60–604800**). When the\n   Firebase token includes **`email`**, the server best-effort persists or backfills it on the workspace\n   end-user row (audit display only).\n4. Responds with **`302 Found`** to `client_redirect_uri` with query params **`sessionToken`**\n   and, if provided, **`state`**.\n\nIf **`client_redirect_uri`** is not allowed for **`app_id`**, responds **`400`** and does **not**\nredirect (open-redirect mitigation). Other failures return an HTTP error status with a JSON\n**`{\"status\", \"error\"}`** body and do **not** redirect.\n\nSource: GET /api/v1/auth/callback\nNo Authorization header is required.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {},
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {
              "app_id": {
                "type": "string"
              },
              "client_redirect_uri": {
                "format": "uri",
                "type": "string"
              },
              "firebaseToken": {
                "type": "string"
              },
              "payload": {
                "description": "JSON object as a string (e.g. `{\"a\":1}`), URL-encoded. Must parse to a JSON object (not an array or primitive).\nDefault when omitted is `{}`. Must not be combined with `session_token` on the same request.\n",
                "type": "string"
              },
              "session_token": {
                "description": "Previous session JWT (may be expired); signature must validate. When present, the server renews this\nsession instead of creating a new one. Must not be combined with `payload` on the same request.\nURL-encode the value; very long URLs may exceed browser or proxy limits.\n",
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "ttl_seconds": {
                "description": "Session lifetime in seconds (default 0 = unlimited; allowed values: 0 or 60–604800)",
                "maximum": 604800,
                "minimum": 0,
                "type": "integer"
              },
              "workspace_name": {
                "type": "string"
              }
            },
            "required": [
              "firebaseToken",
              "client_redirect_uri",
              "workspace_name",
              "app_id"
            ],
            "type": "object"
          }
        },
        "required": [
          "connection",
          "query"
        ],
        "type": "object"
      },
      "name": "auth_session_callback"
    },
    {
      "description": "Removes `key` from the session payload and returns `true` if the key existed.\n\nSource: DELETE /api/v1/sessions/delete/{key}\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {
              "key": {
                "description": "Payload key to delete",
                "type": "string"
              }
            },
            "required": [
              "key"
            ],
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "params"
        ],
        "type": "object"
      },
      "name": "delete_sessions_delete_key"
    },
    {
      "description": "Browser-friendly logout endpoint for **cross-site** clients (e.g. apps running on `localhost`).\n\nUse this as a **top-level navigation** (not XHR/fetch) so `Clear-Site-Data` is applied in a\n**first-party** context on `secure-flows.com`, making cookie/session clearing reliable even when\nthird-party cookies are blocked.\n\n**Critical client rules:**\n- Clear your in-app `sessionToken` state **before** navigating.\n- **Never** include `session_token` inside `redirect_uri` (that would silently renew and defeat logout).\n\nThis endpoint (best-effort / idempotent for browser UX):\n- Invalidates the provided `session_token` by incrementing `tokenRevision` when the token still\n  matches an **active** session (no new token is issued).\n- If the session is already expired/revoked or the revision was superseded by renew, still\n  completes logout UX (does **not** return 401 solely for that reason).\n- Revokes Firebase refresh tokens for the session’s stored Firebase UID when known.\n- Sets `Clear-Site-Data: \"cookies\"`.\n- Redirects the browser to `redirect_uri`.\n\nSource: GET /api/v1/auth/logout\nNo Authorization header is required.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {},
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {
              "redirect_uri": {
                "description": "Where to redirect after logout completes",
                "format": "uri",
                "type": "string"
              },
              "session_token": {
                "description": "SESSION JWT to invalidate (URL-encoded)",
                "type": "string"
              }
            },
            "required": [
              "session_token",
              "redirect_uri"
            ],
            "type": "object"
          }
        },
        "required": [
          "connection",
          "query"
        ],
        "type": "object"
      },
      "name": "get_auth_logout"
    },
    {
      "description": "Embeds the query with Ollama (`nomic-embed-text`) and returns the closest public doc chunks\nfrom the environment's search index (pgvector).\n\nSource: GET /api/v1/docs/search\nNo Authorization header is required.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {},
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {
              "limit": {
                "description": "Maximum hits to return (server caps at 20)",
                "maximum": 20,
                "minimum": 1,
                "type": "integer"
              },
              "q": {
                "description": "Natural-language question or keywords",
                "type": "string"
              }
            },
            "required": [
              "q"
            ],
            "type": "object"
          }
        },
        "required": [
          "connection",
          "query"
        ],
        "type": "object"
      },
      "name": "get_docs_search"
    },
    {
      "description": "Returns the decrypted session payload for the authenticated internal session token.\n\nResponse shape is a **flat JSON object**. Empty payload returns `{}`.\n\nSource: GET /api/v1/sessions\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection"
        ],
        "type": "object"
      },
      "name": "get_sessions"
    },
    {
      "description": "Retrieves the decrypted payload value for `key`.\n\n**Important:** `404` means the key was never written (normal first-use case). Do not treat as an error.\n\nSource: GET /api/v1/sessions/get/{key}\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {
              "key": {
                "description": "Payload key to read",
                "type": "string"
              }
            },
            "required": [
              "key"
            ],
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "params"
        ],
        "type": "object"
      },
      "name": "get_sessions_get_key"
    },
    {
      "description": "Returns the workspace end-user's **`userId`** and **email** for the authenticated session\ntoken. Does not return Firebase UID or session payload.\n\n`userId` is a stable, opaque identifier for this person across sessions and logins — it is\n**not** derived from Firebase. Use it as the correlation key when your own backend needs to\nlink an external event (e.g. a billing provider webhook you receive and verify yourself)\nback to this user. Do not use the session token or session id for this — sessions expire and\nrotate, `userId` does not.\n\nEmail is best-effort from hosted login (Firebase `email` claim persisted on the user row).\nWhen unknown, `email` is `null`. Browser SDK: **`secureflows-js`** **`fetchSessionIdentity(token)`** (≥ 0.1.15 for `userId`).\n\nSource: GET /api/v1/sessions/identity\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection"
        ],
        "type": "object"
      },
      "name": "get_sessions_identity"
    },
    {
      "description": "Returns a page of sessions for the current user within the current workspace.\nSelf-service dashboard endpoint — requires workspace **`enableSelfService: true`**.\nPayload is included only for rows whose computed status is active.\nSort keys match the admin workspace session list; `pageSize` is clamped to 1–200 (default 20).\n\nSource: GET /api/v1/sessions/my\nRequires `auth.userToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "userToken": {
                "description": "secureFlows USER token",
                "type": "string"
              }
            },
            "required": [
              "userToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {
              "app_id": {
                "description": "Filter by client app id, or `all`.",
                "type": "string"
              },
              "dir": {
                "enum": [
                  "asc",
                  "desc"
                ],
                "type": "string"
              },
              "page": {
                "maximum": 9007199254740991,
                "minimum": 0,
                "type": "integer"
              },
              "pageSize": {
                "description": "Page size (server clamps to 1–200; 0 or invalid uses default 20).",
                "maximum": 200,
                "minimum": 1,
                "type": "integer"
              },
              "q": {
                "description": "Search by session id, app id, or user identifier (own uid)",
                "type": "string"
              },
              "sort": {
                "enum": [
                  "id",
                  "user",
                  "app",
                  "created",
                  "expires",
                  "status",
                  "lastActivity",
                  "updated"
                ],
                "type": "string"
              },
              "status": {
                "description": "Computed session lifecycle filter (`all` or same values as admin session list).",
                "enum": [
                  "all",
                  "active",
                  "expired",
                  "revoked"
                ],
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "required": [
          "connection",
          "query"
        ],
        "type": "object"
      },
      "name": "get_sessions_my"
    },
    {
      "description": "Logs out the current session **without revoking** it.\n\n**Browser warning:** calling this endpoint via XHR/fetch from a different origin than `secure-flows.com`\nis not a reliable way to clear hosted-login cookies. For browser apps (especially localhost), prefer the\nredirect helper `GET /api/v1/auth/logout?session_token=...&redirect_uri=...`.\n\nBehavior:\n- **Invalidates** the current `sessionToken` by incrementing `tokenRevision` (no new token is issued).\n- Calls Firebase `revokeRefreshTokens(firebaseUid)` using the session’s stored Firebase UID.\n- Sets `Clear-Site-Data: \"cookies\"` to clear browser cookies (including Firebase session cookie).\n\nSession payload and session row are **not** deleted or modified (other than `tokenRevision`).\n\nSource: POST /api/v1/auth/logout\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection"
        ],
        "type": "object"
      },
      "name": "post_auth_logout"
    },
    {
      "description": "Verifies **Firebase** ID token, creates a session for **`workspaceName`**, stores serialized\n**`payload`** (defaults to `{}` when omitted), and returns **`sessionToken`** (JWT; subject = internal session id).\nDefault server-side TTL is **1 hour** (implementation detail).\n\nIf the Firebase token includes **`email`**, the server best-effort persists it on the workspace\nend-user row (for audit display). Prefer **`POST /sessions/get-or-create`** for hosted-login-style\nflows that should reuse an active session.\n\nSource: POST /api/v1/sessions\nRequires `auth.firebaseToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "firebaseToken": {
                "description": "Firebase ID token",
                "type": "string"
              }
            },
            "required": [
              "firebaseToken"
            ],
            "type": "object"
          },
          "body": {
            "properties": {
              "app_id": {
                "anyOf": [
                  {
                    "description": "Optional app id (must belong to the workspace). Used for per-app session policy and auditing.",
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "payload": {
                "additionalProperties": {},
                "description": "Arbitrary payload object stored in the session. Optional; omitted or null is stored as `{}`.",
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              "workspaceName": {
                "description": "Workspace name to scope the session",
                "type": "string"
              }
            },
            "required": [
              "workspaceName"
            ],
            "type": "object"
          },
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "body"
        ],
        "type": "object"
      },
      "name": "post_sessions"
    },
    {
      "description": "Verifies **Firebase** ID token. If an **active** session already exists for\n**`(workspaceName, Firebase UID, app_id)`**, returns a new **`sessionToken`** JWT for the **most\nrecently created** matching row (touches activity; does not create a duplicate session). The request\n**`payload` is ignored on reuse** — it is applied only when a new session row is created. Prefer a\ndedicated `app_id` per integration surface, or revoke old sessions, if you need a fresh payload.\n\nOtherwise behaves like **`POST /sessions`** (new row + default **1 hour** TTL).\n\nIf the Firebase token includes **`email`**, the server best-effort persists or backfills it on the\nworkspace end-user row (including when reusing an existing session). Intended for integrators that\nmirror hosted login session reuse.\n\nSource: POST /api/v1/sessions/get-or-create\nRequires `auth.firebaseToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "firebaseToken": {
                "description": "Firebase ID token",
                "type": "string"
              }
            },
            "required": [
              "firebaseToken"
            ],
            "type": "object"
          },
          "body": {
            "properties": {
              "app_id": {
                "anyOf": [
                  {
                    "description": "Optional app id (must belong to the workspace). Used for per-app session policy and auditing.",
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "payload": {
                "additionalProperties": {},
                "description": "Arbitrary payload object stored in the session. Optional; omitted or null is stored as `{}`.",
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              "workspaceName": {
                "description": "Workspace name to scope the session",
                "type": "string"
              }
            },
            "required": [
              "workspaceName"
            ],
            "type": "object"
          },
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "body"
        ],
        "type": "object"
      },
      "name": "post_sessions_get_or_create"
    },
    {
      "description": "Verifies **Firebase** ID token. Parses **`sessionToken`** path segment as an internal SESSION JWT **without\nenforcing JWT expiry** (signature and `tokenType=SESSION` are still validated). Loads the\nsession by id from the token subject; the Firebase UID must match the session owner.\nIncrements **`tokenRevision`** on the server so **previous session JWTs** (same session id,\nolder revision) are no longer accepted for `GET/POST/DELETE /sessions/...`.\nReturns a **new `sessionToken`** (with the new `tokenRevision` claim) and the current decrypted\n**payload**; extends server-side session expiry by **1 hour**.\n\nIf the Firebase token includes **`email`**, the server best-effort backfills it on the session owner\nwhen the user row has no email yet (audit display only).\n\nUse the path form `POST /api/v1/sessions/renew/{sessionToken}` — **URL-encode** the JWT (e.g. `encodeURIComponent` in JS).\n\nSource: POST /api/v1/sessions/renew/{sessionToken}\nRequires `auth.firebaseToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "firebaseToken": {
                "description": "Firebase ID token",
                "type": "string"
              }
            },
            "required": [
              "firebaseToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {
              "sessionToken": {
                "description": "Previous SESSION JWT (may be expired); URL-encoded in the path",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "params"
        ],
        "type": "object"
      },
      "name": "post_sessions_renew_session_token"
    },
    {
      "description": "Permanently revokes the session referenced by the internal SESSION Bearer token. The session ends and everything stored in it is destroyed and cannot be restored. This is NOT sign-out: to sign a user out and keep their data, use POST /api/v1/auth/logout (or, in a browser, the redirect helper GET /api/v1/auth/logout). Call revoke only when the user or an admin deliberately wants the session and its data deleted, for example on account deletion.\n\nSource: POST /api/v1/sessions/revoke\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {},
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection"
        ],
        "type": "object"
      },
      "name": "post_sessions_revoke"
    },
    {
      "description": "Self-service dashboard endpoint. Revokes a session owned by the caller in the current workspace.\nThe session ends and its stored data is destroyed permanently; this is not sign-out.\nRequires workspace **`enableSelfService: true`**.\n\nSource: POST /api/v1/sessions/revoke/{sessionId}\nRequires `auth.userToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "userToken": {
                "description": "secureFlows USER token",
                "type": "string"
              }
            },
            "required": [
              "userToken"
            ],
            "type": "object"
          },
          "body": {},
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {
              "sessionId": {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              }
            },
            "required": [
              "sessionId"
            ],
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "params"
        ],
        "type": "object"
      },
      "name": "post_sessions_revoke_session_id"
    },
    {
      "description": "Sets a key in the encrypted session payload and returns the updated decrypted payload. If the JSON body is `{ \"value\": <x> }`, the server unwraps it and stores `<x>` directly.\n\nSource: POST /api/v1/sessions/set/{key}\nRequires `auth.sessionToken` and forwards it as a Bearer token.\nPrefer connection.workspaceName and connection.appId as stable config instead of generating identity fields dynamically.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "auth": {
            "properties": {
              "sessionToken": {
                "description": "secureFlows session token",
                "type": "string"
              }
            },
            "required": [
              "sessionToken"
            ],
            "type": "object"
          },
          "body": {
            "anyOf": [
              {
                "properties": {
                  "value": {}
                },
                "required": [
                  "value"
                ],
                "type": "object"
              },
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "boolean"
              },
              {
                "items": {},
                "type": "array"
              },
              {
                "additionalProperties": {},
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {}
            ],
            "description": "JSON body can be either `{ \"value\": <x> }` (preferred) or a raw JSON value.\n"
          },
          "connection": {
            "properties": {
              "appId": {
                "description": "Optional secureFlows app id used as a default for hosted login tools",
                "type": "string"
              },
              "host": {
                "description": "secureFlows base URL, for example https://api.example.com",
                "format": "uri",
                "type": "string"
              },
              "workspaceName": {
                "description": "Optional workspace name used as a default for tools that need it",
                "type": "string"
              }
            },
            "required": [
              "host"
            ],
            "type": "object"
          },
          "params": {
            "properties": {
              "key": {
                "description": "Payload key to set",
                "type": "string"
              }
            },
            "required": [
              "key"
            ],
            "type": "object"
          },
          "query": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "connection",
          "params",
          "body"
        ],
        "type": "object"
      },
      "name": "post_sessions_set_key"
    },
    {
      "description": "Builds a correct hosted-login redirect URL. Needs no secureFlows token — safe to call at app-scaffolding time,\nbefore any user session exists, which is the phase most secureFlows integration mistakes happen in.\n\nAlways targets /app/sessions/login (session apps). Never builds the legacy /app/login console URL,\nwhich returns a firebaseToken your SecureFlowsCallback handler cannot consume and causes an infinite redirect loop.\n\nUse this instead of hand-building the URL with URLSearchParams — hand-built login URLs are the #1 source of the\nlogin-loop and stale-renewal bugs documented in SKILL.md.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "appId": {
            "description": "App id from the human prompt (\"appId = ...\")",
            "type": "string"
          },
          "expiredToken": {
            "description": "The old sessionToken to renew. Only read when intent=renew_expired_token. Setting this after an explicit sign-out is the \"send a dead JWT into hosted login\" anti-pattern — it breaks renewal when the underlying identity changed.",
            "type": "string"
          },
          "intent": {
            "default": "fresh_login",
            "description": "fresh_login: normal sign-in, or app-load restore with no prior token (default — almost always correct, including after an explicit sign-out). renew_expired_token: ONLY when resuming the SAME still-intended user after a soft token expiry (401/410) while staying logged in — never after Sign out.",
            "enum": [
              "fresh_login",
              "renew_expired_token"
            ],
            "type": "string"
          },
          "origin": {
            "default": "https://www.secure-flows.com",
            "description": "secureFlows origin — always https://www.secure-flows.com in production",
            "format": "uri",
            "type": "string"
          },
          "redirectUri": {
            "description": "The app's unguarded /callback URL, built from the published/allowlisted app origin — never from an iframe or editor chrome origin.",
            "format": "uri",
            "type": "string"
          },
          "workspaceName": {
            "description": "Workspace name from the human prompt (\"workspace = ...\")",
            "type": "string"
          }
        },
        "required": [
          "workspaceName",
          "appId",
          "redirectUri"
        ],
        "type": "object"
      },
      "name": "secureflows_build_login_url"
    },
    {
      "description": "Builds a correct redirect-logout URL and refuses to build one that violates the two documented logout anti-patterns:\na redirect_uri pointing at /callback (SPA callback handlers treat the tokenless return as a failed login and loop),\nand a redirect_uri that itself embeds session_token (silently renews the old session instead of signing out).\n\nThe result always instructs top-level navigation, never fetch/XHR — cross-site fetch() to this endpoint gets a 200 but\nbrowsers silently ignore its Clear-Site-Data header on cross-site responses, so the hosted-login cookie survives and the\nuser silently re-authenticates on the next login redirect. This tool never builds a revoke request: revoke permanently\ndestroys the user's data and must only run on an explicit \"delete my account\" action, never on ordinary sign-out.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "origin": {
            "default": "https://www.secure-flows.com",
            "description": "secureFlows origin — always https://www.secure-flows.com in production",
            "format": "uri",
            "type": "string"
          },
          "postLogoutRedirectUri": {
            "description": "Where the browser lands after logout completes — allowlisted, must NOT be /callback, and must NOT itself contain session_token.",
            "format": "uri",
            "type": "string"
          },
          "sessionToken": {
            "description": "The current sessionToken to invalidate.",
            "type": "string"
          }
        },
        "required": [
          "sessionToken",
          "postLogoutRedirectUri"
        ],
        "type": "object"
      },
      "name": "secureflows_build_logout_url"
    },
    {
      "description": "Checks source you already generated against the secureFlows integration rules. Needs no secureFlows token; safe at\nscaffolding time. Pass every auth/session-related file in one call — some checks are evaluated across the whole set.\n\nTwo kinds of findings:\n  • scope \"file\"    — a forbidden construct is present (localStorage token, legacy /app/login, fetch-based logout,\n    client-side JWT decode, empty catch, restore non-auth errors clearing session UI, Continue CTA gated on null session, ...), reported at an exact file:line.\n  • scope \"project\" — REQUIRED handling is missing everywhere you passed in: detecting 401/410 but never clearing the\n    token, never handling 403, or handling 403 without the BILLING_GRACE_LOCK carve-out. These are the defects that\n    actually dominate real generated apps, and no \"forbidden pattern\" check can see them, because the bug is an absence.\n\nHeuristic text analysis, not a parser or a type checker. It can miss things it has no rule for, and a project check can\nbe satisfied by the right keyword in the wrong place. It is a fast first pass — not a substitute for the Agent\nimplementation checklist in SKILL.md, and specifically not for the checks that need a running app (auth-guard mount\nraces, the fresh-reload check). Fix every \"error\" before calling an integration done; treat \"needs_review\" as a lead.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "files": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Map of relative file path -> full file source to scan, e.g. { \"src/lib/secureflows.js\": \"...\" }",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "files"
        ],
        "type": "object"
      },
      "name": "secureflows_lint_integration"
    }
  ]
}

What the leaf hashes

{"body":"c34d07187aed060d9c2f29f0832556a71785b8743c99825b4c087d5265d2675f","id":263666,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793033627849045,"prev":null,"subject":"bdf1a3c4-3446-4bf4-b16e-4b7218b055d5","subject_kind":"endpoint"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (296695 rows).

  1. 0x7a1d41f7b17a3295fddb32ff2f5058194704544f297341a8bdf005ba73c5b7f3
  2. 0x8445093327621af2749d46417dd782ca51779499bb4c273b9528572d31c217cf
  3. 0x23a6df4e1c6e0b81ce16e6458a6b0ed6f9f74b74ed59cfbe65d99ebff2b44fdf
  4. 0xa76cc5996fbdd7af0400d40a8550b7fc8026a857dc9f9758780901a9ad830c4d
  5. 0xd84ae1c534096c89adc13b4b88a609f30cb0b85630be73a8c81f47fffc3354cd
  6. 0x1b2a6c993c795fbe1e875fc83b3f41d38765feef4adc0082a443fc192f4ec13b
  7. 0x25414f3c7205b388f92b2e7b06518149fced3e682e35d3d3f4268f6fb92edd80
  8. 0x92d03ec8a7b10c17fe1781a7163b171ccd7f9bce50d0c153c49c6d1fc9376194
  9. 0x2b1846c8f1a71d5ca42246b859f4f9e7f7909cb9c881869cbb1bfe38b07466f7
  10. 0xd7bfe89d1c95d31c83b5cd958ac57e187ca41d9a64c12c75ed199d276c80aa6f
  11. 0x1474b20023ac420a3be8200f14f9ac14f1ee93ff05411fa3760c28b2e50fb3dd
  12. 0xa6406b1a5540d26e0cbd03bb274a01c10968fadb17913a6043bb9427ddfb71ba
  13. 0x01c95624b1f2385ef774ee258a9ae58a4df07a1bdaa829de84e1d5201f3f39c2
  14. 0x7721d38652b6444b18e1193824e50490ade04851ce6221771f6e374c4527d80f
  15. 0x15039087bf60ae9b06b756ec3cbc299760e59923a438bbd91e34d105186db0ed
  16. 0x2b6e23e3624a1b66e1d2298cfbce99a93ce6b13d24a58112a71802d79c5f7a76
  17. 0xd21942ae3214eff88e08ab04884fd4b11958b51af9a0741b7668e2d07a2c56c9
  18. 0x9a9024edb5069d88a324facb310a5ce8e495214bbaa968f077bede437390194f
  19. 0x9b9ce5b74b9bab5121612ef6b64920a8d453cbf311096a423eef9702747e868a
Day root
0xf43e8dcc3d451a4788b26be904c55e8c4c0fa75c9666796c51db38d37e2c0df8
Chained
0x702d5ac508f08b0d1accf36af25822d8e5660367494edd17a642fb61e158a57a
Published
On Arc Testnet, block 69251483: 0x495162f8936e19f0039918feebe6c307f327cd6bf8c37219620b1970041fa9ae

How to check it · This row as JSON