Skip to content

Commit 1b45832

Browse files
authored
Merge pull request #59 from influxdata/fix/pr-56-sync-main-retention
feat: Add Enterprise/Core retention policy support to update_database (supersedes #56)
2 parents 265280a + 65b1aed commit 1b45832

20 files changed

Lines changed: 543 additions & 183 deletions

.claude/skills/build-run-core-enterprise/SKILL.md

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ Copy `env.example` as a starting point: `cp env.example .env`
4343

4444
### Token types (Core/Enterprise)
4545

46-
| Token Type | Purpose | How to obtain |
47-
|---|---|---|
48-
| Operator | Full admin, bootstraps the instance | Printed on first `influxdb3 serve` start |
49-
| Admin | Full admin except managing other admins | Created via `create_admin_token` tool |
50-
| Resource | Scoped read/write on specific databases | Created via `create_resource_token` tool |
46+
| Token Type | Purpose | How to obtain |
47+
| ---------- | --------------------------------------- | ---------------------------------------- |
48+
| Operator | Full admin, bootstraps the instance | Printed on first `influxdb3 serve` start |
49+
| Admin | Full admin except managing other admins | Created via `create_admin_token` tool |
50+
| Resource | Scoped read/write on specific databases | Created via `create_resource_token` tool |
5151

5252
Use the operator token during initial setup. Create scoped resource tokens for
5353
applications.
@@ -105,6 +105,7 @@ npm run "MCP inspector" # quotes required (space in script name)
105105
```
106106

107107
This launches the inspector connected to the built server. Use it to:
108+
108109
- Call `health_check` to verify connectivity
109110
- Call `list_databases` to confirm data access
110111
- Test `execute_query` with a simple SQL query
@@ -113,27 +114,29 @@ This launches the inspector connected to the built server. Use it to:
113114

114115
All tools available for Core/Enterprise instances:
115116

116-
| Tool | Description |
117-
|---|---|
118-
| `health_check` | Verify connection and health status |
119-
| `list_databases` | List all databases |
120-
| `create_database` | Create a new database |
121-
| `delete_database` | Delete a database |
122-
| `execute_query` | Run SQL queries |
123-
| `get_measurements` | List tables in a database |
124-
| `get_measurement_schema` | Show columns/types for a table |
125-
| `write_line_protocol` | Write data via line protocol |
126-
| `create_admin_token` | Create named admin token |
127-
| `list_admin_tokens` | List admin tokens |
128-
| `create_resource_token` | Create scoped resource token |
129-
| `list_resource_tokens` | List resource tokens |
130-
| `delete_token` | Delete a token by name |
131-
| `regenerate_operator_token` | Regenerate operator token (destructive) |
132-
| `get_help` | Built-in help and troubleshooting |
133-
| `load_database_context` | Load custom context from `context/` |
134-
135-
Tools like `update_database` and `cloud_*` token tools are **not** available
136-
for Core/Enterprise.
117+
| Tool | Description |
118+
| --------------------------- | ----------------------------------------------- |
119+
| `health_check` | Verify connection and health status |
120+
| `list_databases` | List all databases |
121+
| `create_database` | Create a new database |
122+
| `update_database` | Update retention period (Core requires v3.2.0+) |
123+
| `delete_database` | Delete a database |
124+
| `execute_query` | Run SQL queries |
125+
| `get_measurements` | List tables in a database |
126+
| `get_measurement_schema` | Show columns/types for a table |
127+
| `write_line_protocol` | Write data via line protocol |
128+
| `create_admin_token` | Create named admin token |
129+
| `list_admin_tokens` | List admin tokens |
130+
| `create_resource_token` | Create scoped resource token |
131+
| `list_resource_tokens` | List resource tokens |
132+
| `delete_token` | Delete a token by name |
133+
| `regenerate_operator_token` | Regenerate operator token (destructive) |
134+
| `get_help` | Built-in help and troubleshooting |
135+
| `load_database_context` | Load custom context from `context/` |
136+
137+
For Core/Enterprise, `update_database` supports the retention period only
138+
(updating retention on Core requires v3.2.0+). The `cloud_*` token tools are
139+
**not** available for Core/Enterprise.
137140

138141
## Troubleshooting
139142

@@ -145,6 +148,7 @@ and `INFLUX_DB_PRODUCT_TYPE` is exactly `core` or `enterprise`.
145148
### Health check fails but server starts
146149

147150
The server can start without a reachable InfluxDB instance. Check:
151+
148152
1. InfluxDB is running: `curl http://localhost:8181/ping`
149153
2. Token is valid (operator or admin token for full access)
150154
3. URL has trailing slash if using the default config

.claude/skills/build-run-core-enterprise/references/mcp-client-configs.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,16 @@ Use `host.docker.internal` to reach InfluxDB running on the Docker host:
5959
"influxdb": {
6060
"command": "docker",
6161
"args": [
62-
"run", "--rm", "-i",
62+
"run",
63+
"--rm",
64+
"-i",
6365
"--add-host=host.docker.internal:host-gateway",
64-
"-e", "INFLUX_DB_INSTANCE_URL",
65-
"-e", "INFLUX_DB_TOKEN",
66-
"-e", "INFLUX_DB_PRODUCT_TYPE",
66+
"-e",
67+
"INFLUX_DB_INSTANCE_URL",
68+
"-e",
69+
"INFLUX_DB_TOKEN",
70+
"-e",
71+
"INFLUX_DB_PRODUCT_TYPE",
6772
"influxdb-mcp-server"
6873
],
6974
"env": {
@@ -87,10 +92,15 @@ When InfluxDB is on a separate host, use the remote URL directly (no
8792
"influxdb": {
8893
"command": "docker",
8994
"args": [
90-
"run", "--rm", "-i",
91-
"-e", "INFLUX_DB_INSTANCE_URL",
92-
"-e", "INFLUX_DB_TOKEN",
93-
"-e", "INFLUX_DB_PRODUCT_TYPE",
95+
"run",
96+
"--rm",
97+
"-i",
98+
"-e",
99+
"INFLUX_DB_INSTANCE_URL",
100+
"-e",
101+
"INFLUX_DB_TOKEN",
102+
"-e",
103+
"INFLUX_DB_PRODUCT_TYPE",
94104
"influxdb-mcp-server"
95105
],
96106
"env": {

.claude/skills/testing/SKILL.md

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,18 @@ Reruns on file changes. Useful during development.
8787

8888
## What the Tests Cover
8989

90-
| Test | What it verifies |
91-
|---|---|
92-
| Initialize handshake | Server starts, SDK handshake succeeds, capabilities reported |
93-
| Server version | Name is `"influxdb-mcp-server"`, version is defined |
94-
| Tool count | `tools/list` returns exactly `EXPECTED_TOOL_COUNT` tools |
95-
| Tool structure | Each tool has `name`, `description`, `inputSchema` with `type: "object"` |
96-
| Core tool names | Spot-checks `health_check`, `execute_query`, `write_line_protocol`, `list_databases`, `create_admin_token` |
97-
| Resource URIs | 4 resources with correct `influx://` URIs |
98-
| Resource structure | Each resource has `name`, `uri`, `description` |
99-
| Prompt names | 3 prompts: `list-databases`, `check-health`, `load-context` |
100-
| Ping | Server responds to ping |
101-
| Unknown tool error | Calling nonexistent tool throws `McpError` |
90+
| Test | What it verifies |
91+
| -------------------- | ---------------------------------------------------------------------------------------------------------- |
92+
| Initialize handshake | Server starts, SDK handshake succeeds, capabilities reported |
93+
| Server version | Name is `"influxdb-mcp-server"`, version is defined |
94+
| Tool count | `tools/list` returns exactly `EXPECTED_TOOL_COUNT` tools |
95+
| Tool structure | Each tool has `name`, `description`, `inputSchema` with `type: "object"` |
96+
| Core tool names | Spot-checks `health_check`, `execute_query`, `write_line_protocol`, `list_databases`, `create_admin_token` |
97+
| Resource URIs | 4 resources with correct `influx://` URIs |
98+
| Resource structure | Each resource has `name`, `uri`, `description` |
99+
| Prompt names | 3 prompts: `list-databases`, `check-health`, `load-context` |
100+
| Ping | Server responds to ping |
101+
| Unknown tool error | Calling nonexistent tool throws `McpError` |
102102

103103
## Analyzing Failures
104104

@@ -112,6 +112,7 @@ The most common failure after code changes. The constant in
112112
below for documentation.
113113

114114
To find the current count, start the server briefly and check stderr:
115+
115116
```bash
116117
npm run build && INFLUX_DB_INSTANCE_URL=http://localhost:19999/ \
117118
INFLUX_DB_TOKEN=fake INFLUX_DB_PRODUCT_TYPE=core \
@@ -122,6 +123,7 @@ sleep 1 && kill $!
122123
Look for: `[MCP] Server initialized with N tools, N resources, N prompts`
123124

124125
The tool count breakdown by category file:
126+
125127
- `help.tools.ts` (2) + `write.tools.ts` (1) + `database.tools.ts` (4)
126128
- `query.tools.ts` (3) + `token.tools.ts` (6) + `cloud-token.tools.ts` (5)
127129
- `health.tools.ts` (1) = **22 total**
@@ -136,13 +138,15 @@ message if the build artifact is missing.
136138
### Initialize handshake timeout
137139

138140
The server process failed to start. Common causes:
141+
139142
- Build is stale after source changes — rebuild with `npm run build`
140143
- Missing or invalid env vars — protocol tests use a fake config internally,
141144
so this usually means `createTestClient` was called with bad overrides
142145

143146
### Integration test: "HEALTHY" not found
144147

145148
InfluxDB instance is unreachable or unhealthy. Verify:
149+
146150
1. Instance is running: `curl http://localhost:8181/ping`
147151
2. Token is valid
148152
3. `INFLUX_DB_PRODUCT_TYPE` matches the actual instance type
@@ -181,6 +185,59 @@ The `createTestClient(env?)` factory in `tests/helpers/mcp-client.ts` spawns
181185
a real server process and returns a connected MCP `Client`. Override env vars
182186
by passing a partial record. Always call `close()` in `afterAll`.
183187

188+
## Reviewing data-plane and admin changes
189+
190+
When a change adds or modifies a tool that talks to an InfluxDB endpoint
191+
(writes, queries, database/token management), verify the actual API contract
192+
and exercise it against a real instance. Tool descriptions, CHANGELOG entries,
193+
and code comments are not authoritative on their own — confirm them.
194+
195+
### Verify the API contract first
196+
197+
Confirm the HTTP method, path, and request/response shape against both the
198+
InfluxData docs knowledge source and the `influxdata/influxdb` source
199+
(`influxdb3_server/src/http.rs` routing, `influxdb3_types/src/http.rs` structs).
200+
201+
Gotchas that have already bitten this repo:
202+
203+
- Core/Enterprise `update_database` retention is `PUT /api/v3/configure/database`
204+
with `retention_period` as a duration string (`"60d"`) — not `PATCH`, not
205+
`retention_period_ns`.
206+
- Core can update retention since v3.2.0 (static docs wrongly say it's immutable).
207+
- `/ping` and `/health` use `Token` auth even for core/enterprise (v1/v2 compat);
208+
the admin client uses `Bearer`. Both are intentional.
209+
210+
### Exercise it against a real instance
211+
212+
Admin endpoints (`/api/v3/configure/*`) need an admin token; `health_check`
213+
does not, so a passing `health_check` does not prove the token works. Run a
214+
self-contained Core for an admin-path test on a free port:
215+
216+
```bash
217+
docker run -d --name mcp-it-core -p 8383:8181 \
218+
-v "$PWD/tests/fixtures/admin-token.json":/admin-token.json:ro \
219+
influxdb:3-core influxdb3 serve \
220+
--node-id local-test --object-store memory \
221+
--admin-token-file /admin-token.json
222+
223+
INFLUX_TEST_ENABLED=true INFLUX_DB_INSTANCE_URL=http://localhost:8383/ \
224+
INFLUX_DB_TOKEN=apiv3_test INFLUX_DB_PRODUCT_TYPE=core \
225+
npx vitest run tests/integration.test.ts
226+
227+
docker rm -f mcp-it-core
228+
```
229+
230+
This uses the offline preconfigured admin token in `tests/fixtures/admin-token.json`
231+
(token `apiv3_test`) — the `docker-compose.test.yml` pattern, but on a port you
232+
choose so it does not collide with other local instances.
233+
234+
### Token gotcha
235+
236+
v3 tokens are base64 and can contain `+`, `/`, and `=`. Do not extract one with
237+
`grep -oE 'apiv3_[A-Za-z0-9_-]+'` — it truncates at the first base64 character
238+
and yields an invalid token (the server returns `401 "the request was not
239+
authenticated"`).
240+
184241
## Additional Resources
185242

186243
### Reference Files

.claude/skills/testing/references/test-architecture.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The trick: `createTestClient()` passes a fake config:
2525

2626
```typescript
2727
const BASE_ENV = {
28-
INFLUX_DB_INSTANCE_URL: "http://localhost:19999/", // nothing listens here
28+
INFLUX_DB_INSTANCE_URL: "http://localhost:19999/", // nothing listens here
2929
INFLUX_DB_TOKEN: "test-token-not-used",
3030
INFLUX_DB_PRODUCT_TYPE: "core",
3131
};
@@ -106,7 +106,7 @@ exist, and skips gracefully if not (rather than failing on an empty instance).
106106
```
107107

108108
- **15s timeouts**: Generous for slow CI machines where child process spawn
109-
+ initialize handshake can take 2-3 seconds
109+
- initialize handshake can take 2-3 seconds
110110
- **No pool override**: Default vitest forks handle child process spawning
111111
- **No `rootDir` change to tsconfig**: vitest uses Vite's esbuild pipeline
112112
to compile test files independently from `tsc`. The production tsconfig
@@ -127,6 +127,7 @@ For integration tests that need InfluxDB, use the same
127127
## Local Docker Infrastructure
128128

129129
`docker-compose.test.yml` starts InfluxDB 3 Core with:
130+
130131
- `--object-store memory` — ephemeral, no volumes
131132
- Docker secrets to inject `tests/fixtures/admin-token.json` as
132133
`--admin-token-file=/run/secrets/admin-token`
@@ -151,6 +152,7 @@ Uses `docker run` (not `services:`) because Core requires
151152
cannot pass container CMD arguments.
152153

153154
The job:
155+
154156
1. Checks out the repo (which includes `tests/fixtures/admin-token.json`)
155157
2. Bind-mounts the token file into the container at `/run/secrets/admin-token`
156158
3. Polls `/ping` until Core is ready (up to 30 seconds)

.github/workflows/ci.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
name: Version consistency check
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1616
with:
1717
persist-credentials: false
1818

@@ -40,11 +40,11 @@ jobs:
4040
name: Protocol tests
4141
runs-on: ubuntu-latest
4242
steps:
43-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
43+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4444
with:
4545
persist-credentials: false
4646

47-
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
47+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
4848
with:
4949
node-version: "22"
5050
cache: "npm"
@@ -57,11 +57,11 @@ jobs:
5757
name: Integration tests (InfluxDB 3 Core)
5858
runs-on: ubuntu-latest
5959
steps:
60-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
60+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
6161
with:
6262
persist-credentials: false
6363

64-
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
64+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
6565
with:
6666
node-version: "22"
6767
cache: "npm"
@@ -113,11 +113,11 @@ jobs:
113113
github.event.pull_request.head.repo.full_name == github.repository)
114114
environment: cloud-serverless
115115
steps:
116-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
116+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
117117
with:
118118
persist-credentials: false
119119

120-
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
120+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
121121
with:
122122
node-version: "22"
123123
cache: "npm"

.prettierrc.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": false,
7+
"trailingComma": "all"
8+
}

0 commit comments

Comments
 (0)