mcp
Business Central for your agent
The knowledge base this site is built from, as an MCP server your agent can query, and a Claude Code plugin around it. Every answer carries the page, its trust tier and its evidence. No API key, no account.
- 0.7.1bc-observatory on npm
- 0.3.0Claude Code plugin
- 9tools
- 4skills
What to ask
What is on table 18, and which fields are obsolete?
What changed in codeunit Sales-Post between BC29 and BC30?
What does the Belgian localization change in W1?
What is new in Business Central since last Monday?
Where is posting preview documented, and who blogged about it?
What does kauffmann-nl write about?
Show me the body of Sales-Post.PostInvoice and what it calls.
Walk me through setting up intercompany partners.
The tools
| Tool | What it does | Example |
|---|---|---|
search | Every page by title, AL object name and caption, summary and tags, plus fields, events and procedures, ranked like the site's search (t36, cu 80, plurals, one typo, synonyms); hybrid (keywords plus meaning), so a paraphrase still finds the page. A symbol ranks where its owner ranks; a kind: query that finds nothing says so and names the nearest symbols. Filter by type, tier, galaxy system, country, app, object type or kind. | search('posting preview') |
ls | Browse the page tree; an empty path lists the sections. | ls('objects/table') |
cat | A page's markdown: frontmatter with evidence and links, then the body. A long page comes back compact with its section keys; section, offset and limit read one part, and a symbol's path returns just that member. | cat('localizations/be') |
get_object | An object of W1, a first-party app or a country layer by type and id, reference, name or caption: fields, keys, events, public procedures, obsolete state, versions, countries that replace it, Learn pages; a country layer that replaces a W1 object prints what it adds before the page. A large object comes back compact; read one section with section, offset and limit. counts.procedures in the frontmatter counts every procedure; the summary's 'public procedures' excludes locals and events. | get_object('table', '18') |
diff_object | Member-level changes of a W1 object between two consecutive versions: fields, events, procedures, keys, properties, obsolete state. | diff_object('codeunit', 'Sales-Post', '29', '30') |
localization | What a country layer adds to or changes in W1, with its Learn local functionality hub. Large countries come back compact, as with cat. | localization('BE') |
whats_new | Videos, posts, roadmap features, AL extension releases and code changes (merged pull requests) dated on or after a date and up to today, newest first. | whats_new('2026-10-01') |
blog_footprint | What a blog or channel covers: its posts or videos and the systems they touch. | blog_footprint('kauffmann-nl') |
feedback | A prefilled GitHub issue link for a page (wrong fact, missing evidence, broken link). Nothing is sent by the agent. | feedback('objects/table/18', 'field 7 is wrong') |
The plugin (Claude Code)
The plugin registers the server, ships four skills that tell the agent when to use it, and connects bc-code-atlas by Stefan Maron for procedure bodies and the per-procedure call graph. The observatory keeps the object-level facts; the atlas has the source. It also connects Microsoft's Learn MCP: the observatory finds the Learn page, the Learn MCP reads it and finds AL code samples.
bc-lookupBusiness Central facts with evidence: AL objects, Learn documentation, roadmap features, videos and posts. For 'what is table 18', 'where is this documented'.bc-whats-newRecent videos, posts and roadmap features with status, and what changed in the code between versions. For 'what's new', 'what changed in BC30'.bc-localizationWhich objects a country layer adds, which W1 objects it changes, added fields and events, and where Learn documents the local functionality.bc-groundingThe servers together: the observatory for ids, fields, events, versions, callers and evidence, bc-code-atlas for the procedure body and what one procedure calls, Microsoft Learn MCP for the Learn page and AL code samples.
What the plugin installs
Three MCP servers and four skills. Nothing needs an account or an API key.
| Server | Run by | Connects to | For, and what leaves your machine |
|---|---|---|---|
bc-observatory | this project (waldo), the npm package run locally | npx -y bc-observatory@latest | Business Central facts with evidence and a trust tier: objects, fields, events, versions, localizations, what changed, roadmap, videos, posts. Not procedure bodies or Learn text. Your queries stay on your machine; it downloads the site's search index and the pages you read. |
bc-code-atlas | Stefan Maron, a free hobby server (be a polite client) | https://bc-code-atlas.stefanmaron.dev/mcp | AL source: a procedure body, what one procedure calls, semantic code search of one W1 version. The names and search text of your calls go to his server. |
microsoft-learn | Microsoft, public endpoint, no authentication | https://learn.microsoft.com/api/mcp | Reading a Learn page the observatory points to and AL code samples. The URLs and search text of your calls go to Microsoft. |
Routing: the observatory first; bc-code-atlas for procedure bodies and per-procedure edges; Microsoft Learn MCP to read a Learn page the observatory points to and for AL code samples. Switch one plugin server off with /mcp (Claude Code stops connecting to it, without removing the plugin); claude mcp remove acts on servers you added yourself, so to take only some servers install them by hand instead. A Learn MCP you already have at the same URL wins over the plugin's: keep one. Details in plugin/README.md.
Install
- Claude Code: the plugin (server, four skills, bc-code-atlas, Microsoft Learn MCP)
claude plugin marketplace add waldo1001/waldo.BCObservatory - Claude Code: the server only
claude mcp add bc-observatory -- npx -y bc-observatory@latest - Claude Desktop, Cursor, Windsurf and other MCP clients
{ "mcpServers": { "bc-observatory": { "command": "npx", "args": [ "-y", "bc-observatory@latest" ] } } } - VS Code (GitHub Copilot)
{ "servers": { "bc-observatory": { "type": "stdio", "command": "npx", "args": [ "-y", "bc-observatory@latest" ] }, "bc-code-atlas": { "type": "http", "url": "https://bc-code-atlas.stefanmaron.dev/mcp" }, "microsoft-learn": { "type": "http", "url": "https://learn.microsoft.com/api/mcp" } } } - From a checkout of the repository
git clone https://github.com/waldo1001/waldo.BCObservatory.git && cd waldo.BCObservatory && npm ci claude mcp add bc-observatory -- env BC_OBSERVATORY_LOCAL=$PWD node --import tsx packages/mcp/src/server.ts - Without any install
How it answers
The server fetches the search index from this site over HTTPS and caches it by hash in ~/.cache/bc-observatory/, refreshed daily, and reads a page's markdown twin when you ask for it; a page over 30,000 characters comes back as a compact view with its section keys. Search is hybrid: keywords plus a small static embedding model (model2vec potion-base-8M, 30 MB, downloaded once and checked by SHA-256) computed locally; BC_OBSERVATORY_EMBEDDINGS=0 turns the model off. BC_OBSERVATORY_LOCAL reads a checkout instead, BC_OBSERVATORY_SITE points at another deployment. Nothing is sent anywhere: feedback only returns a link you open yourself.