A rock-solid, AOT-compatible .NET SDK for Supermemory - the AI memory layer for your applications.
- Full API Coverage - Complete access to Supermemory's Documents, Search, Memories, Connections, Settings, and Profile APIs
- AOT Compatible - Fully supports ahead-of-time compilation and trimming with zero reflection in configuration binding
- Multi-targeting - Supports .NET 8, .NET 9, and .NET 10
- Modern Configuration - Uses
IOptions<T>pattern with AOT-compatibleLoadFrom()methods for configuration from any .NET source - IHttpClientFactory - Proper HttpClient lifecycle management via typed client pattern
- Dependency Injection - First-class support for Microsoft.Extensions.DependencyInjection with
AddSupermemory()andAddSupermemoryAgent() - Microsoft Agent Framework Integration - Seamless integration with Microsoft Agent Framework for AI agents with persistent memory
- Strongly Typed - Full IntelliSense support with comprehensive XML documentation
- Exception Hierarchy - Granular exception types for precise error handling
| Package | Description |
|---|---|
| Supermemory | Core API client for Supermemory |
| CloudNimble.Agents.AI.Supermemory | Microsoft Agent Framework integration |
dotnet add package Supermemorydotnet add package CloudNimble.Agents.AI.SupermemoryThe SDK uses the standard .NET configuration pattern. Configuration can come from any source:
appsettings.json/appsettings.{Environment}.json- Environment variables (e.g.,
Supermemory__ApiKey) - User secrets (for local development)
- Azure Key Vault, AWS Secrets Manager, etc.
- Command line arguments
appsettings.json:
{
"Supermemory": {
"ApiKey": "your-api-key",
"BaseUrl": "https://api.supermemory.ai",
"Timeout": "00:01:00",
"MaxRetries": 2
}
}Or via user secrets (recommended for development):
dotnet user-secrets set"Supermemory:ApiKey""your-api-key"Or via environment variables:
# Linux/macOSexport Supermemory__ApiKey=your-api-key
# Windowsset Supermemory__ApiKey=your-api-keyusingCloudNimble.Supermemory;usingMicrosoft.Extensions.DependencyInjection;usingMicrosoft.Extensions.Hosting;varbuilder=Host.CreateApplicationBuilder(args);// Add Supermemory - configuration is automatically bound from the "Supermemory" sectionbuilder.Services.AddSupermemory();// Or with programmatic configuration overlaybuilder.Services.AddSupermemory(options =>{options.Timeout=TimeSpan.FromSeconds(120);options.MaxRetries=5;});usingvarhost=builder.Build();// Inject where neededvarclient=host.Services.GetRequiredService<SupermemoryClient>();usingCloudNimble.Supermemory;usingCloudNimble.Supermemory.Models.Documents;usingCloudNimble.Supermemory.Models.Search;// Inject via constructorpublicclassMyService(SupermemoryClientsupermemory){publicasyncTaskAddAndSearchAsync(){// Add a documentvaraddResponse=awaitsupermemory.Documents.AddAsync(newAddDocumentRequest{Content="Supermemory is the AI memory layer for your applications.",ContainerTag="my-app",Metadata=newDictionary<string,object>{["source"]="documentation",["category"]="overview"}});Console.WriteLine($"Document added: {addResponse.Id}");// Search for relevant contentvarsearchResponse=awaitsupermemory.Search.SearchDocumentsAsync(newSearchDocumentsRequest{Query="AI memory layer",Limit=5,Rerank=true});foreach(varresultinsearchResponse.Results){Console.WriteLine($"Found: {result.DocumentId} (score: {result.Score:F3})");}}}The SupermemoryClient provides access to all Supermemory API resources:
| Resource | Description |
|---|---|
client.Documents | Add, update, delete, and list documents |
client.Search | Search documents and memories with semantic search |
client.Memories | Update and forget memories |
client.Connections | Manage external connections (Notion, Google Drive, etc.) |
client.Settings | Configure organization settings |
client.Profile | Get user profiles with static and dynamic memories |
// Add a documentvarresponse=awaitclient.Documents.AddAsync(newAddDocumentRequest{Content="Your content here",ContainerTag="my-container"});// Add documents in batchvarbatchResponse=awaitclient.Documents.BatchAddAsync(newBatchAddDocumentsRequest{ContainerTag="my-container",Documents=[new(){Content="Document 1"},new(){Content="Document 2"}]});// Get a documentvardocument=awaitclient.Documents.GetAsync("document-id");// List documentsvarlist=awaitclient.Documents.ListAsync(newListDocumentsRequest{ContainerTags=["my-container"],Limit=20});// Update a documentawaitclient.Documents.UpdateAsync("document-id",newUpdateDocumentRequest{Content="Updated content"});// Delete a documentawaitclient.Documents.DeleteAsync("document-id");// Bulk deleteawaitclient.Documents.DeleteBulkAsync(newDeleteBulkRequest{ContainerTags=["container-to-delete"]});// Search documents (v3 API)varresults=awaitclient.Search.SearchDocumentsAsync(newSearchDocumentsRequest{Query="your search query",Limit=10,Rerank=true,ContainerTags=["my-container"]});// Search memories (v4 API - low latency)varmemories=awaitclient.Search.SearchMemoriesAsync(newSearchMemoriesRequest{Query="your search query",ContainerTag="my-container",SearchMode=SearchMode.Memories});// Get user profile with static and dynamic memoriesvarprofile=awaitclient.Profile.GetAsync(newProfileRequest{ContainerTags=["user-123"],Query="current context"// Optional: for contextual retrieval});Console.WriteLine("Static memories (long-term facts):");foreach(varmemoryinprofile.Profile.Static){Console.WriteLine($" - {memory}");}Console.WriteLine("Dynamic memories (recent context):");foreach(varmemoryinprofile.Profile.Dynamic){Console.WriteLine($" - {memory}");}The SDK provides a granular exception hierarchy for precise error handling:
try{varresponse=awaitclient.Documents.GetAsync("document-id");}catch(SupermemoryAuthenticationExceptionex){// 401 Unauthorized - Invalid or missing API keyConsole.WriteLine($"Authentication failed: {ex.Message}");}catch(SupermemoryNotFoundExceptionex){// 404 Not Found - Resource doesn't existConsole.WriteLine($"Document not found: {ex.Message}");}catch(SupermemoryValidationExceptionex){// 400 Bad Request - Invalid request parametersConsole.WriteLine($"Validation error: {ex.Message}");Console.WriteLine($"Details: {ex.ApiError?.Details}");}catch(SupermemoryRateLimitExceptionex){// 429 Too Many Requests - Rate limit exceededConsole.WriteLine($"Rate limited: {ex.Message}");}catch(SupermemoryApiExceptionex){// Other API errors with status codeConsole.WriteLine($"API error ({ex.StatusCode}): {ex.Message}");}catch(SupermemoryExceptionex){// Base exception for all Supermemory errorsConsole.WriteLine($"Error: {ex.Message}");}The CloudNimble.Agents.AI.Supermemory package provides seamless integration with Microsoft Agent Framework, enabling AI agents with persistent memory.
| Provider | Purpose | Supermemory APIs Used |
|---|---|---|
SupermemoryContextProvider | Semantic memory injection | Profile API + Search API |
SupermemoryChatHistoryProvider | Conversation persistence | Documents API |
usingCloudNimble.Supermemory;usingCloudNimble.Agents.AI.Supermemory;usingMicrosoft.Agents.AI;usingMicrosoft.Extensions.AI;usingMicrosoft.Extensions.DependencyInjection;usingMicrosoft.Extensions.Hosting;varbuilder=Host.CreateApplicationBuilder(args);// Add Supermemory client (binds from "Supermemory" config section)builder.Services.AddSupermemory();// Add your chat client (e.g., Azure OpenAI)builder.Services.AddSingleton<IChatClient>(sp =>sp.GetRequiredService<AzureOpenAIClient>().GetChatClient("gpt-4o-mini").AsIChatClient());// Add Supermemory-enabled agent - all configuration from appsettings.jsonbuilder.Services.AddSupermemoryAgent(configureAgent: options =>options.Name="MemoryAgent",configureContext: options =>options.EnableConversationStorage=true,configureHistory: options =>options.MaxMessages=100);usingvarhost=builder.Build();// Get the fully-configured agent from DIvaragent=host.Services.GetRequiredService<ChatClientAgent>();// Start a conversation - the agent has persistent memory across sessions!varsession=awaitagent.GetNewSessionAsync();varresponse=awaitagent.RunAsync("My name is Alice and I love cats.",session);appsettings.json:
{
"Supermemory": {
"ApiKey": "your-api-key"
},
"SupermemoryContext": {
"DefaultContainerTag": "user-{userId}",
"RetrievalStrategy": "ProfileFirst",
"SearchLimit": 5
},
"SupermemoryHistory": {
"DefaultContainerTag": "user-{userId}",
"MaxMessages": 50
}
}For scenarios where you need more control:
// Get clients from DIvarsupermemoryClient=host.Services.GetRequiredService<SupermemoryClient>();varchatClient=/* your chat client */;// Create agent with Supermemory integration manuallyvaragent=chatClient.AsAIAgent(newChatClientAgentOptions{Name="MemoryAgent",Description="An AI agent with persistent memory"}.WithSupermemory(supermemoryClient,contextOptions:newSupermemoryContextProviderOptions{DefaultContainerTag="user-{userId}",RetrievalStrategy=MemoryRetrievalStrategy.ProfileFirst,EnableConversationStorage=true},historyOptions:newSupermemoryChatHistoryProviderOptions{DefaultContainerTag="user-{userId}",MaxMessages=50}));varcontextOptions=newSupermemoryContextProviderOptions{// Container tag with template placeholdersDefaultContainerTag="tenant-{tenantId}-user-{userId}",// Memory retrieval strategyRetrievalStrategy=MemoryRetrievalStrategy.ProfileFirst,// or SearchOnly, ProfileOnly, Both// Profile API settingsUseProfileApi=true,ProfileThreshold=0.7,// Search API settingsUseSearchApi=true,SearchMode=SearchMode.Memories,SearchLimit=5,MinimumSimilarityScore=0.7,RerankResults=false,// Conversation storage (for automatic memory extraction)EnableConversationStorage=true,StorageFormat=ConversationStorageFormat.Markdown,StoreUserMessagesOnly=false,// Custom instruction templateInstructionTemplate=""" ## User Context ### Known Facts {staticMemories} ### Recent Context {dynamicMemories} ### Relevant Memories {searchMemories} """};varhistoryOptions=newSupermemoryChatHistoryProviderOptions{// Container tag for conversation isolationDefaultContainerTag="session-{sessionId}",// Message limitsMaxMessages=50,// Document storage settingsDocumentIdPrefix="chat-",StoreContextProviderMessages=false};Switch user context during a conversation:
varsession=awaitagent.GetNewSessionAsync();// Get the context providervarcontextProvider=session.GetService<SupermemoryContextProvider>();// Change container tag mid-conversationcontextProvider.ContainerTag="user-456";// Or use template resolutionvarresolver=newDefaultContainerTagResolver();contextProvider.State.ContainerTag=resolver.Resolve("tenant-{tenantId}-user-{userId}",newContainerTagContext{TenantId="acme",UserId="john"});Serialize and resume sessions:
// Serialize the sessionvarserializedSession=session.Serialize();// Store serializedSession (e.g., in Redis, database)// Later, resume the sessionvarresumedSession=awaitagent.DeserializeSessionAsync(serializedSession);// Continue the conversation with full context preservedvarresponse=awaitagent.RunAsync("What's my name?",resumedSession);| Property | Type | Default | Description |
|---|---|---|---|
ApiKey | string? | null | Your Supermemory API key (required) |
BaseUrl | string | "https://api.supermemory.ai" | API base URL |
Timeout | TimeSpan | 00:01:00 | HTTP request timeout |
MaxRetries | int | 2 | Maximum retry attempts for failed requests |
Each options class exposes a SectionName constant for the default configuration section:
| Options Class | Section Name |
|---|---|
SupermemoryClientOptions.SectionName | "Supermemory" |
SupermemoryContextProviderOptions.SectionName | "SupermemoryContext" |
SupermemoryChatHistoryProviderOptions.SectionName | "SupermemoryHistory" |
You can customize the section name:
// Use a different configuration section with programmatic overridesbuilder.Services.AddSupermemory("MyCustomSection", options =>{options.Timeout=TimeSpan.FromSeconds(120);});All configuration uses AOT-compatible manual binding via LoadFrom() methods - no reflection required:
// The SDK automatically calls LoadFrom() internally, but you can also use it directly:varoptions=newSupermemoryClientOptions();options.LoadFrom(configuration.GetSection(SupermemoryClientOptions.SectionName));The repository includes sample applications:
- CloudNimble.Supermemory.Samples.Console - Basic SDK usage examples
- CloudNimble.Agents.AI.Supermemory.Samples - Microsoft Agent Framework integration demo
Run the samples:
# Configure API key via user secretscd src/CloudNimble.Supermemory.Samples.Console
dotnet user-secrets set"Supermemory:ApiKey""your-api-key"
dotnet run
# Run the agent framework sample (requires Azure OpenAI)cd src/CloudNimble.Agents.AI.Supermemory.Samples
dotnet user-secrets set"Supermemory:ApiKey""your-api-key"
dotnet user-secrets set"AzureOpenAI:Endpoint""https://your-resource.openai.azure.com"
dotnet run- .NET 8.0, .NET 9.0, or .NET 10.0
- A Supermemory API key (Get one here)
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.