Skip to content

Commit 39d0f81

Browse files
committed
Add DaxFormatter MCP server (typescript/stdio)
1 parent a5f2b96 commit 39d0f81

27 files changed

Lines changed: 3156 additions & 1 deletion

.github/dependabot.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,15 @@ updates:
1919
interval: "weekly"
2020
open-pull-requests-limit: 10
2121
assignees:
22-
- "albertospelta"
22+
- "albertospelta"
23+
24+
- package-ecosystem: "npm"
25+
directory: "/mcp"
26+
schedule:
27+
interval: "weekly"
28+
open-pull-requests-limit: 10
29+
assignees:
30+
- "albertospelta"
31+
groups:
32+
dev-dependencies:
33+
dependency-type: "development"

.github/workflows/ci-mcp.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: ci-mcp
2+
3+
on:
4+
pull_request:
5+
branches: [master]
6+
paths:
7+
- mcp/**
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
build-and-test:
15+
name: build-and-test
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 15
18+
steps:
19+
- uses: actions/checkout@v6
20+
with:
21+
persist-credentials: false
22+
23+
- uses: actions/setup-node@v6
24+
with:
25+
node-version: "20"
26+
cache: npm
27+
cache-dependency-path: mcp/package-lock.json
28+
29+
- name: install
30+
working-directory: mcp
31+
run: npm ci
32+
33+
- name: lint
34+
working-directory: mcp
35+
run: npm run lint
36+
37+
- name: typecheck
38+
working-directory: mcp
39+
run: npm run typecheck
40+
41+
- name: build
42+
working-directory: mcp
43+
run: npm run build
44+
45+
- name: test
46+
working-directory: mcp
47+
run: npm test

.github/workflows/publish-mcp.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: publish-mcp
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
contents: read
8+
id-token: write # npm provenance
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 15
14+
steps:
15+
- uses: actions/checkout@v6
16+
with:
17+
fetch-depth: 0 # Nerdbank.GitVersioning needs full history
18+
persist-credentials: false
19+
20+
- uses: actions/setup-dotnet@v5
21+
with:
22+
global-json-file: global.json
23+
24+
- name: install
25+
working-directory: mcp
26+
run: npm ci
27+
28+
- name: build
29+
working-directory: mcp
30+
run: npm run build
31+
32+
- name: test
33+
working-directory: mcp
34+
run: npm test
35+
36+
- uses: actions/setup-node@v6
37+
with:
38+
node-version: "20"
39+
registry-url: "https://registry.npmjs.org"
40+
cache: npm
41+
cache-dependency-path: mcp/package-lock.json
42+
43+
# `prepack` stamps the Nerdbank.GitVersioning version into package.json; `postpack` resets it.
44+
- name: publish
45+
working-directory: mcp
46+
run: npm publish --provenance --access public
47+
env:
48+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

mcp/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
dist/
3+
coverage/
4+
*.tsbuildinfo

mcp/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# @sqlbi/daxformatter-mcp
2+
3+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that formats and
4+
validates DAX from any MCP-enabled AI client — Claude Code,
5+
Claude Desktop, Cursor, VS Code, and others — using the SQLBI DAX Formatter service.
6+
7+
Requires [Node.js](https://nodejs.org) 18+.
8+
9+
## Add it to your client
10+
11+
**Claude Code** (CLI):
12+
13+
```bash
14+
claude mcp add daxformatter -- npx -y @sqlbi/daxformatter-mcp
15+
```
16+
17+
**Other clients** — add this to the client's MCP configuration (e.g. `.mcp.json`,
18+
`claude_desktop_config.json`):
19+
20+
```json
21+
{
22+
"mcpServers": {
23+
"daxformatter": {
24+
"command": "npx",
25+
"args": ["-y", "@sqlbi/daxformatter-mcp"]
26+
}
27+
}
28+
}
29+
```
30+
31+
No separate install step: `npx` downloads and runs the server on demand.
32+
33+
## What it does
34+
35+
The server exposes a single tool, **`format_dax`** — just ask your assistant to format or check
36+
some DAX and it will use it:
37+
38+
- Formats one or more DAX expressions in a single call.
39+
- Reports syntax errors with their line and column, so the same call both **formats** and
40+
**validates** (an expression that can't be parsed comes back unformatted, with the errors).
41+
- Optional formatting controls: line style, spacing, and the list/decimal separators.
42+
43+
## Privacy
44+
45+
Your DAX is sent to the DAX Formatter web service (`daxformatter.com`), where the formatting
46+
happens. If you provide server or database names, they are **SHA-256 hashed** before being sent —
47+
they never leave your machine in clear text.
48+
49+
## License
50+
51+
[MIT](https://github.com/sql-bi/DaxFormatter/blob/master/LICENSE.md)

mcp/biome.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"organizeImports": { "enabled": true },
4+
"linter": {
5+
"enabled": true,
6+
"rules": { "recommended": true }
7+
},
8+
"formatter": {
9+
"enabled": true,
10+
"indentStyle": "space",
11+
"indentWidth": 2,
12+
"lineWidth": 100
13+
},
14+
"files": {
15+
"ignore": ["dist", "node_modules", "coverage"]
16+
}
17+
}

0 commit comments

Comments
 (0)