--- title: "Microsoft Agent Framework memory and context providers" description: "Microsoft Agent Framework keeps a conversation in an AgentSession and adds memory through context providers. Add timestamped, source-backed recall with a Python tool or MCP." canonical: https://past.dev/integrations/microsoft-agent-framework last-updated: 2026-10-09 --- # Add memory to Microsoft Agent Framework agents Source: https://past.dev/integrations/microsoft-agent-framework Microsoft Agent Framework memory is built from sessions and context providers. An AgentSession carries one conversation between runs. Context providers run before and after each run: history providers load and store messages, and FileMemoryProvider gives the model file-based memory tools under a scope such as a user id. A Python function tool that calls past.dev over HTTP adds timestamped ingestion and recall that returns ranked documents with dates and source excerpts. ## Microsoft Agent Framework memory scope The [conversations guide](https://learn.microsoft.com/en-us/agent-framework/concepts/agents/conversations/) describes `AgentSession`: create one with `agent.create_session()`, pass it to each `run`, and serialize it with `to_dict()` to resume later. With service-managed storage, the session holds a service-side conversation id. [Context providers](https://learn.microsoft.com/en-us/agent-framework/concepts/agents/conversations/context-providers) run around each invocation. `before_run` adds instructions, messages or tools, and `after_run` processes what the run produced. `InMemoryHistoryProvider` keeps local history. `FileMemoryProvider` gives the model `file_memory_*` tools over a file store; without a `scope` its memory belongs to one session, and a stable scope such as a user id shares it across sessions. - **History is per session.** A new session starts empty unless a provider loads earlier messages. - **File memory is notes.** The model decides what to write. The files carry no documented event time or validity period. - **A custom provider is the extension point.** The documented examples load memories before a run and store new ones after it. ## The integration: two function tools A Python function passed to `tools` becomes a function tool, with parameter descriptions from `Annotated` and Pydantic `Field`. The `@tool` decorator sets the name, the description and the approval mode ([function tools](https://learn.microsoft.com/en-us/agent-framework/agents/tools/function-tools)). A `FunctionInvocationContext` parameter receives runtime values that the model never sees, so the recipe passes the user's identity through `function_invocation_kwargs`. ```python import asyncio, os, requests from typing import Annotated from pydantic import Field from agent_framework import Agent, FunctionInvocationContext, tool BASE = "https://api.past.dev/api/v1" HEADERS = {"Authorization": f"Bearer {os.environ['PAST_API_KEY']}"} @tool(approval_mode="never_require") def remember( text: Annotated[str, Field(description="Source text to store.")], happened_at: Annotated[str, Field(description="ISO 8601 time the text was written.")], ctx: FunctionInvocationContext, ) -> str: """Store timestamped source text, readable by the whole project.""" return requests.post(f"{BASE}/ingest", headers=HEADERS, json={ "content": text, "timestamp": happened_at, "identity": ctx.kwargs["user_id"], }).text @tool(approval_mode="never_require") def recall( question: Annotated[str, Field(description="The question to answer from memory.")], ctx: FunctionInvocationContext, ) -> str: """Return ranked documents with dates and source excerpts.""" return requests.post(f"{BASE}/recall", headers=HEADERS, json={ "query": question, "identity": ctx.kwargs["user_id"], }).text agent = Agent( client=client, # any Agent Framework chat client name="Assistant", instructions="Call recall before you answer questions about people, decisions or history.", tools=[remember, recall], ) async def main(): response = await agent.run( "What did we decide about the Q4 budget?", function_invocation_kwargs={"user_id": "demo-user"}, ) print(response.text) asyncio.run(main()) ``` For an agent that must read memory on every turn, a custom context provider can call the same recall endpoint in `before_run` and add the returned documents as instructions. > **Identity** > > The application sets the identity. The model never chooses it. Recall returns what the identity in the request may read, so take the identity from the signed-in user in code, and keep it out of every value that the model fills. Recall returns ranked documents with dates and source excerpts. The application decides whether those documents support an answer, contain a disagreement, or are insufficient; HTTP failures are handled separately. ## Or connect the MCP server `MCPStreamableHTTPTool` from `agent_framework` connects an agent to a remote server over Streamable HTTP; pass it through `tools` to the agent or to a run ([MCP tools](https://learn.microsoft.com/en-us/agent-framework/agents/tools/local-mcp-tools)). On a minimal Python install, install the `mcp` package first. The project's end-user MCP server then gives the agent `recall`, `answer` and `who_am_i`, plus `remember` while the project's write toggle is on, with no tool code to write. 1. Turn on the project's end-user MCP server on **Build › MCP server** in the console. 2. Mint an access link there, or with the account server's `create_mcp_access_link` tool. The link has the form `https://api.past.dev/mcp//link/`. It is one URL that is one identity, and the server answers it with no sign-in step. 3. Keep the link in a secret store, such as the `PAST_MCP_URL` environment variable that the code below reads. The secret in its path is the credential. ```python import asyncio, os from agent_framework import Agent, MCPStreamableHTTPTool async def main(): async with ( MCPStreamableHTTPTool(name="past", url=os.environ["PAST_MCP_URL"]) as past, Agent( client=client, # any Agent Framework chat client name="Assistant", instructions="Call recall before you answer questions about people, decisions or history.", ) as agent, ): result = await agent.run("What did we decide about the Q4 budget?", tools=past) print(result.text) asyncio.run(main()) ``` Every call through the link runs as its identity, with that identity's audiences. Mint one link per install, so that a revoked link stops one agent only. When the agent serves several people, mint one link per end user, and connect each request with the link of the user who makes it. Never share one link between users. `remember` writes to the identity's own private audience, and only that identity recalls it. Send data that the whole project must recall through the ingest call. The [end-user server documentation](/docs/mcp/serving-your-own-users) describes the tools, the links and revocation. ## Sessions, providers and past.dev side by side | Requirement | Agent Framework | past.dev via tool | | --- | --- | --- | | Continue a conversation | AgentSession with a history provider | No | | Notes the agent keeps for one user | FileMemoryProvider with a user scope | Recall as that user's identity | | Source records with their original dates | No documented field | `timestamp` on ingest | | What was true on a date | No documented query | `queryTimestamp` on recall | | Recall result | Defined by each provider | Ranked documents with dates and source excerpts | The [quickstart](/docs/memory-api/quickstart) shows how to ingest, wait until ingestion completes, and recall. The [benchmarks](/benchmarks) document how recall is measured. AutoGen is in maintenance mode, and the [AutoGen guide](/integrations/autogen) covers its Memory protocol. ## Frequently asked questions ### Does Microsoft Agent Framework have long-term memory? Context providers add it. FileMemoryProvider keeps model-written notes across sessions when its scope is a stable user id, and context provider integrations connect other memory services. ### Is Microsoft Agent Framework the successor to AutoGen? Yes. The AutoGen repository names Microsoft Agent Framework as its successor and links a migration guide. The past.dev tools and MCP server work in both frameworks. ## Related - [Memory for AutoGen](https://past.dev/integrations/autogen) - [Memory for the OpenAI Agents SDK](https://past.dev/integrations/openai-agents-sdk) - [Memory for LangGraph](https://past.dev/integrations/langgraph) - [Session memory](https://past.dev/glossary/session-memory) - [Quickstart](https://past.dev/docs/memory-api/quickstart)