Repository navigation
Conversation
…ent stores
Add two entry points that implement more TanStack AI 1.x backend contracts
on Upstash Redis:
- ./sandbox: upstashSandboxCheckpointStore (SandboxCheckpointStore with
forkFromCheckpoint) and upstashSandboxInstanceStore. They pass
runSandboxCheckpointStoreConformance, runSandboxCheckpointForkConformance
and runSandboxInstanceStoreConformance. The run store also passes
runDurableRunFieldsConformance.
- ./mcp: upstashMcpTaskStore (createMCPServer taskStore) and
upstashMcpEventStore (MCP Events direct mode).
upstashPersistence({ bucket }) now returns a required blobs store in its
type, so it plugs straight into createSandboxSnapshots.
Optional peers: @tanstack/ai-sandbox and @tanstack/ai-mcp >=1.0.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CMK4etJMDDBFkjEyWDVCdy
This was referenced Nov 11, 2026
McpServerDescriptor carries functions and objects (needsApproval, toolFilter, toolName, a transport's fetch and authProvider) that cannot be stored in Redis. So set() stores the JSON part and records which code-only fields were dropped. get() takes them from a user-supplied resolve() callback. get() fails closed: if a recorded field is still missing, it returns null, so createMcpAppCallHandler falls back to its registry or refuses the call. A widget can never reach a server that lost its approval gate. Transport headers and stdio env can be encrypted at rest with AES-256-GCM, bound to the prefix, thread and server. The helpers move to src/secret-box.ts, which the BYOK credential store now shares. The TTL slides like the in-memory store's (1800 s by default). An end-to-end test drives createMcpAppCallHandler against a real MCP server over HTTP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMK4etJMDDBFkjEyWDVCdy
…fore the first poll subscribe() took its baseline from its first poll, which runs after subscribe returns. A write from another machine in between became the baseline and was never reported. Start each watch from this store's own last write to the log instead.
2.44.3 exits with code 1 and no output, even for --help, so the e2e failed before it started.
latest points to a working release again.
… into fix/stack-102-ci # Conflicts: # CLAUDE.md
- MCP sessions: with encryptionKey, seal each stored entry whole, so a Redis writer cannot change the server url or strip the fail-closed field list - MCP events: revisions come from one counter, so a stale update cannot match a deleted and re-created subscription; drop the key-to-id hash - fork: write the transcript first, so a failing JSON.SET leaves nothing half-written; reject a non-integer messagesTtlSeconds - sandbox validation: keep only the checks this store relies on - BYOK: use the shared secretBox (same stored format)
- regression test: another store's write before the first poll is reported - drop references to the removed baseline read and header-only encryption - move the MCP session store notes in CLAUDE.md under the stores entry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack: #100 → #102 → #103 → #104 → #106. Merge in order.
Adds Upstash Redis stores for TanStack AI's sandbox and MCP packages, under two new entry points.
Sandbox snapshots (
@upstash/agentkit-tanstack-ai/sandbox)Sandbox files survive after the provider sandbox is gone, any server can resume a thread's sandbox, and you can fork a conversation (files included) from an earlier checkpoint.
MCP stores (
@upstash/agentkit-tanstack-ai/mcp)MCP tasks, event subscriptions and MCP Apps sessions are shared across instances and survive restarts.
upstashMcpSessionStore()stores MCP Apps server descriptors. Transport headers can be encrypted withencryptionKey, and code-only fields likeneedsApprovalcome back through aresolvecallback. If one is missing,getreturnsnull, so a widget never reaches a server without its approval gate.Also
upstashPersistence({ bucket })is now typed with a requiredblobsstore, so it can be passed straight tocreateSandboxSnapshots().@tanstack/ai-sandbox >=1.0.0,@tanstack/ai-mcp >=1.0.0. The root entry doesn't import them.Tested against TanStack's own sandbox conformance suites on live Redis, plus MCP store tests. Changeset: minor for
@upstash/agentkit-tanstack-ai.