Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dtwo/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dtwo",
"version": "1.3.0",
"version": "1.3.1",
"description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.",
"author": {
"name": "Dtwo",
Expand Down
2 changes: 1 addition & 1 deletion dtwo/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dtwo",
"version": "1.3.0",
"version": "1.3.1",
"description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.",
"author": {
"name": "Dtwo",
Expand Down
2 changes: 1 addition & 1 deletion dtwo/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dtwo",
"version": "1.3.0",
"version": "1.3.1",
"description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.",
"author": {
"name": "Dtwo",
Expand Down
14 changes: 7 additions & 7 deletions dtwo/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ Setup-specific tools (may be newer — see Graceful degradation if any are missi
| `dtwo-set-gateway-auth` | Deterministically write the `gateway.authentication` block into the draft config. Input `{ uid, mode, customFields? }` where `mode` is `dtwo_default` \| `custom` \| `disabled` \| `removed`. `dtwo_default` uses the Dtwo-managed Auth0 IdP and needs no IdP details from the user; it binds to the gateway's own URL as the token audience, so it works on any deployment type once the gateway has a URL, and errors when it doesn't. `custom` takes the audience from `customFields` and so needs no gateway URL. On `localHttp` and `hostedAws`, which are created on the Dtwo-managed IdP already, this tool is for moving off that default rather than first-time setup. `customFields` carries `jwt_algorithm`, `jwt_jwks_uri`, `jwt_issuer`, `jwt_audience`, `sso_issuer` when `mode: custom` |
| `dtwo-update-gateway` | Update gateway metadata. Input `{ uid, name?, tags?, url?, callbackUrl? }`. This is how a `standard` gateway gets the MCP URL it was created without. The URL is the audience the Dtwo-managed IdP binds to, so it has to be set before `dtwo-set-gateway-auth` with `mode: dtwo_default`; `mode: custom` carries its own audience and doesn't need it. Either way it can be left for a later session if the user doesn't have the address yet. `url` and `callbackUrl` are `standard`-only, since `localHttp` and `hostedAws` URLs are platform-assigned and a change to those is refused |
| `dtwo-get-gateway-connection-info` | Fetch client connection details, on any deployment type. Input `{ uid }` → `{ mcpUrl, authMode, clientId?, audience?, issuer?, jwksUri?, domain?, callbackPort? }`. `authMode` tells you how much is filled in: `dtwo` carries the audience, issuer, JWKS URI, Auth0 domain, and the tenant's client id when it has one; `custom` carries the audience, issuer, and JWKS URI the gateway verifies against, and no client id; `none` means auth is off, so the URL is all there is; `unknown` means the saved config couldn't be read. `callbackPort` (33418) comes back for `localHttp` only. Errors when the gateway has no URL yet, which for `standard` means the `dtwo-update-gateway` step hasn't happened |
| `dtwo-get-gateway-activation` | Fetch the **first-run** activation bundle for a **self-hosted** gateway. Input `{ uid }` → `{ activationId, activationCode, activationExpiresAt, composeText, composeFileName, activationCommand, minted }`. The activation code is never stored, so in practice every call mints a fresh pair and returns `minted: true`, invalidating any previously issued one; the pair is single-use and lasts 24 hours. Call it once per activation attempt. Use `activationId` and `activationCode` to write the `dtwo.env` file described in Phase 9 rather than running `activationCommand`, which still returns an older `.env`-writing form. `composeText` carries the `443:443`→`80:80` port swap for `localHttp`. Errors for `hostedAws` (nothing to activate, since provisioning is managed) |
| `dtwo-refresh-gateway-activation` | Mint a fresh activation pair for a `localHttp` or `standard` gateway that is already up, invalidating any previously issued one. Input `{ uid }` → the same fields as `dtwo-get-gateway-activation`. Again, take `activationId` and `activationCode` and rewrite `dtwo.env`; its `activationCommand` is an older `docker compose down` / `.env` form. Re-register with `docker compose --env-file dtwo.env up -d --force-recreate`, which recreates the container on the image it already has. For a host that has never come up, use `dtwo-get-gateway-activation` instead, since its flow pulls the image. Errors for `hostedAws`: refreshing would invalidate the credential the provisioning instance is using |
| `dtwo-create-gateway-activation` | Create (mint) the **first-run** activation bundle for a **self-hosted** gateway. Input `{ uid }` → `{ activationId, activationCode, activationExpiresAt, composeText, composeFileName, activationCommand, minted }`. Every call mints a fresh pair and returns `minted: true`, invalidating any previously issued one; the pair is single-use and lasts 24 hours. Call it once per activation attempt. Use `activationId` and `activationCode` to write the `dtwo.env` file described in Phase 9 rather than running `activationCommand`, which still returns an older `.env`-writing form. `composeText` carries the `443:443`→`80:80` port swap for `localHttp`. Errors for `hostedAws` (nothing to activate, since provisioning is managed) |
| `dtwo-refresh-gateway-activation` | Mint a fresh activation pair for a `localHttp` or `standard` gateway that is already up, invalidating any previously issued one. Input `{ uid }` → the same fields as `dtwo-create-gateway-activation`. Again, take `activationId` and `activationCode` and rewrite `dtwo.env`; its `activationCommand` is an older `docker compose down` / `.env` form. Re-register with `docker compose --env-file dtwo.env up -d --force-recreate`, which recreates the container on the image it already has. For a host that has never come up, use `dtwo-create-gateway-activation` instead, since its flow pulls the image. Errors for `hostedAws`: refreshing would invalidate the credential the provisioning instance is using |
| `dtwo-record-setup-progress` | Record the closing setup steps on the account, so the Dtwo Hub shows setup as finished instead of asking the user to confirm work you already did with them. Input `{ steps }`, any of `connectClient` \| `testPolicies` \| `plugin`. Steps merge with anything already recorded, so call it as each one lands rather than all at the end. Only these three are accepted; everything earlier (gateway, MCP servers, policies, deploy) the platform reads from the account itself |
| `dtwo-get-setup-progress` | Read back which closing steps are already recorded. Input `{}` → `{ completedSetupSteps, completedAssertedSteps }`. Useful when resuming an interrupted setup |

Expand Down Expand Up @@ -328,7 +328,7 @@ Confirm with the user, then call `dtwo-publish-gateway-config` to publish the dr

**Skip this phase entirely for `hostedAws`** — there is nothing to activate; provisioning was queued at creation. Instead, check `dtwo-get-gateway` (and `dtwo-get-gateway-deployments` if useful) to confirm provisioning has progressed before deploying in Phase 10.

For **localHttp / standard**, call `dtwo-get-gateway-activation` `{ uid }` to get `{ activationId, activationCode, activationExpiresAt, composeText, composeFileName, activationCommand, minted }`.
For **localHttp / standard**, call `dtwo-create-gateway-activation` `{ uid }` to mint an activation and get `{ activationId, activationCode, activationExpiresAt, composeText, composeFileName, activationCommand, minted }`.

Activation is two files in one folder on the host, plus two commands run from that folder:

Expand Down Expand Up @@ -358,11 +358,11 @@ The credentials are **single-use and valid for 24 hours** from when they were mi

Print the real values in that second case. The pair is a credential, so don't scatter it around unasked, but a user who has said they'll run the commands themselves needs the actual id and code, and a placeholder or an offer to write the file for them instead is just an obstacle. Someone who came to a skill for guidance may well not want it creating files on their machine, and that's a reasonable thing to want.

**Expired or missing credentials are handled for you.** The activation code is never stored, so `dtwo-get-gateway-activation` mints a fresh pair on essentially every call and reports `minted: true`. There is nothing to do about expiry up front, and no reason to check it before starting.
**Expired or missing credentials are handled for you.** The activation code is never stored, so `dtwo-create-gateway-activation` mints a fresh pair on every call and reports `minted: true`. There is nothing to do about expiry up front, and no reason to check it before starting.

If a first attempt needs another go, which tool to call depends on whether the host is up:

- **The host has never come up** (the normal case here, including a first attempt whose code expired before the user ran it): call `dtwo-get-gateway-activation` again, then hand over or write the new pair the same way as the first attempt, and run the same two commands. The `pull` matters, since the image may still not be on the host.
- **The host has never come up** (the normal case here, including a first attempt whose code expired before the user ran it): call `dtwo-create-gateway-activation` again, then hand over or write the new pair the same way as the first attempt, and run the same two commands. The `pull` matters, since the image may still not be on the host.
- **The host is already up** and reported an invalid or expired code at run time: call `dtwo-refresh-gateway-activation` `{ uid }`, hand over or write the new pair into `dtwo.env` as before, and re-register with one command instead:

```bash
Expand All @@ -371,7 +371,7 @@ If a first attempt needs another go, which tool to call depends on whether the h

`--force-recreate` is what makes Compose rebuild the container so it picks up the new pair, and leaving `pull` out keeps the host on the image it is already running.

**Fetch the activation once per attempt.** Do not call `dtwo-get-gateway-activation` again after the container has started with the pair you were given: a re-fetch mints a new one and invalidates the one the host just used. Re-fetching is only right when the attempt didn't finish, as in the first case above. Fetch once, activate, then move on to Phase 10.
**Create the activation once per attempt.** Do not call `dtwo-create-gateway-activation` again after the container has started with the pair you were given: another call mints a new one and invalidates the one the host just used. Calling it again is only right when the attempt didn't finish, as in the first case above. Create once, activate, then move on to Phase 10.

**Then wait for the gateway to check in.** Starting the container isn't the same as the platform knowing about it. Check `dtwo-get-gateway` `{ uid }`: while `status` is `provisioning` or `provisioned` the gateway hasn't checked in yet and has nothing for a deploy to land on. Once it reaches `registered` or `running`, Phase 10 can go ahead. If it sits in `provisioned` for more than a minute or two, the container is up but can't reach Dtwo, so check the container logs rather than deploying into it.

Expand Down Expand Up @@ -527,7 +527,7 @@ Tell the user what you found ("Looks like your gateway exists with two MCP serve

The progress-recording tools (`dtwo-record-setup-progress`, `dtwo-get-setup-progress`) are the one exception to everything below: they only keep the Dtwo Hub's view of setup in step with what you did, so if either is missing or a call fails, carry on and finish setup as normal. Don't retry, don't mention it, and don't let it become the last thing the user hears. The only cost is that the Hub still lists the closing steps as unconfirmed, and the user can tick them off there.

If any other setup-specific tool this skill relies on (`dtwo-create-gateway`, `dtwo-update-gateway`, `dtwo-set-gateway-auth`, `dtwo-get-gateway-connection-info`, `dtwo-get-gateway-activation`, `dtwo-refresh-gateway-activation`) is **not present** in your available tool list, the connected Dtwo environment doesn't support plugin-driven setup yet. Don't try to reconstruct these steps by hand. Instead, tell the user plainly and point them to the Hub's own guided setup, which walks through the same journey in the web app: open the account menu at the bottom of the left sidebar and choose **Setup guide**. The other companion skills still work for managing a gateway once it exists.
If any other setup-specific tool this skill relies on (`dtwo-create-gateway`, `dtwo-update-gateway`, `dtwo-set-gateway-auth`, `dtwo-get-gateway-connection-info`, `dtwo-create-gateway-activation`, `dtwo-refresh-gateway-activation`) is **not present** in your available tool list, the connected Dtwo environment doesn't support plugin-driven setup yet. Don't try to reconstruct these steps by hand. Instead, tell the user plainly and point them to the Hub's own guided setup, which walks through the same journey in the web app: open the account menu at the bottom of the left sidebar and choose **Setup guide**. The other companion skills still work for managing a gateway once it exists.

## Limitations

Expand Down
Loading