@integrity-labs/xero-mcp-server
v0.0.19
Published
Augmented Team fork of @xeroapi/xero-mcp-server adding XERO_TENANT_ID env var support (ENG-4898). Pins multi-tenant OAuth tokens to an explicit tenant instead of silently defaulting to tenants[0].
Maintainers
Readme
@integrity-labs/xero-mcp-server
Augmented Team fork of @xeroapi/xero-mcp-server (MIT, Xero Limited) — same MCP server, plus XERO_TENANT_ID env-var support so multi-tenant OAuth tokens can be pinned to an explicit tenant.
Why this fork exists (ENG-4898)
The upstream MCP server is designed for Xero Custom Connections — a flow that issues single-tenant tokens via client_credentials. With those tokens the upstream's "always pick tenants[0]" behaviour is correct, because there's only ever one tenant in the list.
Augmented Team's integration uses 3-leg OAuth, which returns a multi-tenant access token: it grants access to every Xero organisation the OAuth user has previously connected. Without explicit tenant pinning, the upstream server picks whichever tenant Xero happens to return first — which is not necessarily the one the operator selected during consent. That's a cross-tenant data leak: an agent in Org A could return Org B's invoices.
This fork adds the missing knob:
if (this.tenants && this.tenants.length > 0) {
- this.tenantId = this.tenants[0].tenantId;
+ const desired = process.env.XERO_TENANT_ID;
+ if (desired) {
+ const match = this.tenants.find((t) => t.tenantId === desired);
+ if (!match) {
+ throw new Error(`XERO_TENANT_ID=${desired} not in token's tenant list…`);
+ }
+ this.tenantId = desired;
+ } else {
+ this.tenantId = this.tenants[0].tenantId;
+ }
}Set XERO_TENANT_ID in the MCP server's env to pin. Leave it unset and the behaviour matches upstream.
Failure mode if mis-configured
If XERO_TENANT_ID is set to an ID that the bearer token doesn't have access to, the server throws on updateTenants / requestToken with the available IDs in the error message. That's deliberate — silently falling back to tenants[0] is the original bug.
Upstream sync
When pulling a new upstream release:
git remote add xero-upstream https://github.com/XeroAPI/xero-mcp-server.git(one-time).git fetch xero-upstream.git merge --no-commit xero-upstream/main(orgit checkout xero-upstream/main -- src/).- Re-apply the
XERO_TENANT_IDenv-var patch insrc/clients/xero-client.ts(two call sites:MCPXeroClient.updateTenantsandCustomConnectionsXeroClient.requestToken). - Bump
versioninpackage.json. npm publish(public,@integrity-labsscope).
A tracking PR upstream would let us drop the fork once merged. See [Issue / PR link in ENG-4898].
License
MIT — same as upstream. See UPSTREAM_LICENSE for the original Xero notice.
