{
  "markdown": "# OfficeAgent.NET\n<!-- mcp-name: io.github.ilia-sokolov/officeagent -->\n\n[![build](https://img.shields.io/github/actions/workflow/status/ilia-sokolov/OfficeAgent.NET/build.yml?branch=main)](https://github.com/ilia-sokolov/OfficeAgent.NET/actions/workflows/build.yml)\n[![NuGet](https://img.shields.io/nuget/v/OfficeAgent.Core.svg)](https://www.nuget.org/packages/OfficeAgent.Core)\n[![downloads](https://img.shields.io/nuget/dt/OfficeAgent.Core.svg)](https://www.nuget.org/packages/OfficeAgent.Core)\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nOfficeAgent.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.\n\n\n![OfficeAgent.NET finds, previews, and applies a contract edit as a tracked change in Word.](https://raw.githubusercontent.com/ilia-sokolov/OfficeAgent.NET/main/media/demo.gif)\n\n## What this project does\n\nA `.docx` or `.pptx` file is a package of related XML parts. A small text change\ncan affect runs, styles, numbering, comments, content controls, or revision\nmarkup. OfficeAgent.NET handles that document-specific work. The model works\nwith structured document data and JSON-serialisable operations such as \"replace\nthis clause as a tracked change\" or \"add a row to this table.\"\n\nThe same engine is available in three forms:\n\n- an MCP server for agents that support the Model Context Protocol;\n- tools for Microsoft Agent Framework and `Microsoft.Extensions.AI`;\n- a .NET API for applications that want to control the workflow directly.\n\nIt supports Word `.docx` files and PowerPoint `.pptx` decks; one client serves\nboth, routing each document to the module that handles it. Excel is not\nimplemented. See [Scope and limitations](#scope-and-limitations) before choosing\nit for a workflow that depends on Office's layout or calculation engine.\n\n## Choose a starting point\n\n| I want to... | Start here |\n| --- | --- |\n| Edit my first Word document | [Your first edit](#your-first-edit) |\n| Connect Codex, Claude Code, Copilot Studio, or Microsoft 365 Copilot | [Deployment and client setup](docs/deployment.md) |\n| Use OfficeAgent from C# | [Getting started](docs/getting-started.md) |\n| Add tools to a Microsoft Agent Framework agent | [Agent integration](docs/agent-integration.md) |\n| Host the MCP server or use SharePoint | [MCP server](docs/mcp-server.md) and [document providers](docs/document-providers.md) |\n| Edit documents with no storage configured | [Documents with no storage](docs/mcp-server.md#documents-with-no-storage) |\n| Teach an agent to review documents properly | [word-document-review skill](skills/word-document-review/SKILL.md) |\n| Contribute | [Contributing](#contributing) |\n\n## Your first edit\n\nInstall the server:\n\n```bash\ndotnet tool install --global OfficeAgent.Mcp\n```\n\nMake a folder for the agent to work in and download the\n[sample contract](samples/documents/services-agreement.docx) into it — a fictional services\nagreement with a clause to change, a table, an open comment, and a pending redline:\n\n```bash\nmkdir -p ~/officeagent-documents\ncurl -Lo ~/officeagent-documents/services-agreement.docx \\\n  https://raw.githubusercontent.com/ilia-sokolov/OfficeAgent.NET/main/samples/documents/services-agreement.docx\n```\n\nAny `.docx` of your own works too — the sample just gives you something with a comment and a\npending revision already in it.\n\nRegister the server with Claude Code, pointed at that folder and nothing else:\n\n```bash\nclaude mcp add \\\n  --env OfficeAgent__FileSystemConnections__0__ConnectionId=documents \\\n  --env OfficeAgent__FileSystemConnections__0__RootPath=$HOME/officeagent-documents \\\n  --transport stdio \\\n  officeagent -- officeagent-mcp --stdio\n```\n\nThen ask:\n\n> In services-agreement.docx, change the payment terms from thirty days to forty-five days.\n\nOpen the file in Word. Clause 3 now reads **forty-five days** as a tracked change you can\naccept or reject, and everything else — the table, the comment, the redline that was\nalready there — is exactly as it was. That is the whole idea: the document that comes out\nis the one that went in, minus the edit you asked for.\n\n[What else the sample is good for](samples/documents/README.md) — reviewing comments,\naccepting revisions, editing the table.\n\n### If it does not work\n\n| | |\n| --- | --- |\n| `claude mcp list` shows officeagent as failed | Check `RootPath` is an absolute path to a directory that exists. |\n| The agent says it cannot find the document | The name must be relative to `RootPath`, not a full path. |\n| `io-error` on save | The document is open in Word. Close it. |\n\n## Beyond the first edit\n\nThe quick start above is deliberately the smallest thing that works. Four settings extend it:\n\n| Setting | Adds |\n| --- | --- |\n| `OfficeAgent__AllowCreation=true` | `create_document`, so \"draft a project brief in brief.docx\" makes a new file instead of failing |\n| `OfficeAgent__FileSystemConnections__0__AllowedExtensions__1=.pptx` | PowerPoint decks. Add `__DefaultChangeMode=Direct` with it — a deck has no redline vocabulary and refuses tracked changes |\n| `OfficeAgent__EphemeralConnectionId=session` | Names the in-memory session connection explicitly. With no configuration at all the server already falls back to one - this is for running it alongside storage, or under a different id |\n| `OfficeAgent__AllowInlineContent=true` | Tools that carry the document as base64, for a single self-contained call |\n\nPast a couple of settings, use a file instead — the same `OfficeAgent` section, where a list\nis a list:\n\n```json\n{\n  \"OfficeAgent\": {\n    \"AllowCreation\": true,\n    \"FileSystemConnections\": [\n      {\n        \"ConnectionId\": \"documents\",\n        \"RootPath\": \"C:\\\\officeagent-documents\",\n        \"AllowedExtensions\": [ \".docx\", \".pptx\" ],\n        \"DefaultChangeMode\": \"Direct\"\n      }\n    ]\n  }\n}\n```\n\n```bash\nclaude mcp add --transport stdio officeagent -- officeagent-mcp --stdio --config ./officeagent.json\n```\n\nEnvironment variables still override the file. Windows, PowerShell, other MCP clients,\nHTTP hosting and SharePoint are in\n[Deployment and client setup](docs/deployment.md); every setting is listed in\n[MCP server](docs/mcp-server.md).\n\n### Teaching the agent to review, not just replace\n\n[`skills/word-document-review`](skills/word-document-review/SKILL.md) is an\n[Agent Skill](https://code.claude.com/docs/en/skills) that teaches the review loop: read the\ncomments and pending revisions before editing, keep edits as redlines, address documents by\nid rather than passing bytes around, and recover from each error code rather than retrying.\nCopy it into `.claude/skills/` in your project, or `~/.claude/skills/` for every project:\n\n```bash\ncp -r skills/word-document-review ~/.claude/skills/\n```\n\n### What reaches the model\n\nThe inspect and find tools return document text and structure to the model — that is how it\nlocates an edit. The `.docx` package itself does not travel that way *unless* you enable\n`AllowInlineContent`, whose tools carry the whole file as base64 in both directions by\ndesign. Connect folders and model providers appropriate for the data you are handling.\n\nThe server ships no authentication layer for HTTP hosting; put it behind your own. A\nfilesystem root is a trust boundary: its ACLs must stop untrusted principals creating,\nrenaming or replacing entries while the server runs.\n\n## .NET quick start\n\nInstall the core package and Word module:\n\n```bash\ndotnet add package OfficeAgent.Core\ndotnet add package OfficeAgent.Word\n```\n\nAfter registering services and a document provider, the edit loop looks like\nthis:\n\n```csharp\nvar client = services.GetRequiredService<OfficeAgentClient>();\nvar doc = await client.RegisterAsync(\"workspace\", \"/srv/workspace/contract.docx\");\n\nvar inspect = await client.InspectAsync(\"workspace\", doc.ItemId);\nvar hit = (await client.FindAsync(\n    \"workspace\", doc.ItemId, new FindQuery(\"Acme Corp\"))).First();\n\nvar plan = new DocumentPlan\n{\n    Snapshot = inspect.Snapshot,\n    Operations = new PlanOperation[]\n    {\n        new ChangeTextOp\n        {\n            Target = hit.Anchor,\n            With = \"Globex Inc.\",\n            Mode = ChangeMode.Tracked\n        }\n    }\n};\n\nvar preview = await client.PreviewAsync(\"workspace\", doc.ItemId, plan);\nif (preview.IsValid)\n    await client.CommitAsync(\"workspace\", doc.ItemId, plan);\n```\n\nThe complete example, including service registration and reading the saved\nfile, is in [Getting started](docs/getting-started.md).\nThe minimal sample replaces the first `Acme Corp` with `Globex Inc.`. To run it,\ncopy a Word document containing `Acme Corp` to `contract.docx` in the cloned\nrepository root, then run:\n\n```bash\ndotnet run --project samples/QuickEdit -- ./contract.docx ./contract-edited.docx\n```\n\nThe repository also contains a\n[direct `IChatClient` Word-editing sample](samples/IChatClientWordEdit/) and an\ninteractive\n[Agent Framework sample](samples/AgentEdit/).\n\n## How it works\n\nEvery edit follows the same four steps:\n\n1. **Inspect** returns a structured map of the document: its outline,\n   paragraphs, styles, content controls, tables, images, and revisions.\n2. **Find** searches text and returns a content-verified anchor for each match.\n3. **Preview** validates a plan against the current document and reports the\n   proposed changes without writing.\n4. **Apply** commits the complete plan and saves it through the configured\n   provider.\n\nA plan (`DocumentPlan`) is a typed, JSON-serialisable list of operations. An\nanchor records both a location and the content expected there. If the content\nor optional document snapshot has changed, validation fails instead of silently\ntargeting a different location. Applying a plan is all-or-nothing.\n\nThe Word module supports changes to text, paragraphs, tables, images, styles,\ncontent controls, comment threads, footnotes and endnotes, page geometry and\nbreaks, document properties, and tracked revisions. Every verb that changes\ncontent records a redline when the connection asks for one - an inserted clause,\na deleted row and a restyled heading all come back as revisions a reviewer\naccepts or rejects, not only a replaced phrase. The\nPowerPoint module implements a broad, explicitly documented set of deck\noperations: text, bullets, run and paragraph formatting, template\nslots, style copying, tables, images, text boxes, embedded video and audio,\nspeaker notes, resolvable comments, footers and slide numbers, sections,\ntransitions and animations, and the slide lifecycle - adding, removing,\nreordering and duplicating. Several slide inserts in one plan author a deck end\nto end, so a single call turns nothing into a finished presentation. Any verb it\ndoes not support is named rather than silently skipped. The full operation\nschema is documented in [Document plans](docs/document-plans.md), and the deck\nspecifics in [PowerPoint support](docs/powerpoint.md).\n\nDocuments are accessed through configured providers. After registration,\nediting calls use a `(connectionId, documentId)` pair instead of a storage path\nor credentials. The filesystem provider restricts registrations to its root;\nthe SharePoint provider uses the permissions of its configured identity.\n`CreateAsync` starts a new document inside a connection: the requested `.docx`\nor `.pptx` extension selects a registered blank-document factory. The engine\napplies an optional initial plan in memory, and then asks\nthe provider to create and register it without overwriting an existing name.\n\n## Documentation\n\n| Guide | Covers |\n| --- | --- |\n| [Documentation hub](docs/README.md) | Learning paths, package map, and the complete documentation set |\n| [Getting started](docs/getting-started.md) | A complete edit from service registration to reading the result |\n| [Concepts](docs/concepts.md) | Anchors, snapshots, plans, providers, transactions, and capabilities |\n| [Document plans](docs/document-plans.md) | JSON shapes and validation rules for every operation |\n| [Document providers](docs/document-providers.md) | Filesystem, SharePoint, save modes, and custom providers |\n| [PowerPoint support](docs/powerpoint.md) | Slide addressing, the verbs the deck module implements, and what it preserves |\n| [Agent integration](docs/agent-integration.md) | Microsoft Agent Framework and `Microsoft.Extensions.AI` tools |\n| [MCP server](docs/mcp-server.md) | Server configuration, transports, security notes, and tool contracts |\n| [Deployment and client setup](docs/deployment.md) | Codex, Claude Code, Microsoft Copilot clients, containers, and Azure |\n| [Operations](docs/operations.md) | Concurrency, streams, cancellation, telemetry, and production concerns |\n| [Troubleshooting](docs/troubleshooting.md) | Startup, registration, validation, concurrency, and provider failures |\n| [Failure modes](docs/operations.md#failure-modes-you-should-handle) | Common plan errors and what to do next |\n| [Releasing](docs/releasing.md) | Publishing to NuGet, the MCP Registry, and GitHub |\n\n## Contributing\n\nBug reports, documentation fixes, new document operations, provider\nintegrations, and focused test cases are useful contributions. If you found a problem,\n[open an issue](https://github.com/ilia-sokolov/OfficeAgent.NET/issues) with the\ndocument feature involved, the operation you attempted, and the error or\nunexpected result. Do not attach confidential documents; a small sanitised\nreproduction is enough.\n\nTo work on the code, install the .NET 8 SDK, fork the repository, and run:\n\n```bash\ndotnet build OfficeAgent.NET.sln\ndotnet test OfficeAgent.NET.sln\n```\n\nBefore starting a larger change, especially one that changes public types or\nthe JSON wire format, [open an issue](https://github.com/ilia-sokolov/OfficeAgent.NET/issues)\nso the design can be discussed. See\n[CONTRIBUTING.md](CONTRIBUTING.md)\nfor code style, tests, and pull-request expectations.\n\n## Scope and limitations\n\nOfficeAgent.NET edits Word `.docx` files and PowerPoint `.pptx` decks; it does\nnot automate the Office desktop applications. An Excel module can be added\nthrough `IFormatModule`, but it does not ship today.\n\nThe deck module refuses the verbs a presentation has no vocabulary for -\n`setProperty`, `revision`, `pageSetup`, `insertBreak` and `note` - per\noperation, rather than applying part of a plan, and refuses an explicit tracked\nmode on any verb that carries one. PresentationML has no redline model, so tracked changes are Word-only, and\na slide has no header (that is a notes and handout concept). Animations cover\nthe effects expressible as a filtered `p:animEffect`; fly-in, zoom and motion\npaths are refused rather than approximated. See\n[PowerPoint support](docs/powerpoint.md) for what a deck does and does not\naccept.\n\nThe engine does not render pages or calculate Word fields. Operations that\ndepend on pagination, table-of-contents rendering, field recalculation, or\npage-fit checks are outside its scope. Preview reports structural changes, not\na visual rendering of the final document. Test the workflow on representative\ndocuments and keep human review in the loop for consequential edits.\n\nTwo more limits worth knowing before you build on it:\n\n- **Token savings depend on how you connect.** Addressing a document by id keeps\n  the package out of the conversation, and inspection can be narrowed with\n  `fidelity` and paging - that is where the saving comes from. The inline\n  `*_content` tools are the deliberate exception: they carry the whole file as\n  base64 in both directions, which costs tokens in proportion to file size. They\n  suit a single self-contained call, not a sequence of edits - a model asked to\n  pass a document of a few kilobytes back for a second edit reproduces it\n  imperfectly and the follow-up fails. Use a connection, or a session connection,\n  when more than one edit is coming.\n- **A skill helps, and is not automatic.** Nothing here makes an agent read the\n  open comments before editing, or keep an edit as a redline. The\n  [word-document-review skill](skills/word-document-review/SKILL.md) teaches that;\n  without it, behaviour depends on the model and the prompt.\n\n## Commercial support\n\nOfficeAgent.NET is MIT-licensed and can be self-hosted. Managed hosting and\ncommercial support are available from dotaction:\n[contact dotaction](mailto:contact@dotaction.io?subject=OfficeAgent.NET%20commercial%20support).\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n",
  "bytes": 16664,
  "sha": "d346a69b58d44b61556551f49ec24d347e46f9827f45c7b7f9d5ccf1af4f09db",
  "repo_slug": "ilia-sokolov/officeagent.net",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ilia_sokolov_officeagent_855838ef/readme"
}