bcquality-mcp
This server exposes Microsoft's BCQuality Business Central best-practices repository to AI agents as structured MCP tools, enabling discovery, search, retrieval, and context-based recommendation of AL development rules.
List knowledge domains (performance, security, privacy, etc.) with file counts and contributing layers.
List knowledge files with filters on layer, domain, technologies, BC version, countries, application area, and keywords, plus pagination.
List skills (meta-skills and action-skills) filtered by layer or kind.
Get a parsed knowledge file with frontmatter, sections (Description, Best Practice, Anti Pattern, other), and the body.
Get good/bad example files (.good.al / .bad.al) sibling to a knowledge file.
Get a skill file with parsed frontmatter and body.
Free-text search across knowledge with scoring, matched keywords, and structured filters.
Get applicable rules for context (the flagship workflow tool): given a goal plus BC context, returns matching rules with sections inlined, applies layer precedence (custom > community > microsoft), and surfaces suppressed duplicates.
Check server status (clone path, source, commit, enabled layers, per-layer counts, index age).
Refresh the clone (git pull) and rebuild the in-memory index.
Provides access to the microsoft/BCQuality GitHub repository (or a fork) as a source of Business Central development best practices, enabling AI agents to retrieve, search, and apply structured AL coding rules and examples.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bcquality-mcpsearch for best practices about table naming"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bcquality-mcp
Serveur MCP (Model Context Protocol) qui expose le contenu de
microsoft/BCQualityà des agents IA (Claude Code, Claude Desktop, Cursor, etc.) sous forme de tools structurés.
microsoft/BCQuality est un référentiel Microsoft (MIT) qui codifie les bonnes pratiques de développement Business Central — fichiers .md à frontmatter YAML structuré + exemples .good.al / .bad.al. Le repo est conçu pour la consommation par agents IA, mais il faut une mécanique d'orchestration pour l'exploiter (filtrage par frontmatter, application du workflow Source → Relevance → Worklist → Action, gestion de précédence entre couches).
Ce serveur fait ce travail. Un agent IA n'a qu'à appeler les tools pour récupérer les règles pertinentes à son contexte de développement AL.
📦 Vous voulez juste l'installer pour l'utiliser ? Voir INSTALL.md — guide court avec one-liner PowerShell. Le présent README est destiné aux contributeurs / mainteneurs.
Table des matières
Related MCP server: Business Central MCP Server
Architecture
┌─────────────────┐ JSON-RPC stdio ┌──────────────────────┐
│ Agent IA │ ◄────────────────► │ bcquality-mcp │
│ (Claude Code, │ │ (Node.js, stdio) │
│ Cursor, …) │ │ │
└─────────────────┘ │ ┌──────────────┐ │
│ │ Tools (10) │ │
│ │ list/get/ │ │
│ │ search/... │ │
│ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ In-memory │ │
│ │ index │ │
│ └──────┬───────┘ │
└─────────┼───────────┘
│ filesystem read
┌─────────▼───────────┐
│ BCQuality clone │
│ (microsoft, ou fork)│
│ │
│ /microsoft/ │
│ /community/ │
│ /custom/ ← VOUS │
│ /skills/ │
└─────────────────────┘Source de données : un clone git local du repo microsoft/BCQuality (ou de votre fork). Le serveur peut :
pointer vers un clone existant (variable
BCQUALITY_REPO_PATH)cloner automatiquement le repo dans un cache si rien n'est défini
Couches : précédence croissante microsoft < community < custom. Quand deux fichiers ont le même slug, custom/ gagne ; les autres sont reportés en suppressed[].
Prérequis
Outil | Version min | Notes |
Node.js | 18.x | LTS recommandé (18, 20, 22). |
Git | toute version récente | Pour le clone auto + |
Un client MCP | — | Claude Code (recommandé), Claude Desktop, Cursor, etc. |
Vérifiez :
node --version
git --versionInstallation de A à Z
Voie la plus simple — npm
Le package est publié sur npm : bcquality-mcp.
npm install -g bcquality-mcp
claude mcp add bcquality bcquality-mcp -s userPas de clone, pas de build local. Le binaire bcquality-mcp est disponible dans le PATH après installation globale. Pour Claude Desktop / Cursor, voir Intégration aux clients MCP.
Voie rapide depuis GitHub — un script
Utile si vous voulez le code source local (modif, debug, fork avec couche custom/) :
git clone https://github.com/glachana/bcquality-mcp.git "$env:USERPROFILE\bcquality-mcp"
cd "$env:USERPROFILE\bcquality-mcp"
.\scripts\setup.ps1setup.ps1 vérifie Node/Git, fait npm install + npm run build, puis vous demande dans quel client MCP enregistrer le serveur (Claude Code, Claude Desktop, les deux).
Pour les collègues sans clone local, un one-liner existe :
irm https://raw.githubusercontent.com/glachana/bcquality-mcp/main/scripts/install-from-github.ps1 | iexVoir INSTALL.md pour la doc utilisateur final.
Voie manuelle (pour comprendre / debugger)
Étape 1 — Cloner le projet
git clone https://github.com/glachana/bcquality-mcp.git "$env:USERPROFILE\bcquality-mcp"
cd "$env:USERPROFILE\bcquality-mcp"Étape 2 — Installer les dépendances
npm installInstalle @modelcontextprotocol/sdk, zod, gray-matter, simple-git, esbuild et leurs dépendances.
Étape 3 — Builder le serveur
npm run buildTranspile src/**/*.ts → dist/**/*.js via esbuild (≈ 100 ms). Le dist/index.js est l'entrée à passer au client MCP.
Pourquoi esbuild et pas tsc ? Le couple
@modelcontextprotocol/sdk1.29 +zod3.25 fait exploser l'inférence de types detsc(heap > 8 Go). Le type-check reste accessible vianpm run typechecksi vous voulez le faire ponctuellement.
Étape 4 — Premier démarrage (smoke test)
node dist/index.jsAu premier lancement, le serveur clone automatiquement microsoft/BCQuality dans %LOCALAPPDATA%\bcquality\cache. Vous devez voir :
[bcquality-mcp] Loaded repo from %LOCALAPPDATA%\bcquality\cache (source=cloned, layers=microsoft,community,custom)
[bcquality-mcp] Indexed 156 knowledge files, 12 skills
[bcquality-mcp] Connected on stdio.(Le serveur attend ensuite des messages JSON-RPC sur stdin — Ctrl+C pour quitter.)
Étape 5 — Connecter le serveur à votre client MCP
Voir Intégration aux clients MCP ci-dessous.
Configuration
Toutes les options se passent par variables d'environnement au lancement du serveur. Un fichier .env.example est fourni à titre de référence (ce serveur ne le charge pas automatiquement — c'est le client MCP qui injecte les variables).
Variable | Défaut | Rôle |
| (vide) | Chemin local prioritaire vers un clone (votre fork avec |
|
| URL utilisée par le clone automatique et par |
|
| Dossier où le serveur clone si aucun |
|
| Couches activées, dans l'ordre de précédence croissante. |
|
| Si |
Logique de résolution du repo au démarrage
Si
BCQUALITY_REPO_PATHest défini et que le dossier existe et ressemble à un clone BCQuality → on l'utilise (source=env).Sinon, si
CACHE_PATHcontient déjà un clone → on l'utilise (source=cache).Sinon, si
AUTO_CLONE=true→git clone --depth 1 BCQUALITY_REPO_URLdansCACHE_PATH(source=cloned).Sinon → erreur explicite avec instructions.
Intégration aux clients MCP
Claude Code (CLI / VS Code extension)
Méthode rapide — installation déjà effectuée par la commande :
claude mcp add bcquality node "$env:USERPROFILE/bcquality-mcp/dist/index.js" -s userVérification :
claude mcp list
# bcquality: node <path>/bcquality-mcp/dist/index.js - ✔ ConnectedPour pointer vers votre fork avec variables d'environnement :
claude mcp remove bcquality -s user
claude mcp add bcquality node "$env:USERPROFILE/bcquality-mcp/dist/index.js" -s user -e BCQUALITY_REPO_PATH="C:/path/to/your/fork"Important : redémarrez la session Claude Code après l'ajout. Les serveurs MCP sont chargés au lancement.
Claude Desktop
Éditez %APPDATA%\Claude\claude_desktop_config.json :
{
"mcpServers": {
"bcquality": {
"command": "node",
"args": ["<absolute-path-to>/bcquality-mcp/dist/index.js"],
"env": {
"BCQUALITY_REPO_PATH": "C:/path/to/your/fork"
}
}
}
}Redémarrez Claude Desktop.
Cursor
Éditez ~/.cursor/mcp.json (même format que Claude Desktop).
MCP Inspector (test interactif)
Pour explorer manuellement les tools dans une UI web :
npm run inspectOuvre une UI sur http://localhost:5173 où vous pouvez appeler chaque tool avec des inputs personnalisés.
Tools exposés
Tous les tools sont préfixés bcquality_ et retournent à la fois du texte JSON formaté (content[0].text) et un objet structuré (structuredContent) typé via Zod.
Découverte
bcquality_list_domains
Liste les domaines de connaissance (performance, security, privacy, …).
Inputs :
layers?: ("microsoft"|"community"|"custom")[]— sous-ensemble de couches.
Output : { domains: [{ name, fileCount, layers[] }] }
Exemple d'output réel :
{
"domains": [
{ "name": "performance", "fileCount": 42, "layers": ["community", "microsoft"] },
{ "name": "privacy", "fileCount": 17, "layers": ["microsoft"] },
{ "name": "security", "fileCount": 24, "layers": ["community", "microsoft"] },
{ "name": "style", "fileCount": 35, "layers": ["microsoft"] },
{ "name": "testing", "fileCount": 1, "layers": ["microsoft"] }
]
}bcquality_list_knowledge
Liste les fichiers de connaissance avec filtres.
Inputs : layer?, domain?, technologies?, bcVersion?, countries?, applicationArea?, keywords?, limit (1–500, défaut 50), offset.
Output : { items: [{ path, layer, domain, slug, title, descriptionExcerpt, keywords, bcVersion, … }], total, nextOffset? }
bcquality_list_skills
Liste les meta-skills (/skills/entry.md, read.md, do.md, write.md), les host-skills (/skills/<name>/SKILL.md — adaptateurs au format natif de l'hôte, exposés quand BCQuality est installé comme plugin autonome) et les action skills (<layer>/skills/…).
Inputs : layer?, kind? (action-skill | host-skill | meta).
Output : { items: [{ path, kind, id?, version?, title, inputs?, outputs?, subSkills? }] }
Lecture
bcquality_get_knowledge
Récupère un fichier de connaissance parsé.
Inputs : path: string (chemin repo-relatif, ex. microsoft/knowledge/performance/use-setloadfields-for-partial-records.md)
Output : { path, title, frontmatter, sections: { description, bestPractice?, antiPattern?, other[] }, exampleFiles: { good?, bad? }, body }
bcquality_get_examples
Récupère le contenu des exemples .good.al / .bad.al associés à un knowledge.
Inputs : knowledgePath: string, kind: 'good'|'bad'|'both' (défaut both).
Output : { good?: { path, content }, bad?: { path, content } }
bcquality_get_skill
Récupère une skill (meta ou action).
Inputs : path: string (ex. skills/entry.md, microsoft/skills/review/al-performance-review.md).
Output : { path, kind, title, frontmatter, body }
Workflow haut niveau (les tools « phares »)
bcquality_search_knowledge
Recherche full-text avec filtres.
Inputs : query: string, layers?, domain?, technologies?, bcVersion?, countries?, applicationArea?, limit (1–100, défaut 20).
Output : { matches: [{ path, score, layer, domain, title, descriptionExcerpt, matchedKeywords }] }
Logique : applique Source (filtrage par couches/domain) → Relevance (intersection frontmatter) → Worklist (scoring sur keywords/title/domain/description).
bcquality_get_applicable_for_context 🌟
Le tool le plus puissant. Donné un objectif de développement + un contexte BC, retourne les règles applicables avec leurs sections inlinées, prêtes à être consommées par le LLM.
Inputs :
goal: string— description libre de ce que l'agent essaie de fairetechnologies: string[](défaut["al"])bcVersion?: string | numbercountries?,applicationArea?,layers?,limit(1–50, défaut 10)
Output :
{
applicable: [{
path, layer, domain, title, score,
sections: { description?, bestPractice?, antiPattern? }
}],
suppressed: [{ path, layer, supersededBy, reason: "layer-precedence" }]
}Applique la précédence des couches : si une règle existe en custom/, community/ et microsoft/ sur le même slug, custom/ gagne ; les autres remontent en suppressed[].
Méta
bcquality_status
Renvoie l'état du serveur : path du clone, source de résolution (env/cache/cloned), commit actuel, couches actives, nombre d'articles par couche.
bcquality_refresh
Lance git pull sur le clone actif et reconstruit l'index en mémoire.
Output : { before, after, changedFiles, rebuiltAt }
Cas d'usage
1. Revue de code AL en début de session
Vous travaillez sur une procédure AL et voulez consulter les règles applicables.
Vous demandez à Claude Code :
Avec BCQuality, donne-moi toutes les règles performance applicables à du code AL pour BC v27.
Claude appelle bcquality_get_applicable_for_context avec { goal: "performance review of AL code", technologies: ["al"], bcVersion: 27 } et reçoit la liste filtrée + les sections Description / Best Practice / Anti Pattern directement utilisables.
2. Diagnostic d'une règle spécifique
Montre-moi la règle BCQuality sur SetLoadFields, avec son exemple bon et mauvais.
Claude enchaîne :
bcquality_search_knowledge { query: "setloadfields" }→ trouvemicrosoft/knowledge/performance/use-setloadfields-for-partial-records.mdbcquality_get_knowledge { path: ... }→ titre, frontmatter, sectionsbcquality_get_examples { knowledgePath: ... }→ contenu.good.al+.bad.al
3. Découverte du référentiel
Quels domaines de qualité Microsoft maintient-il pour Business Central, et combien de règles par domaine ?
Claude appelle simplement bcquality_list_domains.
4. Audit de PR
J'ai modifié cette codeunit, vérifie si elle respecte les règles security et privacy de BCQuality.
Claude appelle bcquality_list_knowledge { domain: "security" } puis bcquality_list_knowledge { domain: "privacy" }, lit les .md pertinents, puis compare avec votre code.
5. Inspection des action skills officielles
Quelles skills de review Microsoft a-t-elle publiées dans BCQuality ?
Claude appelle bcquality_list_skills { layer: "microsoft", kind: "action-skill" } → liste le super-skill al-code-review et ses sous-skills, un par domaine de connaissance (performance, security, privacy, upgrade, style, ui, error-handling, events, interfaces, breaking-changes, web-services, testing, data-modeling, query, appsource, telemetry). La couche community en ajoute un : al-agents-review.
Fork avec une couche /custom/ interne
L'intérêt principal de BCQuality est de pouvoir surcharger les règles Microsoft avec vos propres standards organisationnels.
Étape 1 — Forker le repo
Allez sur https://github.com/microsoft/BCQuality, cliquez Fork vers votre organisation ou compte personnel.
Étape 2 — Cloner le fork localement
git clone https://github.com/<your-org>/BCQuality.git $env:USERPROFILE\BCQuality-forkÉtape 3 — Ajouter votre couche custom
Créez des fichiers sous custom/knowledge/<domain>/<slug>.md en respectant le format frontmatter (cf. skills/write.md du repo). Exemple :
---
bc-version: [all]
domain: performance
keywords: [naming, helper-function, internal]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Préférer les helpers internes pour les calculs récurrents
## Description
Au sein de notre organisation, …
## Best Practice
…Étape 4 — Reconfigurer le serveur
claude mcp remove bcquality -s user
claude mcp add bcquality node "$env:USERPROFILE/bcquality-mcp/dist/index.js" -s user -e BCQUALITY_REPO_PATH="$env:USERPROFILE/BCQuality-fork"Redémarrez Claude Code. Vérifiez via le tool bcquality_status que source = env et que custom a articleCount > 0.
À partir de ce moment, vos règles custom/ priment automatiquement sur celles de microsoft/ et community/ (et apparaissent comme superseding dans suppressed[]).
Maintenance et mise à jour
Mettre à jour le serveur (code + build)
cd "$env:USERPROFILE\bcquality-mcp" # ou le dossier où vous l'avez cloné
.\scripts\update.ps1Fait git pull + npm install + npm run build. Redémarrez votre client MCP ensuite.
Mettre à jour le contenu BCQuality (clone des règles)
Depuis Claude (sans quitter la session) :
Lance
bcquality_refreshpour mettre à jour le clone.
Ou manuellement :
cd "$env:LOCALAPPDATA\bcquality\cache"
git pull(Puis redémarrez la session Claude Code pour reconstruire l'index.)
Rebuilder uniquement (après modif locale du code source)
npm run buildPuis redémarrez la session du client MCP.
Vérifier les types ponctuellement
npm run typecheck(Peut prendre 1–2 minutes et nécessiter beaucoup de RAM.)
Dépannage
Symptôme | Cause probable | Solution |
| Le chemin de | Vérifiez |
Au démarrage : | Variable d'env pointe vers un dossier supprimé | Corrigez ou supprimez la variable pour basculer sur l'auto-clone. |
| Le | Vérifiez que c'est bien un fork de microsoft/BCQuality, pas un autre repo. |
Le tool | Le repo cloné est vide ou les couches activées n'ont aucun contenu | Inspectez avec |
Le clone auto échoue | Pas d'accès internet, ou git non installé | Installez git, vérifiez la connectivité, ou clonez manuellement et pointez |
Au démarrage : | Le cache a été cloné depuis une autre URL que | Laissez |
| Bug d'inférence SDK MCP ↔ Zod | Ignorez — utilisez |
Test de bout en bout manuel (JSON-RPC)
Si vous voulez vérifier sans client MCP :
cd "$env:USERPROFILE\bcquality-mcp"
node dist/index.jsTapez (et Entrée après chaque ligne) :
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"manual","version":"1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"bcquality_status","arguments":{}}}Vous devez recevoir une réponse JSON avec repoPath, commit, layers, etc. Comparez remoteUrl (l'origin réel du clone servi) et repoUrl (la valeur configurée) : ils doivent correspondre.
Développement
Structure du projet
BC QUALITY/
├── src/
│ ├── index.ts # entrée stdio, McpServer registration
│ ├── config.ts # parse env vars
│ ├── repo/
│ │ ├── manager.ts # clone/pull + résolution
│ │ ├── walker.ts # parcours filesystem
│ │ └── index.ts # index en mémoire + précédence couches
│ ├── parser/
│ │ ├── frontmatter.ts # validation Zod du YAML
│ │ ├── knowledge.ts # split body en sections
│ │ └── skill.ts # parse action skills
│ ├── search/
│ │ ├── filter.ts # matching frontmatter
│ │ └── score.ts # ranking keywords/domain/title
│ └── tools/ # tools MCP (1 fichier par groupe)
│ ├── shared.ts
│ ├── discovery.ts # list_domains, list_knowledge, list_skills
│ ├── read.ts # get_knowledge, get_examples, get_skill
│ ├── workflow.ts # search_knowledge, get_applicable_for_context
│ └── meta.ts # status, refresh
├── eval/
│ └── questions.xml # 10 questions d'évaluation
├── build.mjs # script esbuild
├── package.json
├── tsconfig.json
└── README.md (ce fichier)Scripts npm
Commande | Effet |
| Transpile |
| Vérifie les types via |
| Lance le serveur via |
| Lance le serveur compilé ( |
| Ouvre MCP Inspector pour tester les tools en UI web. |
| Lance les 42 tests unitaires + intégration (vitest, < 1 s). |
| Mode watch des tests unitaires. |
| Lance les 7 tests E2E qui spawnent le serveur sur stdio (~1 s). |
Suite de tests
tests/unit/— parsers (frontmatter, knowledge, skill), search (filter, score). Pas d'I/O sur le repo réel.tests/integration/—buildIndex+applyLayerPrecedencecontre le mini-repo detests/fixtures/mini-repo/(couvre la précédence custom > community > microsoft).tests/e2e/— spawndist/index.jset envoie de vrais messages JSON-RPC. Vérifie l'init, letools/listcomplet, et les payloadsstructuredContentdes tools clés. Pré-requis :npm run buildavant.
Le mini-repo de fixture contient les 3 couches avec un slug volontairement dupliqué (use-isempty-for-existence-check) pour valider la logique de précédence.
Ajouter un nouveau tool
Créer une fonction
registerXxxTool(server, ctx)dans le bon fichier soussrc/tools/.L'appeler depuis
src/index.ts.npm run build.Tester via MCP Inspector ou JSON-RPC manuel.
Licence
MIT — comme microsoft/BCQuality lui-même.
Available Tools
10 toolsbcquality_get_applicable_for_contextGet knowledge applicable to a development contextARead-onlyIdempotent
Workflow tool — given a development goal and a BC context (technologies, bc-version, …), returns all knowledge files that match every frontmatter dimension, with sections inlined for direct LLM consumption. Applies layer precedence: custom > community > microsoft. Suppressed candidates are surfaced for transparency.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | Yes | Free-text description of what the agent is trying to do. | |
| limit | No | ||
| layers | No | ||
| bcVersion | No | ||
| countries | No | ||
| technologies | No | ||
| applicationArea | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| applicable | Yes | |
| suppressed | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds critical behavioral details beyond annotations: layer precedence (custom > community > microsoft) and transparency of suppressed candidates. No contradiction with annotations (readOnlyHint, idempotentHint).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose and output format. Every sentence provides value without extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, output schema exists, and annotations present, the description covers key behaviors (precedence, transparency). Could be more explicit about parameter roles but adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 14% (only 'goal' described). The tool description does not elaborate on individual parameters beyond the overall context, failing to compensate for low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'returns' and resource 'knowledge files that match every frontmatter dimension', with specifics on inlined sections and layer precedence. Distinguishes from siblings by labeling itself a workflow tool and describing unique behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies use case: given a development goal and BC context. However, it lacks explicit when-not-to-use guidance or comparison with siblings like bcquality_search_knowledge or bcquality_get_knowledge.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_get_examplesGet BCQuality knowledge examplesARead-onlyIdempotent
Returns the content of the .good.al and/or .bad.al example files sibling to a knowledge file.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | both | |
| knowledgePath | Yes | Repo-relative path to the .md knowledge file. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bad | No | |
| good | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and idempotentHint=true. The description adds that it returns file content but no additional behavioral details like file size limits or error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with verb 'Returns', no waste. Every word is necessary and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity, existence of output schema, and annotations covering behavior, the description is sufficiently complete for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% with descriptions for both parameters. The description does not add extra meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns content of .good.al and/or .bad.al example files sibling to a knowledge file. It distinguishes from sibling tools like bcquality_get_knowledge which returns knowledge content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving example files but does not explicitly state when to use this tool versus alternatives or when to choose good, bad, or both.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_get_knowledgeGet BCQuality knowledge fileARead-onlyIdempotent
Returns the parsed frontmatter, title, and named sections (Description, Best Practice, Anti Pattern, …) of a knowledge file, plus the paths of associated .good.al / .bad.al examples if present.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Repo-relative path, e.g. microsoft/knowledge/performance/use-isempty-for-existence-check.md |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | Yes | |
| path | Yes | |
| title | Yes | |
| sections | Yes | |
| frontmatter | Yes | |
| exampleFiles | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, idempotentHint), description discloses it returns parsed content (frontmatter, sections) and associated example paths. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single, front-loaded sentence with no unnecessary words. Every part adds value: verb, resource, components of return value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With output schema present, description needn't detail return structure. Already covers key return elements (frontmatter, title, sections, example paths) and is complete for a retrieval tool with annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% description coverage for 'path', so baseline is 3. Description does not add further meaning beyond what schema already provides (repo-relative path).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb (returns) and resource (knowledge file content including frontmatter, title, sections, and example paths). Distinguishes from siblings like 'get_examples' and 'get_skill' by specifying it parses a single knowledge file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage: use for retrieving parsed knowledge file. No explicit when/when-not or comparison to sibling tools like 'search_knowledge' or 'get_applicable_for_context'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_get_skillGet BCQuality skill fileARead-onlyIdempotent
Returns the parsed contents of a skill file — either a meta-skill (skills/entry.md, read.md, do.md, write.md) or an action skill under /skills/.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Repo-relative path, e.g. skills/entry.md or microsoft/skills/review/al-performance-review.md |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | Yes | |
| kind | Yes | |
| path | Yes | |
| title | Yes | |
| frontmatter | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a safe, idempotent read. The description adds context about file types parsed but does not disclose error handling or limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no wasted words. Every clause adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the single parameter is well-defined, the description covers the tool's scope adequately. Minor gap: no mention of what 'parsed' entails beyond file types.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter 'path' is fully described in the schema with examples. The tool description reuses those examples, adding no new semantic information beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns parsed contents of skill files and distinguishes between meta-skills and action skills. It differentiates from sibling tools like bcquality_get_knowledge.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when needing parsed skill file contents but lacks explicit when-to-use or when-not-to-use guidance. No alternative tools are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_list_domainsList BCQuality domainsARead-onlyIdempotent
Lists all knowledge domains (performance, security, privacy, …) present in the configured BCQuality clone, with file counts and which layers contribute.
| Name | Required | Description | Default |
|---|---|---|---|
| layers | No | Subset of layers to consider (defaults to all enabled layers). |
Output Schema
| Name | Required | Description |
|---|---|---|
| domains | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark as read-only and idempotent. Description adds that it returns file counts and layer contributions, providing behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with verb and resource, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values are covered. Description fully captures the tool's purpose and key details (file counts, layers). No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and describes the single parameter 'layers' well. Description adds no further parameter details, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Lists' and resource 'knowledge domains', adding detail about file counts and layers. It clearly distinguishes from siblings like bcquality_list_knowledge which lists knowledge items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for overview of domains but provides no explicit when-to-use or when-not-to-use guidance. No alternative tools are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_list_knowledgeList BCQuality knowledge filesBRead-onlyIdempotent
Lists knowledge files with optional filters on layer, domain, technologies, bc-version, countries, application-area, and keywords. Supports pagination via limit/offset.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | No | ||
| limit | No | ||
| domain | No | ||
| offset | No | ||
| keywords | No | ||
| bcVersion | No | ||
| countries | No | ||
| technologies | No | ||
| applicationArea | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| total | Yes | |
| nextOffset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so description does not need to restate safety. The description adds value by specifying pagination via limit/offset and optional filters, which are behavioral details not fully captured in annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences are used: the first states the core functionality and lists filters, the second adds pagination details. No redundant or filler content; every sentence contributes value. Information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 9 optional parameters and an output schema, the description is too minimal. It does not explain typical use cases, how filters interact, or when to prefer list over search (bcquality_search_knowledge). The agent lacks sufficient context to choose and configure the tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It lists all parameter names (layer, domain, etc.) and categorizes them as optional filters, but does not explain their meanings or constraints. The schema provides enums and types, but the description adds a high-level grouping, which is helpful but insufficient for full understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists knowledge files with optional filters, which is a specific verb+resource. However, it does not explicitly differentiate from sibling tools like bcquality_search_knowledge or bcquality_get_knowledge, leaving ambiguity about when to use this vs alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool vs siblings or when not to use it. The description lists filters but does not explain scenarios where specific filters are appropriate, nor does it mention alternatives for other use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_list_skillsList BCQuality skillsARead-onlyIdempotent
Lists all skills (meta-skills under /skills/, host-skill adapters at skills//SKILL.md, and action skills under /skills/). Filter by layer or kind (action-skill | host-skill | meta).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | ||
| layer | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds context beyond the readOnlyHint and idempotentHint: it lists the exact skill locations and the filter dimensions. It does not disclose default behavior when no filters are supplied (though 'all skills' implies a full listing), how the two filters interact when combined, or whether sorting/pagination exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first states the general result and scope, the second lists the filter options. There is no redundant phrasing, and the key purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple list with optional filters and already has outputSchema and safety annotations. The description covers what is returned (skills of any of the listed kinds), the primary filter dimensions, and where those skills are located. The main remaining ambiguity is whether the layer filter applies only to action skills or to all categories, but the overall context is complete enough for selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It maps kind values to the skill categories, explains that action skills are tied to a layer, and the phrase 'filter by layer or kind' clarifies both are optional narrowing axes. The description stops short of explaining how layer values map to filter scope, but it adds genuine semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear verb+resource ('Lists all skills') and gives a specific breakdown of what counts as a skill: meta-skills, host-skill adapters, and action skills. This distinguishes it from sibling list tools (list_domains, list_knowledge) and the more specific get_skill tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells the agent when the tool is relevant (to list all skills) and that filtering by layer or kind is possible. However, it does not name alternatives or give exclusion criteria such as 'use get_skill to retrieve a single skill' or 'use search_knowledge when a full enumeration is not needed.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_refreshRefresh BCQuality cloneAIdempotent
Runs git pull on the active clone and rebuilds the in-memory index. Use after publishing new knowledge to your fork.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| after | Yes | |
| before | Yes | |
| rebuiltAt | Yes | |
| changedFiles | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate non-read-only, idempotent, and not destructive. Description adds specific behavioral details (git pull, in-memory index rebuild) that go beyond annotations, avoiding contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences: first explains action, second provides usage context. No waste, front-loaded with key behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and presence of an output schema, the description fully covers purpose, action, and usage timing. It is complete for a simple refresh tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist (schema coverage 100%), so description naturally adds no parameter info. Baseline is 4; description provides usage context instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs `git pull` on the active clone and rebuilds the in-memory index. It distinguishes from siblings which are mostly read-only queries (e.g., bcquality_get_knowledge, bcquality_list_domains).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use after publishing new knowledge to your fork,' providing a clear context. Does not list exclusions or alternatives, but the when-to-use guidance is straightforward and sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_search_knowledgeSearch BCQuality knowledgeARead-onlyIdempotent
Free-text search over knowledge files. Tokenizes the query and scores against frontmatter keywords, title, domain, and the Description section. Combine with structured filters for narrow results.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| domain | No | ||
| layers | No | ||
| bcVersion | No | ||
| countries | No | ||
| technologies | No | ||
| applicationArea | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| matches | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the tool is safe and idempotent. The description adds behavioral details about tokenization and scoring fields, which go beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise—two sentences that front-load the core purpose and add one additional use context. Every sentence adds value with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 parameters and an output schema, the description does not explain return values (though output schema exists), nor does it detail how to use each filter parameter. For a complex search tool, more guidance is needed for a complete agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning no parameter descriptions in the schema. The description only mentions the query parameter and vaguely references 'structured filters' without explaining each of the 8 parameters. This is insufficient for an agent to know how to fill them correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it performs free-text search over knowledge files, specifying the resource and action. It distinguishes from sibling tools like bcquality_get_knowledge (fetch specific) and bcquality_list_knowledge (list all) by emphasizing free-text and scoring.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises combining with structured filters for narrow results, providing clear context on when to use filters. However, it does not explicitly state when not to use the tool or mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bcquality_statusBCQuality server statusARead-onlyIdempotent
Returns the active clone path, its source (env/cache/cloned), the current commit, the actual origin remote of that clone alongside the configured repo URL, the enabled layers, article counts per layer, and the in-memory index age.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| commit | Yes | |
| layers | Yes | |
| source | Yes | |
| headSha | Yes | |
| repoUrl | Yes | |
| repoPath | Yes | |
| remoteUrl | No | |
| skillCount | Yes | |
| indexBuiltAt | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description reinforces non-mutating behavior with 'Returns...'. It adds useful operational context beyond annotations by enumerating exactly what state is exposed (clone source precedence, actual vs configured remote, in-memory index age).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence packs ten distinct pieces of returned information without fluff drugs, but the long enumeration makes it slightly harder to parse at a glance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters players, read-only annotations, and an output schema present, the description covers the observable behavior well; it doesn't explain when to call it or what triggers a stale index, but that is not essential for a status check.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters)Skip no param documentation needed. The output descriptor compensates for the empty input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Returns') tied to a clear resource ('active clone path', index age, article counts), and the detailed field list makes it obvious this is the read-only status snapshot tool distinct from sibling search/list/get/refresh operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit statement of when to use this versus alternatives like bcquality_refresh or bcquality_search_knowledge. The context is implied by the title and 'server status' framing, but no exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.4- Changed
bcquality_list_skills1 field changed- changed
Input schema / properties / kind / enumPrevious value: -[ - "action-skill", - "meta" -]New value: +[ + "action-skill", + "host-skill", + "meta" +]
- Changed
bcquality_status1 field changed- added
Output schema / properties / remoteUrlAdded value: +{ + "type": "string" +}
10 tool updates
v0.1.2- First observed
bcquality_get_applicable_for_context - First observed
bcquality_get_examples - First observed
bcquality_get_knowledge - First observed
bcquality_get_skill - First observed
bcquality_list_domains - First observed
bcquality_list_knowledge - First observed
bcquality_list_skills - First observed
bcquality_refresh - First observed
bcquality_search_knowledge - First observed
bcquality_status
TDQS
Scored across 10 tools
Each tool has a clearly distinct purpose: list/get/search for knowledge, list/get for skills, list domains, get examples, status, refresh, and context-aware retrieval. Even the three knowledge-discovery tools (list, search, applicable-for-context) are differentiated by filtering, free-text scoring, and layer-precedence workflow.
Most tools follow a consistent bcquality_<verb>_<noun> pattern (get_knowledge, list_skills, search_knowledge). Two names deviate slightly: bcquality_status is noun-only and bcquality_get_applicable_for_context uses a longer phrasal object, but the pattern remains predictable.
Ten tools is a well-scoped size for a knowledge/retrieval server. Each tool covers a distinct retrieval or maintenance operation without redundancy or feature creep.
The surface covers discovery (list domains/knowledge/skills), retrieval (get_knowledge/get_skill/get_examples/get_applicable_for_context), search, and maintenance (status/refresh). This is complete for a read-only knowledge MCP; no obvious dead ends remain.
Maintenance
Related MCP Connectors
MCP server exposing the Backtest360 engine API as tools for AI agents.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
100+ MCP tools for AI agents: content metadata, trade intelligence, business-expertise analysis.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to perform Business Central AL development tasks including language server operations, container management, Git version control, and file system operations for professional BC development workflows.-
- FlicenseNot gradedqualityDmaintenanceEnables AI clients to interact with Microsoft Dynamics 365 Business Central through MCP, providing access to customers, items, sales orders, and allowing creation of new records via natural language.2-
- AlicenseAqualityCmaintenanceExposes structured Microsoft Dynamics 365 Business Central source code (versions 23-29, 47 localizations) to AI agents via MCP, enabling fast lookups, searches, and code analysis.1412 npmMIT
- AlicenseAqualityDmaintenanceModel Context Protocol (MCP) server for Microsoft Dynamics 365 Business Central. Provides AI assistants with direct access to Business Central data through properly formatted API v2.0 calls.68 npm8MIT