Odel
OfficeAgent.NET

OfficeAgent.NET

Local
@ilia-sokolov21C#MITUpdated Today

Create and edit real Word documents (filesystem or SharePoint): typed change plans, tracked changes

OfficeAgent.NET

build NuGet downloads license

OfficeAgent.NET translates an AI agent’s intent into controlled changes to Microsoft Word documents and PowerPoint decks. The agent proposes a typed edit plan; the library validates and applies it while preserving document features such as styles and comments. Word edits can be recorded as tracked changes for human review, while structured document operations can reduce token use compared with processing entire files.

OfficeAgent.NET finds, previews, and applies a contract edit as a tracked change in Word.

What this project does

A .docx or .pptx file is a package of related XML parts. A small text change can affect runs, styles, numbering, comments, content controls, or revision markup. OfficeAgent.NET handles that document-specific work. The model works with structured document data and JSON-serialisable operations such as "replace this clause as a tracked change" or "add a row to this table."

The same engine is available in three forms:

  • an MCP server for agents that support the Model Context Protocol;
  • tools for Microsoft Agent Framework and Microsoft.Extensions.AI;
  • a .NET API for applications that want to control the workflow directly.

It supports Word .docx files and PowerPoint .pptx decks; one client serves both, routing each document to the module that handles it. Excel is not implemented. See Scope and limitations before choosing it for a workflow that depends on Office's layout or calculation engine.

Choose a starting point

I want to...Start here
Add Word editing to a local MCP clientRun the MCP server over stdio
Connect Codex, Claude Code, Copilot Studio, or Microsoft 365 CopilotDeployment and client setup
Use OfficeAgent from C#Getting started
Add tools to a Microsoft Agent Framework agentAgent integration
Host the MCP server or use SharePointMCP server and document providers
Edit documents with no storage configuredDocuments with no storage
ContributeContributing

MCP quick start

Install the server as a .NET tool:

dotnet tool install --global OfficeAgent.Mcp

The following examples register it with Claude Code and limit its filesystem connection to one directory.

macOS/Linux:

claude mcp add \
  --env OfficeAgent__FileSystemConnections__0__ConnectionId=documents \
  --env OfficeAgent__FileSystemConnections__0__RootPath=/absolute/path/to/documents \
  --env OfficeAgent__AllowCreation=true \
  --transport stdio \
  officeagent -- officeagent-mcp --stdio

PowerShell:

