From 9561e01bed0e76168e500f9750be7ca5b32744f3 Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 15:18:48 +0200 Subject: [PATCH 1/6] docs(mcp-server): document the tokenTtl option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both values are upper bounds — they only shorten what Forest Admin granted — and refreshTokenSeconds is anchored on the login rather than the last refresh, so the page states both explicitly: that is what surprises users. Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 991ce37..75ec5ab 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -55,6 +55,8 @@ The standalone Forest MCP Server is configured entirely through environment vari | `MCP_SERVER_PORT` | No | `3931` | Port the standalone server listens on. | | `FOREST_MCP_ENABLED_TOOLS` | No | all tools | Comma-separated allowlist of tools to expose (see [Restrict tools](#restrict-tools)). | | `FOREST_AGENT_URL` | No | your environment's back-end URL | URL the MCP Server uses to reach your back-end's data layer. | +| `FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS` | No | Forest Admin's own lifetime | Shortens the OAuth access token lifetime (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | +| `FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS` | No | Forest Admin's own lifetime | Shortens the time between two interactive logins (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | Set `FOREST_AGENT_URL` when the MCP Server runs next to a self-hosted back-end reachable at an internal address (e.g. `http://localhost:3310`), so tool calls hit it directly instead of the public back-end URL registered in Forest. @@ -168,6 +170,46 @@ When `enabledTools` is not set, all tools are enabled by default. `describeCollection` is always enabled, even if omitted from the list, as it is required for the MCP server to function properly. +## Token lifetimes + +The MCP server issues OAuth tokens whose lifetimes come from Forest Admin. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. + + + +```javascript Mounted on agent +agent.mountAiMcpServer({ + tokenTtl: { + accessTokenSeconds: 900, + refreshTokenSeconds: 86400, + }, +}); +``` + +```bash Standalone +FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS=900 \ + FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS=86400 \ + FOREST_ENV_SECRET=xxx FOREST_AUTH_SECRET=xxx npx forest-mcp-server +``` + + + +The two settings differ in what your users notice: + +| Setting | What it bounds | Effect on the user | +| --------------------- | --------------------------------------------------------------- | -------------------------------------------------------------- | +| `accessTokenSeconds` | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | +| `refreshTokenSeconds` | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | + +`refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. + + + Both values are upper bounds: they can only **shorten** the lifetime Forest Admin granted, never extend it. Setting a value longer than Forest Admin's own lifetime has no effect. + + + + The minimum for either value is 60 seconds; a lower value is raised to it. An invalid value (zero, negative or fractional) stops the server at startup rather than silently leaving your tokens uncapped. + + ## Connect your AI assistant Your MCP endpoint is available at `/mcp` (`/mcp` when mounted, `/mcp` when standalone). On first connection, a browser window opens for you to log in with your Forest credentials; the assistant then operates with that user's permissions. @@ -248,6 +290,7 @@ The Forest MCP server: - Uses your environment's authentication - Logs all operations for audit purposes - Never exposes sensitive data without proper access +- Lets you shorten the OAuth token lifetimes (see [Token lifetimes](#token-lifetimes)) Only provide MCP server access to trusted AI tools and users. The server can perform any operation that the authenticated user can perform. From 64ece25be0358a67a4244467477a615695a6c8d6 Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 16:13:50 +0200 Subject: [PATCH 2/6] docs(mcp-server): correct the no-effect claim for refreshTokenSeconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only accessTokenSeconds has an inert case. refreshTokenSeconds bounds the whole session, which Forest Admin re-extends on every refresh, so any value shortens it however large — stating otherwise told readers a working control does nothing. Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 75ec5ab..8703006 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -203,7 +203,7 @@ The two settings differ in what your users notice: `refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. - Both values are upper bounds: they can only **shorten** the lifetime Forest Admin granted, never extend it. Setting a value longer than Forest Admin's own lifetime has no effect. + Both values are upper bounds: they can only **shorten** what Forest Admin granted, never extend it. For `accessTokenSeconds`, a value above Forest Admin's own token lifetime has no effect. `refreshTokenSeconds` bounds the whole session, which Forest Admin otherwise re-extends on every refresh, so any value shortens it however large it is. From c736b242a1170a269d35d671e0c88430b3c474d2 Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 16:18:34 +0200 Subject: [PATCH 3/6] docs(mcp-server): state the lifetimes Forest Admin grants Without the numbers a reader cannot tell whether their value will bind. Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 8703006..363203d 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -55,8 +55,8 @@ The standalone Forest MCP Server is configured entirely through environment vari | `MCP_SERVER_PORT` | No | `3931` | Port the standalone server listens on. | | `FOREST_MCP_ENABLED_TOOLS` | No | all tools | Comma-separated allowlist of tools to expose (see [Restrict tools](#restrict-tools)). | | `FOREST_AGENT_URL` | No | your environment's back-end URL | URL the MCP Server uses to reach your back-end's data layer. | -| `FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS` | No | Forest Admin's own lifetime | Shortens the OAuth access token lifetime (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | -| `FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS` | No | Forest Admin's own lifetime | Shortens the time between two interactive logins (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | +| `FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS` | No | `3600` (1 hour) | Shortens the OAuth access token lifetime (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | +| `FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS` | No | `691200` (8 days) | Shortens the time between two interactive logins (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | Set `FOREST_AGENT_URL` when the MCP Server runs next to a self-hosted back-end reachable at an internal address (e.g. `http://localhost:3310`), so tool calls hit it directly instead of the public back-end URL registered in Forest. @@ -172,7 +172,7 @@ When `enabledTools` is not set, all tools are enabled by default. ## Token lifetimes -The MCP server issues OAuth tokens whose lifetimes come from Forest Admin. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. +The MCP server issues OAuth tokens whose lifetimes come from Forest Admin: **1 hour** (3600s) for an access token, **8 days** (691200s) for a refresh token. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. @@ -195,10 +195,10 @@ FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS=900 \ The two settings differ in what your users notice: -| Setting | What it bounds | Effect on the user | -| --------------------- | --------------------------------------------------------------- | -------------------------------------------------------------- | -| `accessTokenSeconds` | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | -| `refreshTokenSeconds` | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | +| Setting | Forest Admin default | What it bounds | Effect on the user | +| --------------------- | -------------------- | --------------------------------------------- | ----------------------------------------------------------- | +| `accessTokenSeconds` | 1 hour | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | +| `refreshTokenSeconds` | 8 days | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | `refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. From 25ff8368ac0f1d73480aeb0e05c79c6dd3d04fac Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 16:30:41 +0200 Subject: [PATCH 4/6] docs(mcp-server): the refresh default is unbounded, not 8 days Forest Admin re-grants its refresh lifetime on every refresh, so leaving refreshTokenSeconds unset means a working assistant never signs in again. Listing 8 days as the default steered readers away from the whole useful range. Also documents that refresh tokens predating the option anchor on their last refresh, giving one longer session before the bound applies. Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 363203d..1fc8dac 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -56,7 +56,7 @@ The standalone Forest MCP Server is configured entirely through environment vari | `FOREST_MCP_ENABLED_TOOLS` | No | all tools | Comma-separated allowlist of tools to expose (see [Restrict tools](#restrict-tools)). | | `FOREST_AGENT_URL` | No | your environment's back-end URL | URL the MCP Server uses to reach your back-end's data layer. | | `FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS` | No | `3600` (1 hour) | Shortens the OAuth access token lifetime (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | -| `FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS` | No | `691200` (8 days) | Shortens the time between two interactive logins (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | +| `FOREST_MCP_REFRESH_TOKEN_TTL_SECONDS` | No | unbounded | Shortens the time between two interactive logins (see [Token lifetimes](#token-lifetimes)). Minimum `60`. | Set `FOREST_AGENT_URL` when the MCP Server runs next to a self-hosted back-end reachable at an internal address (e.g. `http://localhost:3310`), so tool calls hit it directly instead of the public back-end URL registered in Forest. @@ -172,7 +172,7 @@ When `enabledTools` is not set, all tools are enabled by default. ## Token lifetimes -The MCP server issues OAuth tokens whose lifetimes come from Forest Admin: **1 hour** (3600s) for an access token, **8 days** (691200s) for a refresh token. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. +The MCP server issues OAuth tokens whose lifetimes come from Forest Admin: **1 hour** (3600s) for an access token, **8 days** (691200s) for a refresh token. Forest Admin re-grants those 8 days on *every* refresh, so without `refreshTokenSeconds` an assistant that keeps working is never asked to sign in again. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. @@ -198,9 +198,9 @@ The two settings differ in what your users notice: | Setting | Forest Admin default | What it bounds | Effect on the user | | --------------------- | -------------------- | --------------------------------------------- | ----------------------------------------------------------- | | `accessTokenSeconds` | 1 hour | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | -| `refreshTokenSeconds` | 8 days | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | +| `refreshTokenSeconds` | unbounded | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | -`refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. +`refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. Refresh tokens issued before you enabled the option carry no login timestamp, so their window is measured from their last refresh instead — one longer session each, then bounded. Both values are upper bounds: they can only **shorten** what Forest Admin granted, never extend it. For `accessTokenSeconds`, a value above Forest Admin's own token lifetime has no effect. `refreshTokenSeconds` bounds the whole session, which Forest Admin otherwise re-extends on every refresh, so any value shortens it however large it is. From 0bcdb3f2a8dbdba08cf7c8a24daae995d7367dfd Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 16:33:54 +0200 Subject: [PATCH 5/6] docs(mcp-server): say Forest, not Forest Admin Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 1fc8dac..066473d 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -172,7 +172,7 @@ When `enabledTools` is not set, all tools are enabled by default. ## Token lifetimes -The MCP server issues OAuth tokens whose lifetimes come from Forest Admin: **1 hour** (3600s) for an access token, **8 days** (691200s) for a refresh token. Forest Admin re-grants those 8 days on *every* refresh, so without `refreshTokenSeconds` an assistant that keeps working is never asked to sign in again. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. +The MCP server issues OAuth tokens whose lifetimes come from Forest: **1 hour** (3600s) for an access token, **8 days** (691200s) for a refresh token. Forest re-grants those 8 days on *every* refresh, so without `refreshTokenSeconds` an assistant that keeps working is never asked to sign in again. You can shorten them with `tokenTtl`, to reduce how long a leaked token stays usable and to force users to log in again periodically. @@ -195,7 +195,7 @@ FOREST_MCP_ACCESS_TOKEN_TTL_SECONDS=900 \ The two settings differ in what your users notice: -| Setting | Forest Admin default | What it bounds | Effect on the user | +| Setting | Forest default | What it bounds | Effect on the user | | --------------------- | -------------------- | --------------------------------------------- | ----------------------------------------------------------- | | `accessTokenSeconds` | 1 hour | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | | `refreshTokenSeconds` | unbounded | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | @@ -203,7 +203,7 @@ The two settings differ in what your users notice: `refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. Refresh tokens issued before you enabled the option carry no login timestamp, so their window is measured from their last refresh instead — one longer session each, then bounded. - Both values are upper bounds: they can only **shorten** what Forest Admin granted, never extend it. For `accessTokenSeconds`, a value above Forest Admin's own token lifetime has no effect. `refreshTokenSeconds` bounds the whole session, which Forest Admin otherwise re-extends on every refresh, so any value shortens it however large it is. + Both values are upper bounds: they can only **shorten** what Forest granted, never extend it. For `accessTokenSeconds`, a value above Forest's own token lifetime has no effect. `refreshTokenSeconds` bounds the whole session, which Forest otherwise re-extends on every refresh, so any value shortens it however large it is. From c2f90df858039a90b9e955f6ab203ff71cde1bda Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Tue, 28 Jul 2026 16:44:10 +0200 Subject: [PATCH 6/6] docs(mcp-server): scope what accessTokenSeconds actually protects The signed JWT carries the Forest token, so a leak stays exploitable against the agent past the cap. Say so rather than implying the cap bounds the leak. Co-Authored-By: Claude Opus 5 (1M context) --- product/embed/mcp-server.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 066473d..aaff870 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -197,7 +197,7 @@ The two settings differ in what your users notice: | Setting | Forest default | What it bounds | Effect on the user | | --------------------- | -------------------- | --------------------------------------------- | ----------------------------------------------------------- | -| `accessTokenSeconds` | 1 hour | How long an issued access token stays usable | None — the AI assistant silently obtains a new one | +| `accessTokenSeconds` | 1 hour | How long an issued access token drives the MCP server | None — the AI assistant silently obtains a new one | | `refreshTokenSeconds` | unbounded | The time between two **interactive logins** | Once it elapses, the user logs in through the browser again | `refreshTokenSeconds` is measured from the login itself, not from the last refresh, so an assistant that keeps working cannot keep extending its own session. Refresh tokens issued before you enabled the option carry no login timestamp, so their window is measured from their last refresh instead — one longer session each, then bounded. @@ -206,6 +206,10 @@ The two settings differ in what your users notice: Both values are upper bounds: they can only **shorten** what Forest granted, never extend it. For `accessTokenSeconds`, a value above Forest's own token lifetime has no effect. `refreshTokenSeconds` bounds the whole session, which Forest otherwise re-extends on every refresh, so any value shortens it however large it is. + + `accessTokenSeconds` bounds what a leaked token can do through the MCP server — its scopes stop applying and its calls stop being audited. It does **not** shorten the Forest token carried inside that JWT, which is signed rather than encrypted: treat a leak as a Forest token leak and revoke at the source. + + The minimum for either value is 60 seconds; a lower value is raised to it. An invalid value (zero, negative or fractional) stops the server at startup rather than silently leaving your tokens uncapped.