{"id":5547,"date":"2026-06-29T03:41:33","date_gmt":"2026-06-29T10:41:33","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5547"},"modified":"2026-06-29T03:41:33","modified_gmt":"2026-06-29T10:41:33","slug":"agent-harness-working-with-your-data-safely","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-harness-working-with-your-data-safely\/","title":{"rendered":"Agent Harness: Working with your data, safely"},"content":{"rendered":"<p><em>Part 2 of <a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\/\">Build your own claw and agent harness with Microsoft Agent Framework<\/a>.<\/em><\/p>\n<p>In <a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/meet-your-agent-harness-and-claw\/\">Part 1<\/a> we stood up a harness and gave our personal finance assistant its first abilities: a custom tool, web search, and planning. It can <em>talk<\/em> about the markets &#8211; but it can&#8217;t yet touch <em>your<\/em> data, and nothing stops it from taking a sensitive action on a whim.<\/p>\n<p>This part fixes both, using three abilities that are all included in the harness:<\/p>\n<ol>\n<li><strong>File access<\/strong> &#8211; read your portfolio from a CSV and write reports back to disk.<\/li>\n<li><strong>Approvals<\/strong> &#8211; gate risky actions (like placing a trade) behind a human&#8217;s explicit OK.<\/li>\n<li><strong>Durable memory<\/strong> &#8211; remember things across sessions, in <em>two<\/em> complementary ways.<\/li>\n<\/ol>\n<p>As before, we only supply <em>what makes our agent ours<\/em>; the harness provides the machinery. Let&#8217;s take the three in turn.<\/p>\n<h2 id=\"give-it-your-data-file-access\">Give it your data: file access<\/h2>\n<p>Our assistant should work from the user&#8217;s <em>actual<\/em> holdings, not made-up numbers. The harness includes a <strong>file-access provider<\/strong> that exposes a set of <code>file_access_*<\/code> tools &#8211; list, read, write, search &#8211; over a default folder. We point it at a <code>working\/<\/code> folder that already contains a <code>portfolio.csv<\/code>.<\/p>\n<p>C#:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\r\n{\r\n    \/\/ The agent can read\/write files under this folder via the file_access_* tools.\r\n    FileAccessStore = new FileSystemAgentFileStore(Path.Combine(AppContext.BaseDirectory, \"working\")),\r\n    ChatOptions = new ChatOptions { Instructions = instructions, Tools = [\/* ... *\/] },\r\n});<\/code><\/pre>\n<p>Python:<\/p>\n<pre><code class=\"language-python\">from agent_framework import FileSystemAgentFileStore\r\n\r\nagent = create_harness_agent(\r\n    client=client,\r\n    agent_instructions=FINANCE_INSTRUCTIONS,\r\n    tools=[get_stock_price, place_trade],\r\n    # The agent can read\/write files under this folder via the file_access_* tools.\r\n    file_access_store=FileSystemAgentFileStore(\"working\"),\r\n)<\/code><\/pre>\n<p>Amongst others, the agent now has six tools &#8211; <code>file_access_read_file<\/code>, <code>file_access_save_file<\/code>, <code>file_access_list_files<\/code>, <code>file_access_list_subdirectories<\/code>, <code>file_access_search_files<\/code>, and <code>file_access_delete_file<\/code> &#8211; and we include the following instructions to tell it <em>how<\/em> to use them:<\/p>\n<blockquote><p>The user&#8217;s holdings live in a file called portfolio.csv. Read it before answering questions about their portfolio, and never modify it unless asked. When asked for a report, write it to a Markdown file (e.g. reports\/portfolio-review.md) and tell the user where you saved it.<\/p><\/blockquote>\n<p>Now <em>&#8220;What&#8217;s in my portfolio?&#8221;<\/em> reads real rows, and <em>&#8220;Write me a portfolio report and save it&#8221;<\/em> produces a file you can open.<\/p>\n<h2 id=\"gate-risky-actions-approvals\">Gate risky actions: approvals<\/h2>\n<p>Reading data is often safe. <em>Placing a trade<\/em> is never safe &#8211; that&#8217;s an action with consequences, and the agent should never take it without a human&#8217;s say-so. The harness has a built-in <strong>approval<\/strong> mechanism: mark a tool as approval-required, and the agent will <em>pause and ask<\/em> before the tool ever runs.<\/p>\n<p>We add a <code>place_trade<\/code> tool (it only simulates the order). In <strong>.NET<\/strong>, wrap it in an <code>ApprovalRequiredAIFunction<\/code>:<\/p>\n<pre><code class=\"language-csharp\">public static AIFunction CreatePlaceTradeTool() =&gt;\r\n    new ApprovalRequiredAIFunction(AIFunctionFactory.Create(PlaceTrade, \"place_trade\"));<\/code><\/pre>\n<p>In <strong>Python<\/strong>, set <code>approval_mode<\/code> on the <code>@tool<\/code> decorator:<\/p>\n<pre><code class=\"language-python\">from agent_framework import tool\r\n\r\n@tool(approval_mode=\"always_require\")\r\ndef place_trade(symbol: str, action: str, quantity: int) -&gt; str:\r\n    \"\"\"Place a (simulated) buy or sell order.\"\"\"\r\n    ...<\/code><\/pre>\n<p>When the model decides to call <code>place_trade<\/code>, the harness emits an <em>approval request<\/em> instead of running the function, and the shared console surfaces it as an <strong>Approve \/ Deny<\/strong> prompt. (The planning observers we wired up in Part 1 already include a tool approval observer, so there&#8217;s nothing extra to add.) Approve and the trade runs; deny and the agent adapts.<\/p>\n<h3 id=\"dont-ask-again-always-approve\">Don&#8217;t ask again: always-approve<\/h3>\n<p>Approving the <em>same<\/em> tool over and over is its own kind of friction. The harness has built-in support for <strong>standing approvals<\/strong> &#8211; &#8220;don&#8217;t ask me again&#8221; decisions &#8211; so once you trust a call, you won&#8217;t be pestered for it again. There are two flavours:<\/p>\n<ul>\n<li><strong>Always approve this tool (any arguments)<\/strong> &#8211; every future <code>place_trade<\/code> is approved automatically, whatever the symbol or quantity.<\/li>\n<\/ul>\n<ul>\n<li><strong>Always approve this tool with these arguments<\/strong> &#8211; only calls whose arguments <em>exactly match <\/em>the one you approved are auto-approved; a different symbol or quantity still prompts.<\/li>\n<\/ul>\n<p>These rules are recorded in the <strong>session state<\/strong>, so they last for the <strong>duration of the session<\/strong> &#8211; not baked into the agent, and not leaked into a brand-new session. Because they live in the session, they travel with it: <code>\/session-export<\/code> and <code>\/session-import<\/code> carry your standing approvals across a restart, just like memory.<\/p>\n<p>When using the sample console, its approval prompt already offers all four options out of the box:<\/p>\n<pre><code class=\"language-text\">\ud83d\udd10 Tool approval: place_trade(symbol: \"MSFT\", action: \"buy\", quantity: 10)\r\n  &gt; Approve this call\r\n    Always approve this tool (any arguments)\r\n    Always approve this tool with these arguments\r\n    Deny<\/code><\/pre>\n<p>Pick one of the <em>Always approve<\/em> options and the harness remembers it for the rest of the session; subsequent matching calls sail through without a prompt.<\/p>\n<h3 id=\"keep-the-safe-path-frictionless-auto-approval\">Keep the safe path frictionless: auto-approval<\/h3>\n<p>By default every <code>file_access_*<\/code> call (even a read) asks for approval. That&#8217;s the safe default, but always prompting to <em>read<\/em> <code>portfolio.csv<\/code> gets tedious fast, and it muddies the signal when a genuinely risky call (a write, or a trade) needs your attention.<\/p>\n<p>The harness lets you supply <strong>auto-approval rules<\/strong>: heuristics that silently approve low-risk calls so only the risky ones interrupt you. The file-access provider ships a ready-made rule that auto-approves its <strong>read-only<\/strong> tools (read, list, search) while still prompting for the ones that <em>modify<\/em> the store (save and delete).<\/p>\n<p>In <strong>.NET<\/strong>, add it via <code>ToolApprovalAgentOptions.AutoApprovalRules<\/code>:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\r\n{\r\n    ToolApprovalAgentOptions = new ToolApprovalAgentOptions\r\n    {\r\n        \/\/ Auto-approve read-only file tools; saving, deleting, and place_trade still prompt.\r\n        AutoApprovalRules = [FileAccessProvider.ReadOnlyToolsAutoApprovalRule],\r\n    },\r\n    \/\/ \u2026 file access, tools \u2026\r\n});<\/code><\/pre>\n<p>In <strong>Python<\/strong>, pass <code>auto_approval_rules<\/code>:<\/p>\n<pre><code class=\"language-python\">from agent_framework import FileAccessProvider\r\n\r\nagent = create_harness_agent(\r\n    client=client,\r\n    agent_instructions=FINANCE_INSTRUCTIONS,\r\n    tools=[get_stock_price, place_trade],\r\n    file_access_store=FileSystemAgentFileStore(\"working\"),\r\n    # Auto-approve read-only file tools; saving, deleting, and place_trade still prompt.\r\n    auto_approval_rules=[FileAccessProvider.read_only_tools_auto_approval_rule],\r\n)<\/code><\/pre>\n<p>Now reading your portfolio just works, while writing a report, deleting a file, or placing a trade still pauses for your OK.<\/p>\n<h3 id=\"a-rule-of-your-own-auto-approve-small-trades\">A rule of your own: auto-approve small trades<\/h3>\n<p>A rule is just a callback over the pending function call, so you can encode whatever policy you like. A natural one for our claw: <em>auto-approve trades under $1,000, ask for the rest<\/em> &#8211; keeping only the genuinely consequential orders in front of the user. (<code>place_trade<\/code> takes a symbol and a quantity, so we estimate the order value from the current price.)<\/p>\n<p>In <strong>.NET<\/strong>, a rule is a <code>Func&lt;FunctionCallContent, ValueTask&lt;bool&gt;&gt;<\/code>:<\/p>\n<pre><code class=\"language-csharp\">\/\/ Returns true to auto-approve; false falls through to the normal approval prompt.\r\nstatic async ValueTask&lt;bool&gt; AutoApproveSmallTrades(FunctionCallContent call)\r\n{\r\n    if (call.Name != \"place_trade\" || call.Arguments is null)\r\n    {\r\n        return false; \/\/ Not our tool \u2014 let it prompt as usual.\r\n    }\r\n\r\n    var symbol = call.Arguments[\"symbol\"]?.ToString();\r\n    var quantity = Convert.ToInt32(call.Arguments[\"quantity\"]);\r\n    var estimate = quantity * await GetPriceAsync(symbol!); \/\/ your own pricing logic\r\n\r\n    return estimate &lt; 1000m; \/\/ under $1,000 \u2192 auto-approve\r\n}\r\n\r\n\/\/ Wire it in alongside the read-only rule:\r\nAutoApprovalRules = [FileAccessProvider.ReadOnlyToolsAutoApprovalRule, AutoApproveSmallTrades],<\/code><\/pre>\n<p>In <strong>Python<\/strong>, a rule is a callable taking the function call (sync or async both work):<\/p>\n<pre><code class=\"language-python\">async def auto_approve_small_trades(call: FunctionCallContent) -&gt; bool:\r\n    \"\"\"Return True to auto-approve; False falls through to the normal prompt.\"\"\"\r\n    if call.name != \"place_trade\":\r\n        return False  # Not our tool \u2014 let it prompt as usual.\r\n\r\n    args = call.parse_arguments() or {}\r\n    estimate = int(args.get(\"quantity\", 0)) * await get_price(args[\"symbol\"])  # your pricing logic\r\n\r\n    return estimate &lt; 1000  # under $1,000 -&gt; auto-approve\r\n\r\n\r\n# Wire it in alongside the read-only rule:\r\nauto_approval_rules=[\r\n    FileAccessProvider.read_only_tools_auto_approval_rule,\r\n    auto_approve_small_trades,\r\n],<\/code><\/pre>\n<p>Rules are evaluated in order; the first to return <code>true<\/code> wins, and returning <code>false<\/code> simply lets the next rule (or the manual prompt) take over.<\/p>\n<h2 id=\"remember-across-sessions-durable-memory\">Remember across sessions: durable memory<\/h2>\n<p>Our claw should remember the user&#8217;s watchlist and the things they tell us about themselves &#8211; <em>across<\/em> sessions, not just within one. In this post we demonstrate <strong>two kinds of memory<\/strong>, and they&#8217;re deliberately different:<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th><strong>File memory<\/strong><\/th>\n<th><strong>Foundry memory<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Granularity<\/td>\n<td>Coarse &#8211; whole files<\/td>\n<td>Fine &#8211; individual facts<\/td>\n<\/tr>\n<tr>\n<td>Written by<\/td>\n<td>The agent, <em>explicitly<\/em> (it decides to save a file)<\/td>\n<td>Microsoft Foundry, <em>automatically<\/em> (facts are extracted)<\/td>\n<\/tr>\n<tr>\n<td>Good for<\/td>\n<td>Documents the agent curates: a watchlist, notes, drafts<\/td>\n<td>Ambient facts: &#8220;prefers low-risk ETFs&#8221;, &#8220;saving for a house&#8221;<\/td>\n<\/tr>\n<tr>\n<td>Where it lives<\/td>\n<td>A folder you control<\/td>\n<td>A managed Foundry memory store<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You usually want <strong>both<\/strong>: file memory for things the agent deliberately maintains, and Foundry memory for the small facts that should just <em>stick<\/em> without anyone managing a file.<\/p>\n<h3 id=\"file-memory-coarse-explicit\">File memory (coarse, explicit)<\/h3>\n<p>File memory is a harness <strong>built-in<\/strong> &#8211; it&#8217;s on by default, and you never construct or inject the provider yourself. The agent gets a set of <code>file_memory_*<\/code> tools and decides, on its own, when to write a file like <code>watchlist.md<\/code>.<\/p>\n<p>Its files live on disk under the configured working folder, in a sub-folder keyed by <strong>session id<\/strong> (by default <code>{cwd}\/agent-file-memory\/&lt;session-id&gt;\/<\/code>). That means the files <strong>persist across runs on the same machine<\/strong> automatically. A brand-new session gets a new id &#8211; and so starts with empty memory. You may configure the root folder under which these session-specific sub-folders are created by supplying a file memory store with a specific path.<\/p>\n<p>To pick the memory back up after a console app restart, save and reload the session with the console&#8217;s session commands (the same save\/resume flow from <a href=\".\/01-meet-your-claw.html#save-and-resume-a-session\">Part 1<\/a>):<\/p>\n<pre><code class=\"language-text\">\/session-export my-finance-session.json     # before you quit\r\n\/session-import my-finance-session.json     # after you relaunch<\/code><\/pre>\n<p>The export file holds the <strong>session state<\/strong> (including its id and conversation), not the memory files themselves. Re-importing restores the session&#8217;s identity, so the relaunched session re-links to its still-on-disk memory files. On a fresh checkout or a different machine you&#8217;d also copy the <code>agent-file-memory<\/code> folder for the files to come along.<\/p>\n<p>You don&#8217;t need to set anything up for the default behavior. If you want the memory files to land in a specific folder, point the store there &#8211; in <strong>.NET<\/strong> with <code>HarnessAgentOptions.FileMemoryStore<\/code>:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\r\n{\r\n    FileMemoryStore = new FileSystemAgentFileStore(Path.Combine(AppContext.BaseDirectory, \"agent-memory\")),\r\n    \/\/ \u2026 file access, tools \u2026\r\n});<\/code><\/pre>\n<p>and in <strong>Python<\/strong> with the <code>file_memory_store<\/code> argument:<\/p>\n<pre><code class=\"language-python\">from agent_framework import FileSystemAgentFileStore\r\n\r\nagent = create_harness_agent(\r\n    ...,\r\n    file_memory_store=FileSystemAgentFileStore(\"agent-memory\"),\r\n)<\/code><\/pre>\n<h3 id=\"foundry-memory-fine-automatic\">Foundry memory (fine, automatic)<\/h3>\n<p>Foundry memory works differently: you don&#8217;t tell the agent, and it does not decide to &#8220;save&#8221; anything. As the conversation flows, <strong>Microsoft Foundry extracts durable facts<\/strong> and recalls the relevant ones on later turns &#8211; even in a brand-new session. Because it needs a memory store and an embedding model, we make it <strong>opt-in<\/strong> via environment variables, so the sample still runs without that setup.<\/p>\n<blockquote><p>For more on Foundry memory, see <a href=\"https:\/\/learn.microsoft.com\/azure\/foundry\/agents\/concepts\/what-is-memory\">What is memory?<\/a> and <a href=\"https:\/\/learn.microsoft.com\/azure\/foundry\/agents\/how-to\/memory-usage?pivots=csharp\">Use memory<\/a>. Foundry memory is currently only available in <strong>certain regions<\/strong>, so check that your Foundry project is in a supported region before relying on it.<\/p><\/blockquote>\n<p>In <strong>.NET<\/strong>, create a <code>FoundryMemoryProvider<\/code> scoped to a user and add it to the agent&#8217;s context providers:<\/p>\n<pre><code class=\"language-csharp\">var foundryMemory = new FoundryMemoryProvider(\r\n    projectClient,\r\n    memoryStoreName,\r\n    stateInitializer: _ =&gt; new(new FoundryMemoryProviderScope(\"claw-sample-user\")));\r\n\r\nawait foundryMemory.EnsureMemoryStoreCreatedAsync(deploymentName, embeddingModel, \"\u2026\");\r\n\r\nAIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\r\n{\r\n    AIContextProviders = [foundryMemory],\r\n    \/\/ \u2026 file access, file memory, tools \u2026\r\n});<\/code><\/pre>\n<p>In <strong>Python<\/strong>, it&#8217;s another context provider:<\/p>\n<pre><code class=\"language-python\">from agent_framework.foundry import FoundryMemoryProvider\r\n\r\nfoundry_memory = FoundryMemoryProvider(\r\n    project_client=project_client,\r\n    memory_store_name=store_name,\r\n    scope=\"claw-sample-user\",\r\n    update_delay=0,\r\n)\r\n\r\nagent = create_harness_agent(\r\n    ...,\r\n    context_providers=[foundry_memory],\r\n)<\/code><\/pre>\n<p>Now tell the assistant <em>&#8220;I&#8217;m a conservative investor saving for a house in two years&#8221;<\/em> in one session, restart, and ask <em>&#8220;What do you know about me?&#8221;<\/em> &#8211; it remembers, because Foundry quietly stored the fact and recalled it.<\/p>\n<h2 id=\"run-it\">Run it<\/h2>\n<p><strong>.NET<\/strong><\/p>\n<pre><code class=\"language-bash\">cd dotnet\r\ndotnet run --project samples\/02-agents\/Harness\/BuildYourOwnClaw\/Claw_Step02_WorkingWithData<\/code><\/pre>\n<p><strong>Python<\/strong><\/p>\n<pre><code class=\"language-bash\">uv run python\/samples\/02-agents\/harness\/build_your_own_claw\/claw_step02_working_with_data.py<\/code><\/pre>\n<p>Then try these in order (the sample starts in <strong>execute<\/strong> mode &#8211; quick lookups don&#8217;t need a plan):<\/p>\n<ol>\n<li><code>What's in my portfolio?<\/code> &#8211; the agent reads <code>portfolio.csv<\/code> with the file_access tools.<\/li>\n<li><code>Write me a short report on my portfolio and save it.<\/code> &#8211; it drafts the report, then <em>prompts you to approve the save<\/em> (writes aren&#8217;t auto-approved), and on approval writes a Markdown file under <code>working\/<\/code>.<\/li>\n<li><code>I'm a conservative investor saving for a house in two years.<\/code> &#8211; a durable fact, remembered by Foundry memory (when enabled).<\/li>\n<li><code>Buy 10 shares of MSFT.<\/code> &#8211; the agent calls <code>place_trade<\/code>; <strong>you&#8217;re prompted to approve or deny <\/strong>before anything happens.<\/li>\n<li><code>Add SPY to my watchlist.<\/code> &#8211; saved to <code>watchlist.md<\/code> in file memory.<\/li>\n<\/ol>\n<p>To see memory persist across a relaunch, ask <em>&#8220;What&#8217;s on my watchlist?&#8221;<\/em> or <em>&#8220;What do you know about me?&#8221;<\/em> after restarting:<\/p>\n<ul>\n<li><strong>Foundry memory<\/strong> (when enabled) recalls the facts about you in <em>any<\/em> new session &#8211; it&#8217;s scoped to the hardcoded &#8220;claw-sample-user&#8221; scope, not the session.<\/li>\n<\/ul>\n<ul>\n<li><strong>File memory<\/strong> (the watchlist) lives on disk keyed by session id in <strong>both languages<\/strong>, so <code>\/session-export<\/code> before you quit and <code>\/session-import<\/code> after relaunching to re-link the relaunched session to its files.<\/li>\n<\/ul>\n<h2 id=\"the-runnable-samples\">The runnable samples<\/h2>\n<ul>\n<li><strong>.NET:<\/strong> <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/02-agents\/Harness\/BuildYourOwnClaw\/Claw_Step02_WorkingWithData\"><code>dotnet\/samples\/02-agents\/Harness\/BuildYourOwnClaw\/Claw_Step02_WorkingWithData<\/code><\/a><\/li>\n<li><strong>Python:<\/strong> <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/blob\/main\/python\/samples\/02-agents\/harness\/build_your_own_claw\/claw_step02_working_with_data.py\"><code>python\/samples\/02-agents\/harness\/build_your_own_claw<\/code><\/a><\/li>\n<\/ul>\n<h2 id=\"use-these-building-blocks-in-your-own-agent\">Use these building blocks in your own agent<\/h2>\n<p>The harness assembles all of this for you, but none of it is locked inside the harness. Each feature is a plain <strong>context provider<\/strong>, <strong>middleware<\/strong>, or <strong>agent decorator<\/strong> that you can pick up on its own and add to agent &#8211; so even if you don&#8217;t adopt the full harness, you can reuse exactly the pieces you need. Here&#8217;s where to find them:<\/p>\n<table>\n<thead>\n<tr>\n<th>Feature<\/th>\n<th>.NET (type \u2014 namespace)<\/th>\n<th>Python (import)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>File access<\/strong><\/td>\n<td><code>FileAccessProvider<\/code> \u2014 <code>Microsoft.Agents.AI<\/code><\/td>\n<td><code>from agent_framework import FileAccessProvider<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Approvals<\/strong> (don&#8217;t-ask-again, auto-approval rules)<\/td>\n<td><code>ToolApprovalAgent<\/code> \/ <code>ToolApprovalAgentOptions<\/code>, via <code>builder.UseToolApproval(...)<\/code> \u2014 <code>Microsoft.Agents.AI<\/code><\/td>\n<td><code>from agent_framework import ToolApprovalMiddleware, ToolApprovalRuleCallback<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>File memory<\/strong><\/td>\n<td><code>FileMemoryProvider<\/code> \u2014 <code>Microsoft.Agents.AI<\/code><\/td>\n<td><code>from agent_framework import FileMemoryProvider<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Foundry memory<\/strong><\/td>\n<td><code>FoundryMemoryProvider<\/code> \u2014 <code>Microsoft.Agents.AI.Foundry<\/code><\/td>\n<td><code>from agent_framework.foundry import FoundryMemoryProvider<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In <strong>.NET<\/strong>, file access, approvals, and file memory ship in the <code>Microsoft.Agents.AI<\/code> package, and Foundry memory in <code>Microsoft.Agents.AI.Foundry<\/code>. In <strong>Python<\/strong>, the first three come from the <code>agent-framework<\/code> package and Foundry memory from <code>agent-framework-foundry<\/code>. The providers plug in through an agent&#8217;s context providers, the approval pieces through middleware &#8211; the same wiring the harness does on your behalf.<\/p>\n<h2 id=\"whats-next\">What&#8217;s next<\/h2>\n<p>Our claw now works with your data, asks before it acts, and remembers what matters. Next we make it <em>more capable<\/em>: <strong>skills<\/strong> it can load on demand (including Foundry-managed skills), <strong>background agents<\/strong> for concurrent work, <strong>shell access<\/strong> to reorganize files, and <strong>CodeAct<\/strong> for computation it can write and run itself.<\/p>\n<h2 id=\"the-series\">\ud83d\udcda The series<\/h2>\n<p>Part of <strong>Build your own claw and agent harness with Microsoft Agent Framework<\/strong>:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\">Overview: Build your own claw and agent harness with Microsoft Agent Framework<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/meet-your-agent-harness-and-claw\/\">Part 1 &#8211; Meet your agent harness and claw<\/a><\/li>\n<li><strong>Part 2 &#8211; Working with your data, safely<\/strong> <em>(you are here)<\/em><\/li>\n<li>Part 3 &#8211; Scaling its capabilities <em>(coming soon)<\/em><\/li>\n<li>Part 4 &#8211; Production-ready <em>(coming soon)<\/em><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Part 2 of Build your own claw and agent harness with Microsoft Agent Framework. In Part 1 we stood up a harness and gave our personal finance assistant its first abilities: a custom tool, web search, and planning. It can talk about the markets &#8211; but it can&#8217;t yet touch your data, and nothing stops [&hellip;]<\/p>\n","protected":false},"author":162052,"featured_media":5553,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,143,33],"tags":[],"class_list":["post-5547","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-agent-framework","category-python"],"acf":[],"blog_post_summary":"<p>Part 2 of Build your own claw and agent harness with Microsoft Agent Framework. In Part 1 we stood up a harness and gave our personal finance assistant its first abilities: a custom tool, web search, and planning. It can talk about the markets &#8211; but it can&#8217;t yet touch your data, and nothing stops [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/162052"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5547"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5547\/revisions"}],"predecessor-version":[{"id":5573,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5547\/revisions\/5573"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5553"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}