@bonnard/cli 0.2.4 → 0.2.6
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/README.md +85 -0
- package/dist/bin/bon.mjs +15 -2
- package/dist/bin/{validate-BdqZBH2n.mjs → validate-Bc8zGNw7.mjs} +75 -3
- package/dist/docs/_index.md +17 -6
- package/dist/docs/topics/catalog.md +36 -0
- package/dist/docs/topics/cli.deploy.md +193 -0
- package/dist/docs/topics/cli.md +113 -0
- package/dist/docs/topics/cli.validate.md +125 -0
- package/dist/docs/topics/cubes.data-source.md +1 -1
- package/dist/docs/topics/features.governance.md +58 -59
- package/dist/docs/topics/features.semantic-layer.md +6 -0
- package/dist/docs/topics/getting-started.md +2 -2
- package/dist/docs/topics/governance.md +83 -0
- package/dist/docs/topics/overview.md +49 -0
- package/dist/docs/topics/querying.mcp.md +200 -0
- package/dist/docs/topics/querying.md +11 -0
- package/dist/docs/topics/querying.rest-api.md +198 -0
- package/dist/docs/topics/querying.sdk.md +53 -0
- package/dist/docs/topics/slack-teams.md +18 -0
- package/dist/docs/topics/views.md +17 -9
- package/dist/docs/topics/workflow.md +6 -5
- package/dist/templates/claude/skills/bonnard-design-guide/SKILL.md +233 -0
- package/dist/templates/claude/skills/bonnard-get-started/SKILL.md +49 -15
- package/dist/templates/claude/skills/bonnard-metabase-migrate/SKILL.md +28 -9
- package/dist/templates/cursor/rules/bonnard-design-guide.mdc +232 -0
- package/dist/templates/cursor/rules/bonnard-get-started.mdc +49 -15
- package/dist/templates/cursor/rules/bonnard-metabase-migrate.mdc +28 -9
- package/dist/templates/shared/bonnard.md +28 -11
- package/package.json +2 -2
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Validate
|
|
2
|
+
|
|
3
|
+
> Run validation checks on your cubes and views before deploying to catch YAML syntax errors, missing references, circular joins, and other issues. Use `bon validate` from the CLI.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `bon validate` command checks your YAML cubes and views for syntax errors and schema violations. Run this before deploying to catch issues early.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bon validate
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What Gets Validated
|
|
16
|
+
|
|
17
|
+
### YAML Syntax
|
|
18
|
+
|
|
19
|
+
- Valid YAML format
|
|
20
|
+
- Proper indentation
|
|
21
|
+
- Correct quoting
|
|
22
|
+
|
|
23
|
+
### Schema Compliance
|
|
24
|
+
|
|
25
|
+
- Required fields present (name, type, sql)
|
|
26
|
+
- Valid field values (known measure types, relationship types)
|
|
27
|
+
- Consistent naming conventions
|
|
28
|
+
|
|
29
|
+
### Reference Integrity
|
|
30
|
+
|
|
31
|
+
- Referenced cubes exist
|
|
32
|
+
- Referenced members exist
|
|
33
|
+
- Join relationships are valid
|
|
34
|
+
|
|
35
|
+
## Example Output
|
|
36
|
+
|
|
37
|
+
### Success
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
✓ Validating YAML syntax...
|
|
41
|
+
✓ Checking bonnard/cubes/orders.yaml
|
|
42
|
+
✓ Checking bonnard/cubes/users.yaml
|
|
43
|
+
✓ Checking bonnard/views/orders_overview.yaml
|
|
44
|
+
|
|
45
|
+
All cubes and views valid.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Errors
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
✗ Validating YAML syntax...
|
|
52
|
+
|
|
53
|
+
bonnard/cubes/orders.yaml:15:5
|
|
54
|
+
error: Unknown measure type "counts"
|
|
55
|
+
|
|
56
|
+
Did you mean "count"?
|
|
57
|
+
|
|
58
|
+
14: measures:
|
|
59
|
+
15: - name: order_count
|
|
60
|
+
16: type: counts <-- here
|
|
61
|
+
17: sql: id
|
|
62
|
+
|
|
63
|
+
1 error found.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Common Errors
|
|
67
|
+
|
|
68
|
+
### Missing Required Field
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
# Error: "sql" is required
|
|
72
|
+
measures:
|
|
73
|
+
- name: count
|
|
74
|
+
type: count
|
|
75
|
+
# Missing: sql: id
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Invalid Type
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
# Error: Unknown dimension type "text"
|
|
82
|
+
dimensions:
|
|
83
|
+
- name: status
|
|
84
|
+
type: text # Should be: string
|
|
85
|
+
sql: status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Reference Not Found
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
# Error: Cube "user" not found (did you mean "users"?)
|
|
92
|
+
joins:
|
|
93
|
+
- name: user
|
|
94
|
+
relationship: many_to_one
|
|
95
|
+
sql: "{CUBE}.user_id = {user.id}"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### YAML Syntax
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
# Error: Bad indentation
|
|
102
|
+
measures:
|
|
103
|
+
- name: count # Should be indented
|
|
104
|
+
type: count
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Exit Codes
|
|
108
|
+
|
|
109
|
+
| Code | Meaning |
|
|
110
|
+
|------|---------|
|
|
111
|
+
| 0 | All validations passed |
|
|
112
|
+
| 1 | Validation errors found |
|
|
113
|
+
|
|
114
|
+
## Best Practices
|
|
115
|
+
|
|
116
|
+
1. **Run before every deploy** — `bon validate && bon deploy`
|
|
117
|
+
2. **Add to CI/CD** — validate on pull requests
|
|
118
|
+
3. **Fix errors first** — don't deploy with validation errors
|
|
119
|
+
4. **Test connections** — connections are tested automatically during `bon deploy`
|
|
120
|
+
|
|
121
|
+
## See Also
|
|
122
|
+
|
|
123
|
+
- cli
|
|
124
|
+
- cli.deploy
|
|
125
|
+
- syntax
|
|
@@ -1,84 +1,83 @@
|
|
|
1
1
|
# Governance
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Control who can see which views, columns, and rows in your semantic layer.
|
|
4
4
|
|
|
5
|
-
Bonnard
|
|
5
|
+
Bonnard provides admin-managed data governance — control which views, columns, and rows each group of users can access. Policies are configured in the web UI and enforced automatically across MCP queries and the API. Changes take effect within one minute.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## How It Works
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```
|
|
10
|
+
Admin configures in web UI:
|
|
11
|
+
Groups → Views → Field/Row restrictions
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- name: orders
|
|
14
|
-
access_policy:
|
|
15
|
-
- role: sales_manager
|
|
16
|
-
row_level:
|
|
17
|
-
filters:
|
|
18
|
-
- member: region
|
|
19
|
-
operator: equals
|
|
20
|
-
values: ["{ securityContext.region }"]
|
|
13
|
+
Enforced automatically:
|
|
14
|
+
MCP queries + API → only see what policies allow
|
|
21
15
|
```
|
|
22
16
|
|
|
23
|
-
|
|
17
|
+
Governance uses **groups** as the unit of access. Each group has a set of **policies** that define which views its members can see, and optionally restrict specific columns or rows within those views.
|
|
24
18
|
|
|
25
|
-
##
|
|
19
|
+
## Groups
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
Groups represent teams or roles in your organization — "Sales Team", "Finance", "Executive". Create and manage groups from the **Governance** page in the Bonnard dashboard.
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
member_level:
|
|
35
|
-
includes:
|
|
36
|
-
- count
|
|
37
|
-
- total_revenue
|
|
38
|
-
- status
|
|
39
|
-
- created_at
|
|
23
|
+
Each group has:
|
|
24
|
+
- **Name** and optional description
|
|
25
|
+
- **Color** for visual identification
|
|
26
|
+
- **View access** — which views the group can query
|
|
27
|
+
- **Members** — which users belong to the group
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
member_level:
|
|
43
|
-
includes: "*"
|
|
44
|
-
```
|
|
29
|
+
Users can belong to multiple groups. Their effective access is the **union** of all group policies.
|
|
45
30
|
|
|
46
|
-
|
|
31
|
+
## View-Level Access (Level 1)
|
|
47
32
|
|
|
48
|
-
|
|
33
|
+
The simplest control: toggle which views a group can see. Unchecked views are completely invisible to group members — they won't appear in `explore_schema` or be queryable.
|
|
49
34
|
|
|
50
|
-
|
|
35
|
+
From the group detail page, check the views you want to grant access to and click **Save changes**. New policies default to "All fields" with no row filters.
|
|
51
36
|
|
|
52
|
-
|
|
53
|
-
cubes:
|
|
54
|
-
- name: raw_orders
|
|
55
|
-
public: false
|
|
37
|
+
## Field-Level Access (Level 2)
|
|
56
38
|
|
|
57
|
-
|
|
58
|
-
- name: sales_overview
|
|
59
|
-
public: true
|
|
60
|
-
cubes:
|
|
61
|
-
- join_path: raw_orders
|
|
62
|
-
includes:
|
|
63
|
-
- revenue
|
|
64
|
-
- order_count
|
|
65
|
-
- status
|
|
66
|
-
```
|
|
39
|
+
Fine-tune which measures and dimensions a group can see within a view. Click the gear icon on any granted view to open the fine-tune dialog.
|
|
67
40
|
|
|
68
|
-
|
|
41
|
+
Three modes:
|
|
42
|
+
- **All fields** — full access to every measure and dimension (default)
|
|
43
|
+
- **Only these** — whitelist specific fields; everything else is hidden
|
|
44
|
+
- **All except** — blacklist specific fields; everything else is visible
|
|
69
45
|
|
|
70
|
-
|
|
46
|
+
Hidden fields are removed from the schema — they don't appear in `explore_schema` and can't be used in queries.
|
|
71
47
|
|
|
72
|
-
|
|
48
|
+
## Row-Level Filters (Level 2)
|
|
73
49
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
50
|
+
Restrict which rows a group can see. Add row filters in the fine-tune dialog to limit data by dimension values.
|
|
51
|
+
|
|
52
|
+
For example, filter `traffic_source` to `equals B2B, Organic` so the group only sees rows where traffic_source is B2B or Organic. Multiple values in a single filter are OR'd (any match). Multiple separate filters are AND'd (all must match).
|
|
53
|
+
|
|
54
|
+
Row filters are applied server-side on every query — users cannot bypass them.
|
|
55
|
+
|
|
56
|
+
## Members
|
|
57
|
+
|
|
58
|
+
Assign users to groups from the **Members** tab. Each user shows which groups they belong to and a preview of their effective access (which views they can query, any field or row restrictions).
|
|
59
|
+
|
|
60
|
+
Users without any group assignment see nothing — they must be added to at least one group to query governed views.
|
|
61
|
+
|
|
62
|
+
## How Policies Are Enforced
|
|
63
|
+
|
|
64
|
+
Policies configured in the web UI are stored in Supabase and injected into the query engine at runtime. When a user queries via MCP or the API:
|
|
65
|
+
|
|
66
|
+
1. Their JWT is enriched with group memberships
|
|
67
|
+
2. The query engine loads policies for those groups
|
|
68
|
+
3. View visibility, field restrictions, and row filters are applied automatically
|
|
69
|
+
4. The user only sees data their policies allow
|
|
70
|
+
|
|
71
|
+
No YAML changes are needed — governance is fully managed through the dashboard.
|
|
72
|
+
|
|
73
|
+
## Best Practices
|
|
74
|
+
|
|
75
|
+
1. **Start with broad access, then restrict** — give groups all views first, then fine-tune as needed
|
|
76
|
+
2. **Use groups for teams, not individuals** — easier to manage and audit
|
|
77
|
+
3. **Test with MCP** — after changing policies, query via MCP to verify the restrictions work as expected
|
|
78
|
+
4. **Review after schema deploys** — new views need to be added to group policies to become visible
|
|
79
79
|
|
|
80
80
|
## See Also
|
|
81
81
|
|
|
82
|
-
- [
|
|
82
|
+
- [features.mcp](features.mcp) — How AI agents query your semantic layer
|
|
83
83
|
- [views](views) — Creating curated data views
|
|
84
|
-
- [syntax.context-variables](syntax.context-variables) — Context variable reference
|
|
@@ -9,6 +9,7 @@ Bonnard hosts your semantic layer so you don't have to. Define cubes and views i
|
|
|
9
9
|
Connect any combination of warehouses through a single semantic layer:
|
|
10
10
|
|
|
11
11
|
- **PostgreSQL** — Direct TCP connection
|
|
12
|
+
- **Redshift** — Cluster or serverless endpoint
|
|
12
13
|
- **Snowflake** — Account-based authentication
|
|
13
14
|
- **BigQuery** — GCP service account
|
|
14
15
|
- **Databricks** — Token-based workspace connection
|
|
@@ -43,8 +44,13 @@ Your models are stored securely and served from Bonnard's infrastructure. Each o
|
|
|
43
44
|
|
|
44
45
|
Deploy in seconds. Query in milliseconds.
|
|
45
46
|
|
|
47
|
+
## Built for AI agents
|
|
48
|
+
|
|
49
|
+
Views and descriptions are the discovery API for AI agents. When an agent calls `explore_schema`, it sees view names and descriptions — that's all it has to decide where to query. Well-written descriptions with scope, disambiguation, and dimension values make agents accurate. See the design guide principles in the CLI (`/bonnard-design-guide`) for details.
|
|
50
|
+
|
|
46
51
|
## See Also
|
|
47
52
|
|
|
48
53
|
- [workflow.query](workflow.query) — Query format reference
|
|
49
54
|
- [cubes](cubes) — Cube modeling guide
|
|
50
55
|
- [views](views) — View modeling guide
|
|
56
|
+
- [features.governance](features.governance) — Access control for views and data
|
|
@@ -12,5 +12,5 @@ Bonnard is a semantic layer platform that sits between your data warehouse and y
|
|
|
12
12
|
|
|
13
13
|
- Learn about [cubes](/docs/modeling/cubes) — measures, dimensions, joins
|
|
14
14
|
- Learn about [views](/docs/modeling/views) — curated interfaces for consumers
|
|
15
|
-
- Set up [MCP](/docs/
|
|
16
|
-
- Read the
|
|
15
|
+
- Set up [MCP](/docs/querying/mcp) — connect AI agents to your semantic layer
|
|
16
|
+
- Read the [CLI guide](/docs/cli) — validate, deploy, query
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Governance
|
|
2
|
+
|
|
3
|
+
> Control who can see which views, columns, and rows in your semantic layer.
|
|
4
|
+
|
|
5
|
+
Bonnard provides admin-managed data governance — control which views, columns, and rows each group of users can access. Policies are configured in the web UI and enforced automatically across MCP queries and the API. Changes take effect within one minute.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Admin configures in web UI:
|
|
11
|
+
Groups → Views → Field/Row restrictions
|
|
12
|
+
|
|
13
|
+
Enforced automatically:
|
|
14
|
+
MCP queries + API → only see what policies allow
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Governance uses **groups** as the unit of access. Each group has a set of **policies** that define which views its members can see, and optionally restrict specific columns or rows within those views.
|
|
18
|
+
|
|
19
|
+
## Groups
|
|
20
|
+
|
|
21
|
+
Groups represent teams or roles in your organization — "Sales Team", "Finance", "Executive". Create and manage groups from the **Governance** page in the Bonnard dashboard.
|
|
22
|
+
|
|
23
|
+
Each group has:
|
|
24
|
+
- **Name** and optional description
|
|
25
|
+
- **Color** for visual identification
|
|
26
|
+
- **View access** — which views the group can query
|
|
27
|
+
- **Members** — which users belong to the group
|
|
28
|
+
|
|
29
|
+
Users can belong to multiple groups. Their effective access is the **union** of all group policies.
|
|
30
|
+
|
|
31
|
+
## View-Level Access (Level 1)
|
|
32
|
+
|
|
33
|
+
The simplest control: toggle which views a group can see. Unchecked views are completely invisible to group members — they won't appear in `explore_schema` or be queryable.
|
|
34
|
+
|
|
35
|
+
From the group detail page, check the views you want to grant access to and click **Save changes**. New policies default to "All fields" with no row filters.
|
|
36
|
+
|
|
37
|
+
## Field-Level Access (Level 2)
|
|
38
|
+
|
|
39
|
+
Fine-tune which measures and dimensions a group can see within a view. Click the gear icon on any granted view to open the fine-tune dialog.
|
|
40
|
+
|
|
41
|
+
Three modes:
|
|
42
|
+
- **All fields** — full access to every measure and dimension (default)
|
|
43
|
+
- **Only these** — whitelist specific fields; everything else is hidden
|
|
44
|
+
- **All except** — blacklist specific fields; everything else is visible
|
|
45
|
+
|
|
46
|
+
Hidden fields are removed from the schema — they don't appear in `explore_schema` and can't be used in queries.
|
|
47
|
+
|
|
48
|
+
## Row-Level Filters (Level 2)
|
|
49
|
+
|
|
50
|
+
Restrict which rows a group can see. Add row filters in the fine-tune dialog to limit data by dimension values.
|
|
51
|
+
|
|
52
|
+
For example, filter `traffic_source` to `equals B2B, Organic` so the group only sees rows where traffic_source is B2B or Organic. Multiple values in a single filter are OR'd (any match). Multiple separate filters are AND'd (all must match).
|
|
53
|
+
|
|
54
|
+
Row filters are applied server-side on every query — users cannot bypass them.
|
|
55
|
+
|
|
56
|
+
## Members
|
|
57
|
+
|
|
58
|
+
Assign users to groups from the **Members** tab. Each user shows which groups they belong to and a preview of their effective access (which views they can query, any field or row restrictions).
|
|
59
|
+
|
|
60
|
+
Users without any group assignment see nothing — they must be added to at least one group to query governed views.
|
|
61
|
+
|
|
62
|
+
## How Policies Are Enforced
|
|
63
|
+
|
|
64
|
+
Policies configured in the web UI are stored in Supabase and injected into the query engine at runtime. When a user queries via MCP or the API:
|
|
65
|
+
|
|
66
|
+
1. Their JWT is enriched with group memberships
|
|
67
|
+
2. The query engine loads policies for those groups
|
|
68
|
+
3. View visibility, field restrictions, and row filters are applied automatically
|
|
69
|
+
4. The user only sees data their policies allow
|
|
70
|
+
|
|
71
|
+
No YAML changes are needed — governance is fully managed through the dashboard.
|
|
72
|
+
|
|
73
|
+
## Best Practices
|
|
74
|
+
|
|
75
|
+
1. **Start with broad access, then restrict** — give groups all views first, then fine-tune as needed
|
|
76
|
+
2. **Use groups for teams, not individuals** — easier to manage and audit
|
|
77
|
+
3. **Test with MCP** — after changing policies, query via MCP to verify the restrictions work as expected
|
|
78
|
+
4. **Review after schema deploys** — new views need to be added to group policies to become visible
|
|
79
|
+
|
|
80
|
+
## See Also
|
|
81
|
+
|
|
82
|
+
- [querying.mcp](querying.mcp) — How AI agents query your semantic layer
|
|
83
|
+
- [views](views) — Creating curated data views
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
> Define your metrics once. Query governed data from any AI tool, dashboard, or application.
|
|
4
|
+
|
|
5
|
+
Bonnard is a semantic layer platform. Your data team defines metrics once, and everyone else gets reliable answers from the AI tools they already use — Claude, ChatGPT, Cursor, Copilot — in whatever form they need. No new interface to learn.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Data Warehouse → Cubes (metrics) → Views (interfaces) → Query Surfaces
|
|
11
|
+
├── MCP (AI agents)
|
|
12
|
+
├── REST API
|
|
13
|
+
└── SDK (custom apps)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Cubes** map to your database tables and define measures (revenue, count) and dimensions (status, date). **Views** compose cubes into focused interfaces for specific teams or use cases. Once deployed, your semantic layer is queryable through MCP, REST API, or the TypeScript SDK.
|
|
17
|
+
|
|
18
|
+
## Multi-warehouse
|
|
19
|
+
|
|
20
|
+
Connect any combination of warehouses through a single semantic layer:
|
|
21
|
+
|
|
22
|
+
- **PostgreSQL** — Direct TCP connection
|
|
23
|
+
- **Redshift** — Cluster or serverless endpoint
|
|
24
|
+
- **Snowflake** — Account-based authentication
|
|
25
|
+
- **BigQuery** — GCP service account
|
|
26
|
+
- **Databricks** — Token-based workspace connection
|
|
27
|
+
|
|
28
|
+
Metrics from different warehouses are queried through the same API. Your consumers never need to know where the data lives.
|
|
29
|
+
|
|
30
|
+
## One source of truth for every AI
|
|
31
|
+
|
|
32
|
+
Bonnard exposes your semantic layer as a remote MCP server. Add one URL to any MCP-compatible client — Claude, ChatGPT, Cursor, VS Code, Windsurf, Gemini — and it can explore your data model, run queries, and render charts. Every query is governed and scoped to the user's permissions automatically.
|
|
33
|
+
|
|
34
|
+
## Governed by default
|
|
35
|
+
|
|
36
|
+
Metrics are version-controlled and deployed from the terminal. Access, roles, and row-level security are managed by admins from the dashboard. Every query — whether from an AI agent, the API, or the SDK — is scoped to the user's permissions. No ungoverned access.
|
|
37
|
+
|
|
38
|
+
## Your data stays where it is
|
|
39
|
+
|
|
40
|
+
Your data stays in your warehouse. Bonnard adds a governed semantic layer on top — hosted, queryable, and managed. Each organization gets isolated query execution. Deploy from your terminal in minutes, not quarters.
|
|
41
|
+
|
|
42
|
+
## Where to go next
|
|
43
|
+
|
|
44
|
+
- **[Getting Started](/docs/getting-started)** — Install the CLI and build your first semantic layer
|
|
45
|
+
- **[Modeling](/docs/modeling)** — Define cubes, views, and pre-aggregations
|
|
46
|
+
- **[Querying](/docs/querying)** — Query via MCP, REST API, or SDK
|
|
47
|
+
- **[CLI](/docs/cli)** — Commands, deployment, and validation
|
|
48
|
+
- **[Governance](/docs/governance)** — Control access to views, columns, and rows
|
|
49
|
+
- **[Catalog](/docs/catalog)** — Browse your data model in the browser
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# MCP
|
|
2
|
+
|
|
3
|
+
> Connect AI agents like Claude, ChatGPT, and Cursor to your semantic layer using the Model Context Protocol. One URL, governed access to your metrics and dimensions.
|
|
4
|
+
|
|
5
|
+
Bonnard exposes your semantic layer as a remote MCP server. Add one URL to your agent platform and it can explore your data model, run queries, and render charts — all through the Model Context Protocol.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## MCP URL
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
https://mcp.bonnard.dev/mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
On first use, your browser opens to sign in — the agent receives a 30-day token automatically. No API keys, no config files, no secrets to rotate.
|
|
16
|
+
|
|
17
|
+
## Connect your agent
|
|
18
|
+
|
|
19
|
+
Bonnard works with any MCP-compatible client:
|
|
20
|
+
|
|
21
|
+
- **Claude Desktop** — Add as a custom connector
|
|
22
|
+
- **ChatGPT** — Add via Settings > Apps (Pro/Plus)
|
|
23
|
+
- **Cursor** — Add via Settings > MCP or `.cursor/mcp.json`
|
|
24
|
+
- **Microsoft Copilot Studio** — Add as an MCP tool with OAuth 2.0 authentication
|
|
25
|
+
- **VS Code / GitHub Copilot** — Add via Command Palette or `.vscode/mcp.json`
|
|
26
|
+
- **Claude Code** — Add via `claude mcp add` or `.mcp.json`
|
|
27
|
+
- **Windsurf** — Add via MCP config
|
|
28
|
+
- **Gemini CLI** — Add via `.gemini/settings.json`
|
|
29
|
+
|
|
30
|
+
## Setup
|
|
31
|
+
|
|
32
|
+
### Claude Desktop
|
|
33
|
+
|
|
34
|
+
1. Click the **+** button in the chat input, then select **Connectors > Manage connectors**
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
2. Click **Add custom connector**
|
|
39
|
+
3. Enter a name (e.g. "Bonnard MCP") and the MCP URL: `https://mcp.bonnard.dev/mcp`
|
|
40
|
+
4. Click **Add**
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
Once added, enable the Bonnard connector in any chat via the **Connectors** menu.
|
|
45
|
+
|
|
46
|
+
Remote MCP servers in Claude Desktop must be added through the Connectors UI, not the JSON config file.
|
|
47
|
+
|
|
48
|
+
### ChatGPT
|
|
49
|
+
|
|
50
|
+
Custom MCP servers must be added in the browser at [chatgpt.com](https://chatgpt.com) — the desktop app does not support this.
|
|
51
|
+
|
|
52
|
+
1. Go to [chatgpt.com](https://chatgpt.com) in your browser
|
|
53
|
+
2. Open **Settings > Apps**
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
3. Click **Advanced settings**, enable **Developer mode**, then click **Create app**
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
4. Enter a name (e.g. "Bonnard MCP"), the MCP URL `https://mcp.bonnard.dev/mcp`, and select **OAuth** for authentication
|
|
62
|
+
5. Check the acknowledgement box and click **Create**
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
|
|
66
|
+
Once created, the Bonnard connector appears under **Enabled apps**:
|
|
67
|
+
|
|
68
|
+

|
|
69
|
+
|
|
70
|
+
Available on Pro and Plus plans.
|
|
71
|
+
|
|
72
|
+
### Cursor
|
|
73
|
+
|
|
74
|
+
Open **Settings > MCP** and add the server URL, or add to `.cursor/mcp.json` in your project:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"bonnard": {
|
|
80
|
+
"url": "https://mcp.bonnard.dev/mcp"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
On first use, your browser will open to sign in and authorize the connection.
|
|
87
|
+
|
|
88
|
+
### VS Code / GitHub Copilot
|
|
89
|
+
|
|
90
|
+
Open the Command Palette and run **MCP: Add Server**, or add to `.vscode/mcp.json` in your project:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"servers": {
|
|
95
|
+
"bonnard": {
|
|
96
|
+
"type": "http",
|
|
97
|
+
"url": "https://mcp.bonnard.dev/mcp"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
On first use, your browser will open to sign in and authorize the connection.
|
|
104
|
+
|
|
105
|
+
### Claude Code
|
|
106
|
+
|
|
107
|
+
Run in your terminal:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
claude mcp add --transport http bonnard https://mcp.bonnard.dev/mcp
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Or add to `.mcp.json` in your project:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"mcpServers": {
|
|
118
|
+
"bonnard": {
|
|
119
|
+
"type": "http",
|
|
120
|
+
"url": "https://mcp.bonnard.dev/mcp"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Windsurf
|
|
127
|
+
|
|
128
|
+
Open **Settings > Plugins > Manage plugins > View raw config**, or edit `~/.codeium/windsurf/mcp_config.json`:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"mcpServers": {
|
|
133
|
+
"bonnard": {
|
|
134
|
+
"serverUrl": "https://mcp.bonnard.dev/mcp"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Gemini CLI
|
|
141
|
+
|
|
142
|
+
Add to `.gemini/settings.json` in your project or `~/.gemini/settings.json` globally:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"bonnard": {
|
|
148
|
+
"url": "https://mcp.bonnard.dev/mcp"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Authentication
|
|
155
|
+
|
|
156
|
+
MCP uses OAuth 2.0 with PKCE. When an agent first connects:
|
|
157
|
+
|
|
158
|
+
1. Agent discovers OAuth endpoints automatically
|
|
159
|
+
2. You are redirected to Bonnard to sign in and authorize
|
|
160
|
+
3. Agent receives an access token (valid for 30 days)
|
|
161
|
+
|
|
162
|
+
No API keys or manual token management needed.
|
|
163
|
+
|
|
164
|
+
## Available Tools
|
|
165
|
+
|
|
166
|
+
Once connected, AI agents can use these MCP tools:
|
|
167
|
+
|
|
168
|
+
| Tool | Description |
|
|
169
|
+
|------|-------------|
|
|
170
|
+
| `explore_schema` | Discover views and cubes, list their measures, dimensions, and segments. Supports browsing a specific source by name or searching across all fields by keyword. |
|
|
171
|
+
| `query` | Query the semantic layer with measures, dimensions, time dimensions, filters, segments, and pagination. |
|
|
172
|
+
| `sql_query` | Execute raw SQL against the semantic layer using Cube SQL syntax with `MEASURE()` for aggregations. Use for CTEs, UNIONs, and custom calculations. |
|
|
173
|
+
| `describe_field` | Get detailed metadata for a field — SQL expression, type, format, origin cube, and referenced fields. |
|
|
174
|
+
| `visualize` | Render line, bar, pie, and KPI charts directly inside the conversation. |
|
|
175
|
+
|
|
176
|
+
## Charts in chat
|
|
177
|
+
|
|
178
|
+
The `visualize` tool renders interactive charts inline — auto-detected from your query shape. Charts support dark mode, currency and percentage formatting, and multi-series data.
|
|
179
|
+
|
|
180
|
+
Ask "show me revenue by region this quarter" and get a formatted chart in your conversation, not a data dump.
|
|
181
|
+
|
|
182
|
+
## Testing
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Verify the MCP server is reachable
|
|
186
|
+
bon mcp test
|
|
187
|
+
|
|
188
|
+
# View connection info
|
|
189
|
+
bon mcp
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Managing Connections
|
|
193
|
+
|
|
194
|
+
Active MCP connections can be viewed and revoked in the Bonnard dashboard under **MCP**.
|
|
195
|
+
|
|
196
|
+
## See Also
|
|
197
|
+
|
|
198
|
+
- [querying.rest-api](querying.rest-api) — Query format reference
|
|
199
|
+
- [querying.sdk](querying.sdk) — TypeScript SDK for custom apps
|
|
200
|
+
- [cli.deploy](cli.deploy) — Deploy before querying
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Querying
|
|
2
|
+
|
|
3
|
+
> Once deployed, query your semantic layer three ways: MCP for AI agents, REST API for structured queries, and SDK for custom applications.
|
|
4
|
+
|
|
5
|
+
Once your semantic layer is deployed, it's queryable through three interfaces:
|
|
6
|
+
|
|
7
|
+
- **[MCP](querying.mcp)** — Connect AI agents like Claude, ChatGPT, and Cursor to explore and query your data model through the Model Context Protocol
|
|
8
|
+
- **[REST API](querying.rest-api)** — Send JSON query objects or SQL strings for structured, programmatic access
|
|
9
|
+
- **[SDK](querying.sdk)** — Build custom dashboards, embedded analytics, and data pipelines with the TypeScript client
|
|
10
|
+
|
|
11
|
+
All three interfaces query the same governed semantic layer — same metrics, same access controls, same results.
|