Counting visitors…
Browse all docs
Start · 9Find your path through RunifoldLearn Runifold in 45 minutesUnderstand the complete Runifold platformYour first trustworthy runChoose the right execution APIChoose crates and Cargo featuresBuild common Runifold applicationsRunifold frequently asked questionsTroubleshoot Runifold applications
Execution kernel · 7Understand RunContextCoordinate external effects safelyBound work with budgets and cancellationHandle errors and retries safelyEvents, journals, and execution evidenceDesign capability-safe executionRecover safely from checkpoints
Models & providers · 7Route across models without duplicate outputChoose and configure a providerUse the provider-neutral model protocolBuild on the Provider Runtime contractUse OpenAI control-plane and Realtime APIsTest and benchmark provider adaptersSet up OpenAI, Anthropic, Gemini, and Ollama
Agents · 7Build and configure an AgentGive an Agent typed toolsAdd conversations and semantic memoryDelegate to child Agents safelyReturn structured Rust valuesStream without losing semanticsGround an Agent with retrieval
Durable workflows · 7Compose deterministic workflowsMake workflows durableOperate durable workflow workersCoordinate timers, signals, and durable waitsRun multi-tenant workflow infrastructureRun parallel branches and safe racesVersion and evolve durable workflows
Integrations · 7Connect through MCPChoose stores and persistence boundariesExpose durable work through MCP TasksBuild and evaluate retrieval pipelinesUse MCP Resources, Prompts, and SamplingCache MCP responses without crossing authorityDeploy Runifold in a Rust web service
Quality & operations · 10Test without the networkEvaluate quality and prevent regressionsObserve the complete run treeRun safely in browsers and at the edgeRead reliability claims preciselyRun reproducible evaluations in CIOperate Runifold with SLOsGovern Task retention and deletionArchive audit evidence to S3-compatible WORM storageManage compatibility and trusted releases
Docs/Integrations
NEW TO RUNIFOLD?Build the complete mental model in 45 minutes
Integrations

Cache MCP responses without crossing authority

Apply bounded TTLs, endpoint namespaces, private authorization partitions, pagination keys, notification invalidation, and cache modes.

Practical guide·12 min

Cacheable surface

Only protocol-defined read operations are cacheable: discovery, Tool, Prompt, Resource and Resource Template lists, plus Resource reads. Tool calls, Sampling, Tasks, elicitation, and any effectful operation are never cached.

The cache sits above transport so in-process, stdio, and Streamable HTTP share semantics. Default TTL zero and private scope preserve uncached behavior until the server opts in.

Cache key

Every key contains a host-selected trusted endpoint namespace, exact MCP method, serialized parameters including pagination cursor, and either public scope or private scope plus an authorization partition.

Server-reported identity is not a namespace. Reuse a private partition only for the same authenticated authority. Public sharing requires an explicit application decision and a shared Store plus endpoint namespace.

Modes and TTL

Use returns a fresh hit or fetches and stores. Refresh skips lookup but updates storage. Bypass performs neither. Client policy caps every server-supplied TTL; malformed, future-dated, missing, zero, or expired metadata is a miss.

TTL expiry is lazy. It must not create background polling, hidden network work, or a retry loop.

Invalidation

List-change notifications invalidate every cached page for that operation. Resource-updated invalidates the exact read URI. A rejected pagination request invalidates the operation's pages so callers cannot combine snapshots from different list generations.

Apply invalidation before delivering the notification to application subscribers.

Security invariants

  • cache keys include every request parameter and cursor;
  • private entries never cross authorization partitions;
  • server TTL cannot exceed the client cap;
  • malformed metadata fails closed as a miss;
  • effectful results never enter the cache;
  • cached content remains untrusted;
  • logout, credential rotation, and tenant switch rotate or clear private partitions;
  • cache observability excludes sensitive key material and returned content.

Configure a safe client cache

Use a stable endpoint namespace and an authorization-derived private partition. The partition must change on logout, credential rotation, or tenant switch.

use runifold_mcp::{Implementation, InMemoryResponseCache, McpClientConfig};
use std::{sync::Arc, time::Duration};
 
let config = McpClientConfig::new(Implementation::new("acme-host", "1.0.0"))
    .with_response_cache(Arc::new(InMemoryResponseCache::new(256)))
    .with_cache_namespace("https://mcp.example.com/v1")
    .with_private_cache_partition(format!("tenant:{tenant_id}:subject:{subject_id}"))
    .with_max_cache_ttl(Duration::from_secs(60));

Use CacheMode::Refresh after an operator requests fresh discovery and CacheMode::Bypass when debugging. Never build the partition from a display name or server-returned metadata. A cache hit with the wrong principal is a security incident: rotate the partition, clear the affected store, and audit which read operations used it.