Skip to content

Commit 08b2a1c

Browse files
authored
Session hardening: global cap, two-tier TTL, lazy workspace (#56)
## Summary - **Global session cap** — new `server.max_sessions` config (default 1000). Returns 503 with `CapacityPayload` when exceeded on both SSE and Streamable HTTP paths. 80% capacity warning in reaper tick. - **Two-tier TTL** — new `server.session_unused_ttl_minutes` config (default 15). Sessions that never invoke a tool get the shorter TTL; sessions that have invoked a tool get `session_ttl_minutes` (default 30). "Used" is tracked via `onToolCall` callbacks wired through `createMcpServer` to all 4 tool types. - **Lazy workspace allocation** — removed eager `ensureSession()` from session init. Bash tools already call it lazily per-operation. - **Deploy configs** — all three deploy YAMLs now explicitly set `max_sessions: 1000`, `session_ttl_minutes: 30`, `session_unused_ttl_minutes: 15`. - **57 new tests** covering all three features, edge cases, backward compatibility, and SSE/Streamable HTTP parity. ## Why Production logs showed 269 concurrent SSE sessions with no global cap. A modest number of MCP clients (500 IPs × 20/IP = 10k) could exhaust memory, causing OOM → mass `unknown-session-id` 404 errors. Railway has no session affinity and a 15-min SSE hard limit. ## Test plan - [x] 1672 tests pass (57 new + 1615 existing) - [x] TypeScript clean (`tsc --noEmit`) - [x] Pre-existing `cli.test.ts` failures unrelated (missing build artifact) - [ ] Deploy to staging and verify session cap logging - [ ] Verify MCP clients reconnect cleanly after unused TTL expiry
2 parents 85d0a01 + c771b3a commit 08b2a1c

26 files changed

Lines changed: 3826 additions & 1727 deletions

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# @copilotkit/pathfinder
22

3+
## 1.13.0
4+
5+
### Minor Changes
6+
7+
- **Global Session Cap**: New `server.max_sessions` config (default: 1000). Returns HTTP 503 with `CapacityPayload` when the total concurrent session count across all IPs exceeds the cap. Logs a warning at 80% utilization.
8+
- **Two-Tier TTL**: New `server.session_unused_ttl_minutes` config (default: 15). Sessions that never invoke a tool are reaped at the shorter TTL; sessions that have invoked a tool use the existing `session_ttl_minutes` (default: 30). "Used" is tracked at the tool-invocation level, not the protocol-message level.
9+
- **Lazy Workspace Allocation**: Workspace directories are no longer created eagerly at session init. Bash tools already create them lazily per-operation, so sessions that never invoke bash tools incur zero filesystem I/O.
10+
- **Observability**: Session close logs show count as percentage of cap. Reaper tick logs show used/unused breakdown.
11+
312
## 1.12.0
413

514
### Minor Changes
@@ -95,6 +104,7 @@
95104

96105
- **Notion Data Provider**: Index Notion pages and database entries as searchable markdown documents. Recursive block-to-markdown conversion, database property serialization as YAML frontmatter, configurable page depth, self-throttled API client (340ms/req)
97106
- **Deleted Page Detection**: Two-pass incremental acquire detects pages that were deleted, archived, or had integration access revoked — removes stale chunks automatically
107+
98108
### Patch Changes
99109

100110
- Improve test coverage from 53% to 75% lines across the project (1044 → 1698 tests)

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ claude mcp add pathfinder-docs --transport http https://mcp.pathfinder.copilotki
5252

5353
Pathfinder indexes your GitHub repos — docs (Markdown, MDX, HTML) and source code — into a PostgreSQL vector database. Supports OpenAI, Ollama, and local transformers.js embeddings — no API key required for local providers. It serves configurable search and filesystem exploration tools via [MCP](https://modelcontextprotocol.io), so AI agents can search your docs semantically and browse files with bash commands.
5454

55-
| Tool Type | What It Does | Example |
56-
|-----------|-------------|---------|
57-
| **Search** | Semantic search over indexed content | `search-docs("how to authenticate")` |
58-
| **Bash** | Virtual filesystem with find, grep, cat, ls | `explore-docs("cat /docs/quickstart.mdx")` |
59-
| **Collect** | Structured data collection from agents | `submit-feedback(rating: "helpful")` |
60-
| **Knowledge** | Browse/search FAQ pairs from conversational sources | `knowledge-base("how to deploy")` |
55+
| Tool Type | What It Does | Example |
56+
| ------------- | --------------------------------------------------- | ------------------------------------------ |
57+
| **Search** | Semantic search over indexed content | `search-docs("how to authenticate")` |
58+
| **Bash** | Virtual filesystem with find, grep, cat, ls | `explore-docs("cat /docs/quickstart.mdx")` |
59+
| **Collect** | Structured data collection from agents | `submit-feedback(rating: "helpful")` |
60+
| **Knowledge** | Browse/search FAQ pairs from conversational sources | `knowledge-base("how to deploy")` |
6161

6262
## Features
6363

@@ -72,7 +72,7 @@ Pathfinder indexes your GitHub repos — docs (Markdown, MDX, HTML) and source c
7272
- **[Conversational Sources](https://pathfinder.copilotkit.dev/config)** — Slack threads and Discord forums distilled into searchable Q&A pairs
7373
- **[Auto-Generated Endpoints](https://pathfinder.copilotkit.dev/usage)**`/llms.txt`, `/llms-full.txt`, `/faq.txt`, `/.well-known/skills/default/skill.md`
7474
- **[Webhook Reindexing](https://pathfinder.copilotkit.dev/deploy)** — GitHub push triggers incremental reindex
75-
- **[IP Rate Limiting](https://pathfinder.copilotkit.dev/config)**Per-IP session caps and configurable TTL
75+
- **[Session Management](https://pathfinder.copilotkit.dev/config)**Global session cap, per-IP rate limiting, two-tier TTL (active vs unused sessions)
7676
- **[Analytics](https://pathfinder.copilotkit.dev/analytics)** — Query logging, top queries, empty results, latency metrics at `/analytics`
7777

7878
## CLI

deploy/aimock-docs.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
server:
22
name: aimock-docs
33
version: "1.0.0"
4+
max_sessions: 1000
5+
session_ttl_minutes: 30
6+
session_unused_ttl_minutes: 15
47
# Anthropic crawler — bypasses per-IP session limit (requires trust_proxy: true to match the forwarded IP)
58
allowlist: ["160.79.106.35"]
69
# Safe to enable: Railway's edge discards any client-supplied X-Forwarded-For
@@ -61,7 +64,7 @@ tools:
6164

6265
- name: explore-docs
6366
type: bash
64-
description: "Explore aimock documentation files using bash commands (find, grep, cat, ls, head). Start with 'find / -name \"*.html\" | head -20' or 'cat /INDEX.md' to see what's available."
67+
description: 'Explore aimock documentation files using bash commands (find, grep, cat, ls, head). Start with ''find / -name "*.html" | head -20'' or ''cat /INDEX.md'' to see what''s available.'
6568
sources: [docs]
6669
bash:
6770
session_state: true
@@ -70,7 +73,7 @@ tools:
7073

7174
- name: explore-code
7275
type: bash
73-
description: "Explore aimock source code using bash commands (find, grep, cat, ls, head). Start with 'find / -name \"*.ts\" | head -20' to see what's available."
76+
description: 'Explore aimock source code using bash commands (find, grep, cat, ls, head). Start with ''find / -name "*.ts" | head -20'' to see what''s available.'
7477
sources: [code]
7578
bash:
7679
session_state: true

deploy/copilotkit-docs.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
server:
22
name: copilotkit-docs-mcp
33
version: "1.0.0"
4+
max_sessions: 1000
5+
session_ttl_minutes: 30
6+
session_unused_ttl_minutes: 15
47
# Anthropic crawler — bypasses per-IP session limit (requires trust_proxy: true to match the forwarded IP)
58
allowlist: ["160.79.106.35"]
69
# Safe to enable: Railway's edge discards any client-supplied X-Forwarded-For
@@ -129,7 +132,7 @@ tools:
129132

130133
- name: explore-docs
131134
type: bash
132-
description: "Explore CopilotKit and AG-UI documentation files using bash commands (find, grep, cat, ls, head). Start with 'find / -name \"*.mdx\" | head -20' or 'cat /INDEX.md' to see what's available."
135+
description: 'Explore CopilotKit and AG-UI documentation files using bash commands (find, grep, cat, ls, head). Start with ''find / -name "*.mdx" | head -20'' or ''cat /INDEX.md'' to see what''s available.'
133136
sources: [docs, ag-ui-docs]
134137
bash:
135138
session_state: true
@@ -138,7 +141,7 @@ tools:
138141

139142
- name: explore-code
140143
type: bash
141-
description: "Explore CopilotKit and AG-UI source code files using bash commands (find, grep, cat, ls, head). Start with 'find / -name \"*.ts\" | head -20' to see what's available."
144+
description: 'Explore CopilotKit and AG-UI source code files using bash commands (find, grep, cat, ls, head). Start with ''find / -name "*.ts" | head -20'' to see what''s available.'
142145
sources: [code, ag-ui-code]
143146
bash:
144147
session_state: true

deploy/pathfinder-docs.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
server:
22
name: pathfinder-docs
33
version: "1.4.0"
4+
max_sessions: 1000
5+
session_ttl_minutes: 30
6+
session_unused_ttl_minutes: 15
47
# Anthropic crawler — bypasses per-IP session limit (requires trust_proxy: true to match the forwarded IP)
58
allowlist: ["160.79.106.35"]
69
# Safe to enable: Railway's edge discards any client-supplied X-Forwarded-For

0 commit comments

Comments
 (0)