McpEssentials.Cosmos is the authenticated task store for hosts that already run Azure Cosmos DB for NoSQL. It subclasses McpTaskStoreBase and persists StoredMcpTask snapshots as documents.
Prefer this over Entity Framework Core with UseCosmos when you want in-partition point reads and native document TTL. Cosmos expires documents; the request-path sweep is off by default.
Partition by owner
Task documents live under
/ownerUserId. Client-facing get is a point read.Native document TTL
ttl is DiscardAfter as whole seconds. AutoSweep stays off.Index for complete
McpTaskIndex maps taskId → ownerUserId so background complete still finds the row.CosmosClient. This package ships the store and registration. Register the client as a singleton.
Install
1
Add the package
2
Register the client
Pass
CosmosMcpTaskStore.DefaultClientOptions(). The Cosmos SDK default serializer is Newtonsoft; without these options, id / ttl / camelCase enum names on task documents do not map.Wire the store
Same identity factory as Authenticated tasks. Cosmos has no generic context type, so the MCP builder method isWithCosmosTasks rather than WithTasksPlus<TContext>.
- HTTP
- Stdio
- Store only
Containers and TTL
CreateTaskAsync writes the task, then the index. If the index write fails, the task document is deleted. Client-facing get/cancel/resolve are in-partition. Background complete/fail/input-request read the index first, then point-read the task.
DiscardAfter is stamped at write as CreatedAt + 2×TimeToLive. The document ttl property is that instant as whole seconds from now (at least 1). The index row gets the same ttl so it does not outlive the task. Unlimited TTL (null) leaves both documents until a terminal owner get (ServeAndDrop) or an explicit delete.
Both containers enable per-document TTL (DefaultTimeToLive = -1). AutoSweep defaults to false. SweepExpiredAsync is a no-op; Cosmos owns expiry. Per-row get still honors ShouldDiscard so a custom clock can drop a document before Cosmos does.
On first use the store creates the database and containers when they are missing. Default throughput is 400 RU/s (CosmosMcpTaskStoreOptions.Throughput).
Serverless accounts should pre-create the containers and set
Throughput to null.Isolation
CreateTaskAsync stamps OwnerUserId. Client-facing get/cancel/resolve require that user. Server-side complete/fail/input-request skip the live-user check. Another user’s task is not found. A missing document is not found; get does not distinguish expiry from isolation.
Updates replace the task document with an ETag IfMatch. A terminal owner get with ServeAndDrop (default) deletes the task and the index row after serving it.
Do not encode the user id in the task id.
Events
v1 does not subscribe to the change feed. After a successful resolve, the node raisesInputResponseReceived locally.
Related
Sample
Runnable host. Expects the emulator at
https://localhost:8081/.Stores
Pick a backing store by the engine you already run.
Entity Framework Core
Stay on EF when the host already maps Cosmos with
UseCosmos.Authenticated tasks
Identity factory, isolation rules, and the in-memory store.