In-Memory Caching

When an AI model executes repeated analytical tasks, database queries, or expensive computations with identical arguments, re-running the handler wastes resources and adds latency.

mcponce provides a zero-dependency, ultra-fast in-memory LRU (Least Recently Used) cache built directly into the tool execution lifecycle, achieving over 5,500 operations per second on cache hits with near-instant sub-millisecond response times.


Quick Configuration #

Enable caching on any tool by passing cache: true or providing a detailed ToolCacheConfig object:

app.tool({
name: 'get_exchange_rates',
description: 'Fetches currency exchange rates from foreign API',
inputSchema: {
base: { type: 'string', default: 'USD' }
},
// Automatically caches up to 100 entries for 60 seconds
cache: true,
handler: async ({ base }) => {
const res = await fetch(`https://api.exchangerate.host/latest?base=${base}`);
return res.json();
}
});

Configuration Options #

The cache option accepts either a boolean or ToolCacheConfig:

OptionTypeDefaultDescription
cacheboolean | ToolCacheConfigfalseEnables response caching when set to true or an object.
ttlMsnumber60000 (1m)Time-to-live in milliseconds before a cached item expires.
maxSizenumber100Maximum number of entries. Oldest entries are evicted first.
keyGenerator(args) => stringundefinedCustom hashing function. If omitted, args are recursively sorted and serialized.
Deterministic Default Keys

When keyGenerator is omitted, mcponce uses a fast, recursive canonical serializer that alphabetizes dictionary keys. { a: 1, b: 2 } and { b: 2, a: 1 } generate identical cache keys.


Cache Invalidation & Eviction #

1. Invalidation via Tool Context #

Every tool handler receives context.clearCache(toolName?) to evict cached data upon write or update operations:

TYPESCRIPT
app.tool({
  name: 'update_customer_status',
  description: 'Updates a customer and invalidates their cached profile',
  inputSchema: {
    customerId: { type: 'string', required: true },
    status: { type: 'string', required: true }
  },
  handler: async ({ customerId, status }, context) => {
    await db.customers.update({ id: customerId }, { status });

    // Evicts cached entries for 'get_customer_profile'
    const evictedCount = context.clearCache('get_customer_profile');

    return { 
      success: true, 
      invalidatedEntries: evictedCount 
    };
  }
});
Clearing All Caches

Calling context.clearCache() without arguments clears all cached responses across every registered tool.

2. Programmatic Invalidation #

You can clear cache entries at any time via the main app instance:

TYPESCRIPT
// Clear specific tool cache
const evicted = app.clearCache('query_vector_db');

// Clear all tool caches
const totalEvicted = app.clearCache();

Bypassing Cache per Invocation #

Callers can bypass the cache and force a fresh execution using options or CLI flags:

// Bypass cache for a single programmatic call
const result = await app.callTool('get_exchange_rates', { base: 'USD' }, {
noCache: true // or bypassCache: true
});

Telemetry & Cache Statistics #

mcponce tracks detailed cache metrics automatically. View them via:

TYPESCRIPT
const analytics = app.getAnalytics();

console.log(analytics.summary.cachedInvocations); // Total cache hits
console.log(analytics.tools['get_exchange_rates'].cacheHits);
Updated