@habitusnet/bc365 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/onboard.js CHANGED
@@ -71,4 +71,5 @@ export async function onboard(options = {}) {
71
71
  const name = profileName ?? `${selectedEnv.aadTenantId}/${envName}`;
72
72
  await saveProfile(name, ctx);
73
73
  console.log(`✓ Saved profile '${name}'`);
74
+ console.log(`\nTo get BC-aware Claude skills, run:\n claude plugin install habitusnet/bc365-skills`);
74
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@habitusnet/bc365",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Smart onboarding CLI and MCP config manager for Business Central",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: bc-admin
3
+ description: Manage Microsoft Dynamics 365 Business Central environments, companies, installed apps, feature flags, and user sessions using the bc-admin MCP server. Use when the user asks about environment status, app updates, permissions, or wants to perform admin operations.
4
+ allowed-tools: ["mcp__bc-admin__get_environment_informations", "mcp__bc-admin__get_environment_companies", "mcp__bc-admin__get_installed_apps", "mcp__bc-admin__get_available_app_updates", "mcp__bc-admin__update_app", "mcp__bc-admin__get_available_features", "mcp__bc-admin__activate_feature", "mcp__bc-admin__deactivate_feature", "mcp__bc-admin__get_active_sessions", "mcp__bc-admin__kill_active_sessions", "mcp__bc-admin__get_usage_storage_for_environment", "mcp__bc-admin__get_usage_storage_for_all_environments", "mcp__bc-admin__clear_cached_token", "mcp__bc-admin__get_token_cache_status", "mcp__bc-admin__get_extension_deployment_status", "mcp__bc-admin__get_app_operations"]
5
+ ---
6
+
7
+ # BC Admin Skill
8
+
9
+ Manage Business Central environments and tenant operations via the `bc-admin` MCP server.
10
+
11
+ ## Prerequisites
12
+
13
+ The `bc-admin` MCP server must be configured in `.mcp.json` (run `bc365 onboard` if not). The `BC_TENANT_ID` environment variable must be set to the tenant's Entra ID GUID.
14
+
15
+ ## Tool Reference
16
+
17
+ ### Environment & Company
18
+
19
+ | Tool | Purpose |
20
+ |------|---------|
21
+ | `mcp__bc-admin__get_environment_informations()` | List all environments for the tenant |
22
+ | `mcp__bc-admin__get_environment_companies(environment)` | List companies in an environment |
23
+ | `mcp__bc-admin__get_usage_storage_for_environment(environment)` | Storage usage for one environment |
24
+ | `mcp__bc-admin__get_usage_storage_for_all_environments()` | Storage usage across all environments |
25
+
26
+ ### Apps & Extensions
27
+
28
+ | Tool | Purpose |
29
+ |------|---------|
30
+ | `mcp__bc-admin__get_installed_apps(environment)` | List installed AL apps/extensions |
31
+ | `mcp__bc-admin__get_available_app_updates(environment)` | List apps with pending updates |
32
+ | `mcp__bc-admin__update_app(environment, appId, appVersion)` | Update an app to a specific version |
33
+ | `mcp__bc-admin__get_extension_deployment_status(environment, operationId)` | Check app deployment status |
34
+ | `mcp__bc-admin__get_app_operations(environment)` | List all app operations and their status |
35
+
36
+ ### Feature Flags
37
+
38
+ | Tool | Purpose |
39
+ |------|---------|
40
+ | `mcp__bc-admin__get_available_features(environment)` | List all BC feature flags and their state |
41
+ | `mcp__bc-admin__activate_feature(environment, feature)` | Enable a feature flag |
42
+ | `mcp__bc-admin__deactivate_feature(environment, feature)` | Disable a feature flag |
43
+
44
+ ### Sessions
45
+
46
+ | Tool | Purpose |
47
+ |------|---------|
48
+ | `mcp__bc-admin__get_active_sessions(environment)` | List currently active user sessions |
49
+ | `mcp__bc-admin__kill_active_sessions(environment)` | Force-disconnect all sessions (e.g. before upgrade) |
50
+
51
+ ### Auth
52
+
53
+ | Tool | Purpose |
54
+ |------|---------|
55
+ | `mcp__bc-admin__get_token_cache_status()` | Check if cached token is valid |
56
+ | `mcp__bc-admin__clear_cached_token()` | Clear stale auth token (then re-run `bc365 onboard`) |
57
+
58
+ ## Common Workflows
59
+
60
+ ### Inspect environments
61
+ ```
62
+ mcp__bc-admin__get_environment_informations()
63
+ # Returns: name, type (Production/Sandbox), applicationVersion, status
64
+ ```
65
+
66
+ ### List companies in Production
67
+ ```
68
+ mcp__bc-admin__get_environment_companies(environment="Production")
69
+ # Returns: id (GUID), name, displayName — use id as BC_COMPANY in .mcp.json
70
+ ```
71
+
72
+ ### Check for app updates
73
+ ```
74
+ mcp__bc-admin__get_available_app_updates(environment="Production")
75
+ # Returns: appId, name, currentVersion, latestVersion
76
+ ```
77
+
78
+ ### Update an app
79
+ ```
80
+ # 1. Get current installed apps and their IDs
81
+ mcp__bc-admin__get_installed_apps(environment="Production")
82
+
83
+ # 2. Check for available updates
84
+ mcp__bc-admin__get_available_app_updates(environment="Production")
85
+
86
+ # 3. Update (always confirm with user first — this affects a live environment)
87
+ mcp__bc-admin__update_app(environment="Production", appId="<guid>", appVersion="<latestVersion>")
88
+
89
+ # 4. Monitor deployment
90
+ mcp__bc-admin__get_extension_deployment_status(environment="Production", operationId="<operationId from step 3>")
91
+
92
+ # 5. Or check all pending operations
93
+ mcp__bc-admin__get_app_operations(environment="Production")
94
+ ```
95
+
96
+ ### Prepare for maintenance (force logout users)
97
+ ```
98
+ # 1. Check who is logged in
99
+ mcp__bc-admin__get_active_sessions(environment="Production")
100
+
101
+ # 2. Confirm with user before disconnecting — this will interrupt active work
102
+ mcp__bc-admin__kill_active_sessions(environment="Production")
103
+ ```
104
+
105
+ ### Check storage usage
106
+ ```
107
+ mcp__bc-admin__get_usage_storage_for_all_environments()
108
+ # Returns: environment name, database size, file size in GB
109
+ ```
110
+
111
+ ### Manage feature flags
112
+ ```
113
+ # List available features and their current state
114
+ mcp__bc-admin__get_available_features(environment="Production")
115
+
116
+ # Enable a feature (confirm with user — some features cannot be disabled after activation)
117
+ mcp__bc-admin__activate_feature(environment="Production", feature="<featureKey>")
118
+ ```
119
+
120
+ ## Auth Troubleshooting
121
+
122
+ If bc-admin calls return 401 errors:
123
+ ```
124
+ mcp__bc-admin__get_token_cache_status()
125
+ # If expired or missing:
126
+ mcp__bc-admin__clear_cached_token()
127
+ # Then tell user: run `bc365 onboard` to re-authenticate
128
+ ```
129
+
130
+ ## Profile & Environment Context
131
+
132
+ The active tenant is set by the `BC_TENANT_ID` env var in `.mcp.json`. To switch tenant/environment:
133
+ ```bash
134
+ bc365 switch <profile-name> # updates .mcp.json to a different profile
135
+ bc365 profiles # list saved profiles
136
+ ```
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: bc-diagnose
3
+ description: Interpret Microsoft Dynamics 365 Business Central error messages and API failures, and suggest specific fixes. Use when the user receives an HTTP error, OData error, permission error, or unexpected BC behaviour. Cross-references bc-admin skill for permission lookups.
4
+ ---
5
+
6
+ # BC Diagnose Skill
7
+
8
+ Interpret Business Central errors and guide the user to the correct fix.
9
+
10
+ ## HTTP Status Codes
11
+
12
+ ### 401 Unauthorized
13
+ **Meaning:** The access token is expired, missing, or invalid.
14
+
15
+ **Fix steps:**
16
+ 1. Check token health: `mcp__bc-admin__get_token_cache_status()`
17
+ 2. Clear the cached token: `mcp__bc-admin__clear_cached_token()`
18
+ 3. Tell the user: `bc365 logout && bc365 onboard` to re-authenticate
19
+
20
+ If `bc365 onboard` also fails with 401, the Entra ID app registration may have expired or the user's device code session timed out. Ask the user to run `bc365 onboard` in a terminal with a TTY.
21
+
22
+ ### 403 Forbidden
23
+ **Meaning:** Authenticated successfully, but the user lacks a required permission set.
24
+
25
+ **Fix steps:**
26
+ 1. List companies via bc-admin to confirm the correct company: `mcp__bc-admin__get_environment_companies(environment="Production")`
27
+ 2. Common missing permission sets:
28
+ - `D365 BUS FULL ACCESS` — general read/write access
29
+ - `D365 BASIC` — minimum read access
30
+ - `D365 ACCOUNTANT` — finance/G/L access
31
+ - `D365 SALES` — sales access
32
+ - `D365 PURCHASING` — purchasing access
33
+ - `SUPER` — admin only
34
+ 3. A BC administrator must assign the missing permission in the BC UI (Settings → Users → select user → Permission Sets) — this cannot be done via MCP
35
+
36
+ ### 404 Not Found
37
+ **Meaning:** The entity or endpoint does not exist. Most common causes:
38
+
39
+ | Cause | Symptom | Fix |
40
+ |-------|---------|-----|
41
+ | Wrong company GUID | 404 on any data request | Run `bc365 profiles`, compare `BC_COMPANY` in `.mcp.json` with actual company ID from `mcp__bc-admin__get_environment_companies` |
42
+ | Wrong API version | URL has `/v1.0/` instead of `/v2.0/` | Check `BC_URL_SERVER` in `.mcp.json` — should end in `/api/v2.0` |
43
+ | Entity name wrong | 404 on specific entity | Use the exact camelCase entity name (e.g. `salesOrders` not `sales_orders`) — use `bc-query` skill for the full entity list |
44
+ | Record deleted | 404 on specific ID | The record no longer exists — list the entity to confirm |
45
+
46
+ ### 429 Too Many Requests
47
+ **Meaning:** BC's API rate limit was hit.
48
+
49
+ **Fix steps:**
50
+ 1. Wait 30–60 seconds before retrying
51
+ 2. Reduce query size: add `top=50` to `list_items` calls
52
+ 3. Avoid broad queries with no filter on large entities (e.g. `generalLedgerEntries` without a date filter)
53
+ 4. If hitting limits repeatedly, schedule bulk operations during off-peak hours
54
+
55
+ ### 500 Internal Server Error
56
+ **Meaning:** BC server-side error. Usually transient.
57
+
58
+ **Fix steps:**
59
+ 1. Retry the same operation after 30 seconds
60
+ 2. If persistent, check BC service health at [aka.ms/bchealth](https://aka.ms/bchealth)
61
+ 3. Check environment status: `mcp__bc-admin__get_environment_informations()` — look for `status: Updating`
62
+
63
+ ### 503 Service Unavailable
64
+ **Meaning:** BC environment is unavailable (often during scheduled maintenance or upgrade).
65
+
66
+ **Fix steps:**
67
+ 1. `mcp__bc-admin__get_environment_informations()` — check `status` field
68
+ 2. If `status: Updating` — wait for upgrade to complete
69
+ 3. Monitor upgrade progress: `mcp__bc-admin__get_app_operations(environment="Production")`
70
+ 4. If unexpected downtime, report to Microsoft via BC Admin Center
71
+
72
+ ## OData Errors
73
+
74
+ ### Filter parse error
75
+ **Symptom:** `BadRequest` or `An error occurred while reading from the store provider's data reader`
76
+
77
+ **Cause:** OData `$filter` syntax error.
78
+
79
+ **Common mistakes:**
80
+ - String values must be in single quotes: `displayName eq 'Contoso'` (not double quotes)
81
+ - Date values need full ISO format: `postingDate gt 2024-01-01T00:00:00Z`
82
+ - Field names are camelCase: `displayName` not `Display Name`
83
+ - Use `mcp__bc-data__get_schema(entity="...")` to verify correct field names
84
+
85
+ ### Unauthorized in OData response body
86
+ **Cause:** bc-data server uses `azure_cli` auth — `az login` token has expired.
87
+
88
+ **Fix:** Tell the user to run `az login` to refresh Azure CLI credentials.
89
+
90
+ ### ResourceNotFound in OData response
91
+ **Cause:** Company GUID mismatch or entity not available in this BC version.
92
+
93
+ **Fix:**
94
+ 1. Verify company: `mcp__bc-admin__get_environment_companies(environment="Production")`
95
+ 2. Compare with `BC_COMPANY` in `.mcp.json`
96
+ 3. If mismatch: `bc365 onboard` to regenerate config with the correct company
97
+
98
+ ## Permission Set Reference
99
+
100
+ | Permission Set | Grants |
101
+ |----------------|--------|
102
+ | `D365 BUS FULL ACCESS` | Full read/write on business data |
103
+ | `D365 BASIC` | Read-only on most business data |
104
+ | `D365 ACCOUNTANT` | Full access to finance/G/L |
105
+ | `D365 SALES` | Full access to sales |
106
+ | `D365 PURCHASING` | Full access to purchasing |
107
+ | `SUPER` | Full system access including user management (admin only) |
108
+
109
+ ## Diagnostic Workflow
110
+
111
+ When a user reports an error, follow this sequence:
112
+
113
+ 1. **Identify the HTTP status code** — use the tables above
114
+ 2. **Check token health first** (most errors are auth-related):
115
+ ```
116
+ mcp__bc-admin__get_token_cache_status()
117
+ ```
118
+ 3. **Verify the environment is up**:
119
+ ```
120
+ mcp__bc-admin__get_environment_informations()
121
+ ```
122
+ 4. **Reproduce with a minimal query** — try this as a baseline:
123
+ ```
124
+ mcp__bc-data__list_items(entity="companies", top=1)
125
+ ```
126
+ 5. **Verify BC_COMPANY matches** — compare `mcp__bc-admin__get_environment_companies` output with the `BC_COMPANY` value in `.mcp.json`
127
+ 6. **Check field names** — if the error is filter-related, use `mcp__bc-data__get_schema` to confirm field names
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: bc-query
3
+ description: Query and update Microsoft Dynamics 365 Business Central data using the bc-data MCP server. Use when the user asks to list customers, find items, check sales orders, query general ledger entries, or any other BC data operation.
4
+ allowed-tools: ["mcp__bc-data__list_items", "mcp__bc-data__get_items_by_field", "mcp__bc-data__get_schema", "mcp__bc-data__create_item", "mcp__bc-data__update_item", "mcp__bc-data__delete_item"]
5
+ ---
6
+
7
+ # BC Query Skill
8
+
9
+ Query and update Business Central data via the `bc-data` MCP server.
10
+
11
+ ## Prerequisites
12
+
13
+ The `bc-data` MCP server must be configured in `.mcp.json` (run `bc365 onboard` if not). The server uses Azure CLI credentials — run `az login` if you see auth errors.
14
+
15
+ ## Available Tools
16
+
17
+ | Tool | Purpose |
18
+ |------|---------|
19
+ | `mcp__bc-data__list_items` | List entities with optional OData filtering |
20
+ | `mcp__bc-data__get_items_by_field` | Find records matching a specific field value |
21
+ | `mcp__bc-data__get_schema` | Discover available fields for an entity |
22
+ | `mcp__bc-data__create_item` | Create a new record |
23
+ | `mcp__bc-data__update_item` | Update an existing record by ID |
24
+ | `mcp__bc-data__delete_item` | Delete a record by ID |
25
+
26
+ ## Common Entity Names
27
+
28
+ Use these exact strings as the `entity` parameter:
29
+
30
+ | Entity | Description |
31
+ |--------|-------------|
32
+ | `customers` | Customer master records |
33
+ | `vendors` | Vendor master records |
34
+ | `items` | Item (product/service) master |
35
+ | `salesOrders` | Sales order headers |
36
+ | `salesInvoices` | Posted sales invoices |
37
+ | `purchaseOrders` | Purchase order headers |
38
+ | `purchaseInvoices` | Posted purchase invoices |
39
+ | `generalLedgerEntries` | G/L ledger entries |
40
+ | `accounts` | Chart of accounts |
41
+ | `companies` | Companies in this environment |
42
+ | `currencies` | Currency codes and exchange rates |
43
+ | `paymentTerms` | Payment term codes |
44
+
45
+ ## Querying Patterns
46
+
47
+ ### List all records (with limit)
48
+ ```
49
+ mcp__bc-data__list_items(entity="customers", top=50)
50
+ ```
51
+
52
+ ### Filter by field value
53
+ ```
54
+ mcp__bc-data__list_items(entity="customers", filter="displayName eq 'Contoso'")
55
+ mcp__bc-data__list_items(entity="items", filter="startswith(displayName, 'BIKE')")
56
+ mcp__bc-data__list_items(entity="salesOrders", filter="sellToCustomerNumber eq '10000'")
57
+ ```
58
+
59
+ ### Select specific fields (reduces payload)
60
+ ```
61
+ mcp__bc-data__list_items(entity="customers", select="number,displayName,email,phoneNumber", top=100)
62
+ ```
63
+
64
+ ### Find by known field value (simpler than filter)
65
+ ```
66
+ mcp__bc-data__get_items_by_field(entity="customers", field="number", value="10000")
67
+ mcp__bc-data__get_items_by_field(entity="items", field="number", value="ITEM-001")
68
+ ```
69
+
70
+ ### Discover available fields before querying
71
+ ```
72
+ mcp__bc-data__get_schema(entity="salesOrders")
73
+ ```
74
+ Always call `get_schema` first when the user asks about a field you haven't seen before.
75
+
76
+ ### Sort results
77
+ ```
78
+ mcp__bc-data__list_items(entity="generalLedgerEntries", filter="postingDate gt 2024-01-01", orderby="postingDate desc", top=200)
79
+ ```
80
+
81
+ ### Paginate large result sets
82
+ If the response contains `@odata.nextLink`, call `list_items` again with a `skip` offset:
83
+ ```
84
+ mcp__bc-data__list_items(entity="generalLedgerEntries", top=200, skip=200)
85
+ ```
86
+
87
+ ## OData Filter Syntax
88
+
89
+ BC uses OData v4. Supported operators:
90
+ - Equality: `field eq 'value'` or `field eq 12345`
91
+ - Comparison: `field gt value`, `field lt value`, `field ge value`, `field le value`
92
+ - String: `startswith(field, 'prefix')`, `contains(field, 'substring')`
93
+ - Date: `postingDate gt 2024-01-01T00:00:00Z`
94
+ - Combine: `field1 eq 'x' and field2 gt 100`
95
+
96
+ **Common mistake:** Field names are camelCase in the API (`displayName`, `sellToCustomerNumber`), NOT the BC UI names ("Name", "Sell-to Customer No."). Use `get_schema` to find the correct API field name.
97
+
98
+ ## Write Operations (use with care)
99
+
100
+ Before creating or updating, always call `get_schema` to see required fields and field types.
101
+
102
+ ```
103
+ # Create a new customer
104
+ mcp__bc-data__create_item(entity="customers", data={"displayName": "New Corp", "currencyCode": "CHF"})
105
+
106
+ # Update a customer's email
107
+ mcp__bc-data__update_item(entity="customers", id="<guid>", data={"email": "new@example.com"})
108
+ ```
109
+
110
+ Destructive operations (`delete_item`) require the record's GUID `id`, not its BC number. Always confirm with the user before deleting.