claude mcp add `
  --env OfficeAgent__FileSystemConnections__0__ConnectionId=documents `
  --env OfficeAgent__FileSystemConnections__0__RootPath=C:\officeagent-documents `
  --env OfficeAgent__AllowCreation=true `
  --transport stdio `
  officeagent -- officeagent-mcp --stdio

AllowCreation is off by default and is what adds create_document; drop that line for an agent that may only edit documents that already exist.

If there is no directory to connect - documents arrive as attachments, or the host has nowhere to put a root - the server can run with no storage at all. Set EphemeralConnectionId and the server keeps documents in its own memory for the session, which the agent then edits by opaque id exactly as it would a stored document:

{ "OfficeAgent": { "EphemeralConnectionId": "session", "AllowCreation": true } }

import_document_content puts a document the host holds into the session and export_document_content takes the finished bytes back out; everything between is the ordinary tool surface. AllowInlineContent is the other option - three tools that carry the document as base64 in both directions, holding no state - and it suits a single self-contained call rather than a sequence of edits. Both settings work as environment variables or in a configuration file. See Documents with no storage for which to use and why it matters.

Run claude mcp list to confirm that officeagent is connected. Then ask the client to edit a file in the configured directory, for example:

Change the payment terms in contract.docx from 30 to 45 days.

The server exposes tools to register, create, inspect, search, preview, and apply edits. Asking for a document that does not exist yet - "draft a project brief in brief.docx" - creates it in the configured directory rather than failing. Text replacements are tracked changes by default. A successful apply writes back to the document it edited, guarded by an optimistic version check; pass saveMode: "NewVersion" to keep the source and write a sibling such as contract.v2.docx instead.

A connection accepts .docx only until you say otherwise. To work on decks, add three more --env settings to the command above - .pptx in the extension allow-list, and a Direct default change mode, because a deck has no redline vocabulary and refuses tracked changes:

OfficeAgent__FileSystemConnections__0__AllowedExtensions__0=.docx
OfficeAgent__FileSystemConnections__0__AllowedExtensions__1=.pptx
OfficeAgent__FileSystemConnections__0__DefaultChangeMode=Direct

Past one or two settings, put them in a file instead and point the server at it with --config - the same OfficeAgent section, where a list is a list:

{
  "OfficeAgent": {
    "AllowCreation": true,
    "FileSystemConnections": [
      {
        "ConnectionId": "documents",
        "RootPath": "C:\\officeagent-documents",
        "AllowedExtensions": [ ".docx", ".pptx" ],
        "DefaultChangeMode": "Direct"
      }
    ]
  }
}
claude mcp add --transport stdio officeagent -- officeagent-mcp --stdio --config ./officeagent.json

Environment variables still override the file, so a container can keep setting one value without restating the rest. See Deployment and client setup and MCP server for where the file is looked for.

OfficeAgent does not send the complete .docx package through the model, but the MCP client and model do receive document text and structure returned by the inspect and find tools. Only connect document folders and model providers that are appropriate for the data you are processing.

Configuration for other clients, streamable HTTP hosting, containers, and SharePoint is in Deployment and client setup. The server does not provide an authentication layer for HTTP hosting; put it behind the authentication and network controls appropriate for your environment. Filesystem roots are also trust boundaries: their ACLs must prevent untrusted principals from creating, renaming, or replacing directory entries while the server runs.

.NET quick start

Install the core package and Word module:

dotnet add package OfficeAgent.Core
dotnet add package OfficeAgent.Word

After registering services and a document provider, the edit loop looks like this:

var client = services.GetRequiredService<OfficeAgentClient>();
var doc = await client.RegisterAsync("workspace", "/srv/workspace/contract.docx");

var inspect = await client.InspectAsync("workspace", doc.ItemId);
var hit = (await client.FindAsync(
    "workspace", doc.ItemId, new FindQuery("Acme Corp"))).First();

var plan = new DocumentPlan
{
    Snapshot = inspect.Snapshot,
    Operations = new PlanOperation[]
    {
        new ChangeTextOp
        {
            Target = hit.Anchor,
            With = "Globex Inc.",
            Mode = ChangeMode.Tracked
        }
    }
};

var preview = await client.PreviewAsync("workspace", doc.ItemId, plan);
if (preview.IsValid)
    await client.CommitAsync("workspace", doc.ItemId, plan);

The complete example, including service registration and reading the saved file, is in Getting started. The minimal sample replaces the first Acme Corp with Globex Inc.. To run it, copy a Word document containing Acme Corp to contract.docx in the cloned repository root, then run:

dotnet run --project samples/QuickEdit -- ./contract.docx ./contract-edited.docx

The repository also contains a direct IChatClient Word-editing sample and an interactive Agent Framework sample.

How it works

Every edit follows the same four steps:

  1. Inspect returns a structured map of the document: its outline, paragraphs, styles, content controls, tables, images, and revisions.
  2. Find searches text and returns a content-verified anchor for each match.
  3. Preview validates a plan against the current document and reports the proposed changes without writing.
  4. Apply commits the complete plan and saves it through the configured provider.

A plan (DocumentPlan) is a typed, JSON-serialisable list of operations. An anchor records both a location and the content expected there. If the content or optional document snapshot has changed, validation fails instead of silently targeting a different location. Applying a plan is all-or-nothing.

The Word module supports changes to text, paragraphs, tables, images, styles, content controls, comment threads, footnotes and endnotes, page geometry and breaks, document properties, and tracked revisions. Every verb that changes content records a redline when the connection asks for one - an inserted clause, a deleted row and a restyled heading all come back as revisions a reviewer accepts or rejects, not only a replaced phrase. The PowerPoint module implements a broad, explicitly documented set of deck operations: text, bullets, run and paragraph formatting, template slots, style copying, tables, images, text boxes, embedded video and audio, speaker notes, resolvable comments, footers and slide numbers, sections, transitions and animations, and the slide lifecycle - adding, removing, reordering and duplicating. Several slide inserts in one plan author a deck end to end, so a single call turns nothing into a finished presentation. Any verb it does not support is named rather than silently skipped. The full operation schema is documented in Document plans, and the deck specifics in PowerPoint support.

Documents are accessed through configured providers. After registration, editing calls use a (connectionId, documentId) pair instead of a storage path or credentials. The filesystem provider restricts registrations to its root; the SharePoint provider uses the permissions of its configured identity. CreateAsync starts a new document inside a connection: the requested .docx or .pptx extension selects a registered blank-document factory. The engine applies an optional initial plan in memory, and then asks the provider to create and register it without overwriting an existing name.

Documentation

GuideCovers
Documentation hubLearning paths, package map, and the complete documentation set
Getting startedA complete edit from service registration to reading the result
ConceptsAnchors, snapshots, plans, providers, transactions, and capabilities
Document plansJSON shapes and validation rules for every operation
Document providersFilesystem, SharePoint, save modes, and custom providers
PowerPoint supportSlide addressing, the verbs the deck module implements, and what it preserves
Agent integrationMicrosoft Agent Framework and Microsoft.Extensions.AI tools
MCP serverServer configuration, transports, security notes, and tool contracts
Deployment and client setupCodex, Claude Code, Microsoft Copilot clients, containers, and Azure
OperationsConcurrency, streams, cancellation, telemetry, and production concerns
TroubleshootingStartup, registration, validation, concurrency, and provider failures
Failure modesCommon plan errors and what to do next

Contributing

Bug reports, documentation fixes, new document operations, provider integrations, and focused test cases are useful contributions. If you found a problem, open an issue with the document feature involved, the operation you attempted, and the error or unexpected result. Do not attach confidential documents; a small sanitised reproduction is enough.

To work on the code, install the .NET 8 SDK, fork the repository, and run:

dotnet build OfficeAgent.NET.sln
dotnet test OfficeAgent.NET.sln

Before starting a larger change, especially one that changes public types or the JSON wire format, open an issue so the design can be discussed. See CONTRIBUTING.md for code style, tests, and pull-request expectations.

Scope and limitations

OfficeAgent.NET edits Word .docx files and PowerPoint .pptx decks; it does not automate the Office desktop applications. An Excel module can be added through IFormatModule, but it does not ship today.

The deck module refuses the verbs a presentation has no vocabulary for - setProperty, revision, pageSetup, insertBreak and note - per operation, rather than applying part of a plan, and refuses an explicit tracked mode on any verb that carries one. PresentationML has no redline model, so tracked changes are Word-only, and a slide has no header (that is a notes and handout concept). Animations cover the effects expressible as a filtered p:animEffect; fly-in, zoom and motion paths are refused rather than approximated. See PowerPoint support for what a deck does and does not accept.

The engine does not render pages or calculate Word fields. Operations that depend on pagination, table-of-contents rendering, field recalculation, or page-fit checks are outside its scope. Preview reports structural changes, not a visual rendering of the final document. Test the workflow on representative documents and keep human review in the loop for consequential edits.

Commercial support

OfficeAgent.NET is MIT-licensed and can be self-hosted. Managed hosting and commercial support are available from dotaction: contact dotaction.

License

MIT. See LICENSE.