MCP serverMicrosoft Dynamics 365 Business Central Agent view

How to build an MCP server for Dynamics 365 Business Central

Short answer

An MCP server for Business Central is a small service that turns API v2.0 and custom API page calls into named, read-only tools, authenticates with Entra ID, and logs every call. Any MCP client, including Claude and ChatGPT, can then use it.

The Model Context Protocol gives AI clients a standard way to discover and call tools. For Business Central, that means you write the integration once and avoid building separate plugins for each assistant.

The design work is not the protocol. It is deciding which business questions become tools, how much data each returns, and whose permissions apply. A poorly designed server that exposes generic query access will cost more in tokens, risk and wrong answers than one with ten sharp tools.

Microsoft has signalled MCP support for Business Central in SaaS, so first confirm what exists for your version. Build your own when you need manufacturing tables, on-premises reach, partner extension data or tighter control than a general endpoint gives.

What teams use it for

Item and availability lookup

Tools that return an item card summary, inventory by location and variant, and projected availability, so assistants can answer can we ship this by Friday.

Order status for sales and service

Look up a sales order by number or external document number and return lines, shipped quantities, posted invoices and tracking.

Purchase and receipt visibility

Open PO lines by vendor or item, expected receipt dates and posted receipts, enabling expediting assistants.

Production and BOM context

Through custom API pages, expose released production orders, component status and certified BOM structure for planners and quality engineers.

Controlled draft creation

Later, a gated tool to create a purchase quote or a journal line in an unposted batch with an explicit confirm step.

Microsoft Dynamics 365 Business Central integration surface

  • API v2.0 at /api/v2.0/companies({companyId}) is the primary data path. Use $filter, $select and $top to keep results small, and follow @odata.nextLink for pages.
  • Custom API pages in AL (PageType = API, with APIPublisher, APIGroup, APIVersion, EntityName and EntitySetName) cover production orders, BOM lines, routing or your own tables. Version them like any public API.
  • Environments: SaaS has production and sandbox environments, each with its own base URL in the form of the tenant, environment name and API path. On-premises uses the web service tier's configured port and server instance.
  • Auth: OAuth 2.0 with Entra ID for SaaS, using client credentials for a service principal or an authorization code flow for delegated user context. On-premises may use Windows or NavUserPassword depending on setup.
  • Operational limits: throttling returns HTTP 429 with a retry hint, so build backoff and caching into the server rather than into each tool.

How it works

  1. 1

    Define the tool contract first

    Write the tool names, inputs and outputs on paper. Example: get_sales_order(number) returns header, lines, shipments and invoices. Keep names verb-first and descriptions precise because the model reads them.

  2. 2

    Choose language and SDK

    The official MCP SDKs for TypeScript or Python are enough. Add a typed Business Central client with token caching and retry handling.

  3. 3

    Authenticate to Business Central

    Register an Entra app, add it under Microsoft Entra Applications in Business Central, assign a permission set limited to the tables the tools touch, and test with the sandbox first.

  4. 4

    Choose a transport

    stdio when the server runs on the same machine as a desktop client. Streamable HTTP with OAuth when many users share it. Do not expose an unauthenticated HTTP endpoint on a network.

  5. 5

    Return compact, cited results

    Include record numbers, company and last modified date in each payload. Cap list sizes and say when results are truncated.

  6. 6

    Add audit and rate limits

    Log user, tool, arguments, duration and result size. Apply per-user limits and a global concurrency cap so a chat loop cannot hammer the tenant.

  7. 7

    Test with multiple clients

    Run the MCP inspector, then Claude, then another client. Tool descriptions that work in one often need tuning in another.

Example flows

Order status from any assistant

Trigger: A customer service rep asks an assistant where order SO-1042 is.

  1. Client calls get_sales_order with the number.
  2. Server queries salesOrders and expands salesOrderLines, then looks up posted shipments.
  3. Server returns lines with ordered, shipped and invoiced quantities.
  4. Assistant explains which lines are backordered.

Result: A sourced answer with record numbers and no direct database access by the model.

Gated draft purchase quote

Trigger: A planner asks the assistant to request a quote for a shortage item.

  1. Assistant calls find_item_vendors to list approved vendors.
  2. Assistant calls propose_purchase_quote, which returns a preview and a confirmation token.
  3. Planner approves in the client UI; the assistant calls confirm with the token.
  4. Server creates the quote in Open status and writes an audit entry.

Result: A draft record exists for the buyer to finish; nothing is released or posted.

Keeping data on-prem

Run the MCP server as a service inside the network that hosts the Business Central service tier, so the API call never leaves your boundary. Pair it with a locally served model through any MCP-capable client or an in-house agent, using vLLM or Ollama on your own GPUs. For air-gapped sites, bundle dependencies, disable telemetry, and authenticate users against your directory. If part of the estate is SaaS and part on-premises, run one server per environment rather than one server that holds credentials for both, and make the environment visible in every tool result.

Security checklist

  • Start with read-only tools. Each additional write tool needs its own review, confirmation step and audit entry.
  • Prefer delegated user auth so Business Central permissions and dimension filters apply to the person asking.
  • Bind HTTP servers to authenticated, TLS-protected endpoints; never expose an open MCP port.
  • Keep secrets in a vault, not in config files in a repository.
  • Treat tool inputs from the model as untrusted: validate, bound and escape before building an OData filter.

Ways to get it done

Use a Microsoft-provided or marketplace MCP endpoint

Effort: Days to evaluate and approve.

SaaS tenants whose needs match the published tools.

Build your own on API v2.0 plus custom API pages

Effort: Two to five weeks for a solid read-only set.

Manufacturing data, on-premises installs or tight governance.

Partner-built and maintained (Netray or another integrator)

Effort: Several weeks plus ongoing upgrade support.

Teams without AL or MCP skills, or needing a private model alongside.

Pitfalls

  • !Offering a generic query tool that accepts raw OData filters. Prefer purpose-built tools.
  • !Returning entire entity payloads with dozens of null fields, which wastes context and confuses models.
  • !Forgetting company scoping in multi-company tenants and answering from the wrong company.
  • !Hardcoding API versions and breaking after a release wave. Pin versions and run tests.
  • !Ignoring 429 responses and letting retries snowball.

Frequently asked questions

What tools should a first Business Central MCP server expose?

Item search, item availability, sales order status, purchase order lines by vendor, customer and vendor lookup, and posted shipment or receipt lookup. These cover most questions and are read-only. Add production and BOM tools via custom API pages once the basics are reliable.

stdio or HTTP transport?

Use stdio for a developer running a client on one machine. Use HTTP with OAuth for a shared, centrally managed server. HTTP gives you central logging, rate limiting and upgrades, which matter once more than a handful of people use it.

Do I need to write AL code?

Not for standard entities. You need AL for custom API pages exposing tables the standard API omits, such as parts of production and planning, or for your own extension tables. Many teams start without it and add one small extension later.

How do I handle multiple companies?

Make the company an explicit tool parameter validated against an allowed list, or bind each server instance to one company. Always echo the company name in results so users and models can see which one an answer came from.

Can the same server work with Claude and ChatGPT?

Yes, any client that speaks MCP can use it, although transport support, authentication flows and tool-description tuning differ between clients. Test with each client you plan to support and keep tool descriptions plain and specific.

Want MCP server working on your Microsoft Dynamics 365 Business Central?

A free 30 minute assessment: we map the integration path for your version and setup, and where it should run.

Get a free assessment