@decibelsystems/tools 2.0.1 → 2.1.0
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 +115 -233
- package/dist/client/facade-client.d.ts +9 -3
- package/dist/client/facade-client.d.ts.map +1 -1
- package/dist/client/facade-client.js +58 -29
- package/dist/client/facade-client.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/transports.d.ts +3 -0
- package/dist/client/transports.d.ts.map +1 -1
- package/dist/client/transports.js +12 -0
- package/dist/client/transports.js.map +1 -1
- package/dist/client/types.d.ts +18 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/daemon.d.ts +29 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +64 -0
- package/dist/daemon.js.map +1 -1
- package/dist/daemonConfig.d.ts +7 -0
- package/dist/daemonConfig.d.ts.map +1 -1
- package/dist/daemonConfig.js +9 -0
- package/dist/daemonConfig.js.map +1 -1
- package/dist/facades/definitions.d.ts.map +1 -1
- package/dist/facades/definitions.js +116 -35
- package/dist/facades/definitions.js.map +1 -1
- package/dist/facades/types.d.ts +2 -0
- package/dist/facades/types.d.ts.map +1 -1
- package/dist/httpServer.d.ts +4 -0
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +183 -13
- package/dist/httpServer.js.map +1 -1
- package/dist/kernel.d.ts +9 -0
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +12 -7
- package/dist/kernel.js.map +1 -1
- package/dist/server.js +30 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/coordinator/coordinator.d.ts +14 -0
- package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
- package/dist/tools/coordinator/coordinator.js +101 -0
- package/dist/tools/coordinator/coordinator.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts +2 -0
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +2 -0
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/deck.d.ts +4 -4
- package/dist/tools/deck.d.ts.map +1 -1
- package/dist/tools/deck.js +1546 -78
- package/dist/tools/deck.js.map +1 -1
- package/dist/tools/designer/index.js +1 -1
- package/dist/tools/designer/index.js.map +1 -1
- package/dist/tools/guardian/index.d.ts +1 -0
- package/dist/tools/guardian/index.d.ts.map +1 -1
- package/dist/tools/guardian/index.js +40 -1
- package/dist/tools/guardian/index.js.map +1 -1
- package/dist/tools/guardian.d.ts +30 -0
- package/dist/tools/guardian.d.ts.map +1 -1
- package/dist/tools/guardian.js +96 -0
- package/dist/tools/guardian.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mother.d.ts +11 -0
- package/dist/tools/mother.d.ts.map +1 -0
- package/dist/tools/mother.js +503 -0
- package/dist/tools/mother.js.map +1 -0
- package/dist/tools/swarm.d.ts +11 -0
- package/dist/tools/swarm.d.ts.map +1 -0
- package/dist/tools/swarm.js +701 -0
- package/dist/tools/swarm.js.map +1 -0
- package/dist/tools/terminal.d.ts +17 -0
- package/dist/tools/terminal.d.ts.map +1 -0
- package/dist/tools/terminal.js +968 -0
- package/dist/tools/terminal.js.map +1 -0
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +2 -0
- package/dist/transports/http.js.map +1 -1
- package/dist/transports/mcp.d.ts.map +1 -1
- package/dist/transports/mcp.js +3 -0
- package/dist/transports/mcp.js.map +1 -1
- package/dist/transports/types.d.ts +4 -0
- package/dist/transports/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @decibelsystems/tools
|
|
2
2
|
|
|
3
|
-
MCP server for project intelligence.
|
|
3
|
+
MCP server for project intelligence. 27 facade tools (170+ internal handlers) across work tracking, architecture, experiments, design, git forensics, agent coordination, and more.
|
|
4
4
|
|
|
5
|
-
Tested with Claude Desktop, Claude Code, and Cursor. [Learn more
|
|
5
|
+
Tested with Claude Desktop, Claude Code, and Cursor. [Learn more](https://decibel.systems/tools)
|
|
6
6
|
|
|
7
7
|
<a href="https://github.com/decibelsystems/decibel-tools-mcp#cursor">
|
|
8
8
|
<img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add to Cursor" height="32" />
|
|
@@ -10,23 +10,6 @@ Tested with Claude Desktop, Claude Code, and Cursor. [Learn more →](https://de
|
|
|
10
10
|
|
|
11
11
|
> **Note:** The one-click Cursor install only works on GitHub. [Click here](https://github.com/decibelsystems/decibel-tools-mcp#cursor) or see manual setup below.
|
|
12
12
|
|
|
13
|
-
## What It Does
|
|
14
|
-
|
|
15
|
-
| Domain | Purpose | Example Tools |
|
|
16
|
-
|--------|---------|---------------|
|
|
17
|
-
| **Sentinel** | Work tracking | `sentinel_create_issue`, `sentinel_log_epic`, `sentinel_list_epics` |
|
|
18
|
-
| **Dojo** | AI incubator | `dojo_add_wish`, `dojo_create_proposal`, `dojo_run_experiment` |
|
|
19
|
-
| **Architect** | Decisions | `architect_createAdr`, `architect_createPolicy` |
|
|
20
|
-
| **Roadmap** | Strategy | `roadmap_get`, `roadmap_getHealth`, `roadmap_linkEpic` |
|
|
21
|
-
| **Oracle** | Recommendations | `oracle_next_actions`, `oracle_roadmap` |
|
|
22
|
-
| **Designer** | Design decisions | `designer_record_design_decision`, `designer_crit` |
|
|
23
|
-
| **Friction** | Pain points | `friction_log`, `friction_bump`, `friction_resolve` |
|
|
24
|
-
| **Learnings** | Knowledge base | `learnings_append`, `learnings_list` |
|
|
25
|
-
| **Context** | AI memory | `decibel_context_pin`, `decibel_context_refresh` |
|
|
26
|
-
| **Registry** | Project management | `project_init`, `registry_list`, `registry_add` |
|
|
27
|
-
| **Agentic** | Config compilation | `agentic_compile_pack`, `agentic_render` |
|
|
28
|
-
| **Provenance** | Audit trail | `provenance_list` |
|
|
29
|
-
|
|
30
13
|
## Quick Start
|
|
31
14
|
|
|
32
15
|
```bash
|
|
@@ -37,11 +20,23 @@ npm install -g @decibelsystems/tools
|
|
|
37
20
|
npx @decibelsystems/tools
|
|
38
21
|
```
|
|
39
22
|
|
|
23
|
+
### Project Setup
|
|
24
|
+
|
|
25
|
+
After installing, initialize your first project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Copy the example registry (one-time setup)
|
|
29
|
+
cp projects.example.json projects.json
|
|
30
|
+
# Edit projects.json with your project paths
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or use the MCP tools directly — call `project_init` with your project path and it will create the `.decibel/` folder and register the project automatically.
|
|
34
|
+
|
|
40
35
|
## Platform Setup
|
|
41
36
|
|
|
42
|
-
###
|
|
37
|
+
### Claude Code
|
|
43
38
|
|
|
44
|
-
Add to `~/.
|
|
39
|
+
Add to `.mcp.json` in your project root or `~/.claude/settings.json`:
|
|
45
40
|
|
|
46
41
|
```json
|
|
47
42
|
{
|
|
@@ -54,9 +49,9 @@ Add to `~/.cursor/mcp.json`:
|
|
|
54
49
|
}
|
|
55
50
|
```
|
|
56
51
|
|
|
57
|
-
###
|
|
52
|
+
### Cursor
|
|
58
53
|
|
|
59
|
-
Add to
|
|
54
|
+
Add to `~/.cursor/mcp.json`:
|
|
60
55
|
|
|
61
56
|
```json
|
|
62
57
|
{
|
|
@@ -86,152 +81,86 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
86
81
|
|
|
87
82
|
---
|
|
88
83
|
|
|
89
|
-
## Tools
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
|
117
|
-
|
|
118
|
-
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
|
123
|
-
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
| `designer_sync_tokens` | Sync design tokens from Figma variables |
|
|
170
|
-
| `designer_review_figma` | Review Figma component against design principles |
|
|
171
|
-
| `designer_upsert_principle` | Create or update a design principle |
|
|
172
|
-
| `designer_list_principles` | List design principles, filter by category |
|
|
173
|
-
|
|
174
|
-
### Friction (4 tools)
|
|
175
|
-
*Track recurring pain points*
|
|
176
|
-
|
|
177
|
-
| Tool | Description |
|
|
178
|
-
|------|-------------|
|
|
179
|
-
| `friction_log` | Log a friction point (context, description, impact) |
|
|
180
|
-
| `friction_list` | List friction points sorted by impact/signal |
|
|
181
|
-
| `friction_resolve` | Mark friction as resolved with solution reference |
|
|
182
|
-
| `friction_bump` | Bump signal count when encountering same friction |
|
|
183
|
-
|
|
184
|
-
### Learnings (2 tools)
|
|
185
|
-
*Living knowledge documents*
|
|
186
|
-
|
|
187
|
-
| Tool | Description |
|
|
188
|
-
|------|-------------|
|
|
189
|
-
| `learnings_append` | Append entry to project's learnings document |
|
|
190
|
-
| `learnings_list` | List entries, filter by category |
|
|
191
|
-
|
|
192
|
-
### Context (8 tools)
|
|
193
|
-
*AI memory: pinned facts, events, artifacts*
|
|
194
|
-
|
|
195
|
-
| Tool | Description |
|
|
196
|
-
|------|-------------|
|
|
197
|
-
| `decibel_context_refresh` | Compile full context pack for AI memory |
|
|
198
|
-
| `decibel_context_pin` | Pin a fact to persistent memory |
|
|
199
|
-
| `decibel_context_unpin` | Remove a pinned fact |
|
|
200
|
-
| `decibel_context_list` | List all pinned facts |
|
|
201
|
-
| `decibel_event_append` | Append event to activity journal |
|
|
202
|
-
| `decibel_event_search` | Search events in journal |
|
|
203
|
-
| `decibel_artifact_list` | List artifacts for a run |
|
|
204
|
-
| `decibel_artifact_read` | Read artifact content |
|
|
205
|
-
|
|
206
|
-
### Registry (7 tools)
|
|
207
|
-
*Project discovery and management*
|
|
208
|
-
|
|
209
|
-
| Tool | Description |
|
|
210
|
-
|------|-------------|
|
|
211
|
-
| `project_init` | Initialize .decibel/ folder in a project |
|
|
212
|
-
| `project_status` | Check project status and available tools |
|
|
213
|
-
| `registry_list` | List all registered projects |
|
|
214
|
-
| `registry_add` | Register a project in the registry |
|
|
215
|
-
| `registry_remove` | Remove project from registry |
|
|
216
|
-
| `registry_alias` | Add alias to a project |
|
|
217
|
-
| `registry_resolve` | Test resolution of project ID/alias |
|
|
218
|
-
|
|
219
|
-
### Agentic (4 tools)
|
|
220
|
-
*Configuration compilation and rendering*
|
|
221
|
-
|
|
222
|
-
| Tool | Description |
|
|
223
|
-
|------|-------------|
|
|
224
|
-
| `agentic_compile_pack` | Compile config into versioned, hashed pack |
|
|
225
|
-
| `agentic_render` | Transform payload into rendered text |
|
|
226
|
-
| `agentic_lint` | Validate output against renderer constraints |
|
|
227
|
-
| `agentic_golden_eval` | Run golden eval regression tests |
|
|
228
|
-
|
|
229
|
-
### Provenance (1 tool)
|
|
230
|
-
*Audit trail*
|
|
231
|
-
|
|
232
|
-
| Tool | Description |
|
|
233
|
-
|------|-------------|
|
|
234
|
-
| `provenance_list` | List provenance events for artifact/actor |
|
|
84
|
+
## Facade Tools
|
|
85
|
+
|
|
86
|
+
All tools are accessed through **facade commands** — one tool per domain, with an `action` parameter to select the operation. For example: `sentinel` with action `create_issue`.
|
|
87
|
+
|
|
88
|
+
### Core (always available)
|
|
89
|
+
|
|
90
|
+
| Facade | Domain | Key Actions |
|
|
91
|
+
|--------|--------|-------------|
|
|
92
|
+
| **sentinel** | Work tracking | `create_issue`, `close_issue`, `log_epic`, `list_epics`, `scan` |
|
|
93
|
+
| **architect** | Decisions | `create_adr`, `create_policy`, `list_policies`, `compile_oversight` |
|
|
94
|
+
| **dojo** | Incubation | `add_wish`, `create_proposal`, `scaffold_experiment`, `run_experiment` |
|
|
95
|
+
| **designer** | Design | `record_design_decision`, `crit`, `sync_tokens`, `review_figma` |
|
|
96
|
+
| **oracle** | Recommendations | `next_actions`, `roadmap` |
|
|
97
|
+
| **roadmap** | Strategy | `get`, `list`, `get_health`, `link_epic`, `init` |
|
|
98
|
+
| **git** | Git forensics | `history`, `changes`, `link_issue` |
|
|
99
|
+
| **workflow** | Composites | `status`, `preflight`, `ship`, `investigate` |
|
|
100
|
+
| **vector** | Agent runs | `track`, `drift`, `score` |
|
|
101
|
+
| **context** | AI memory | `pin`, `unpin`, `list`, `refresh`, `event_append`, `event_search` |
|
|
102
|
+
| **auditor** | Code quality | `health`, `refactor_score` |
|
|
103
|
+
| **forecast** | Estimation | `estimate`, `decompose`, `capacity` |
|
|
104
|
+
| **velocity** | Metrics | `trends`, `contributors` |
|
|
105
|
+
| **coordinator** | Multi-agent | `lock`, `unlock`, `heartbeat`, `log`, `message` |
|
|
106
|
+
| **swarm** | Agent sessions | `start_session`, `join_session`, `emit_signal`, `claim_signal` |
|
|
107
|
+
| **friction** | Pain points | `log`, `list`, `resolve`, `bump` |
|
|
108
|
+
| **registry** | Projects | `add`, `remove`, `list`, `alias`, `init`, `status` |
|
|
109
|
+
| **feedback** | Tool feedback | `submit`, `list` |
|
|
110
|
+
| **learnings** | Knowledge | `append`, `list` |
|
|
111
|
+
| **provenance** | Audit trail | `list` |
|
|
112
|
+
| **bench** | Benchmarks | `run`, `compare` |
|
|
113
|
+
| **guardian** | Security | `scan_deps`, `scan_secrets`, `scan_http`, `scan_config`, `report` |
|
|
114
|
+
|
|
115
|
+
### Pro (requires `DECIBEL_PRO=1`)
|
|
116
|
+
|
|
117
|
+
| Facade | Domain | Key Actions |
|
|
118
|
+
|--------|--------|-------------|
|
|
119
|
+
| **voice** | Voice inbox | `sync`, `list`, `process` |
|
|
120
|
+
| **studio** | Creative assets | `generate_image`, `generate_video` |
|
|
121
|
+
| **corpus** | Code patterns | `search`, `index` |
|
|
122
|
+
| **agentic** | Config compilation | `compile_pack`, `render`, `lint`, `golden_eval` |
|
|
123
|
+
|
|
124
|
+
> All tiers are auto-enabled in development (`NODE_ENV !== 'production'`).
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Daemon Mode
|
|
129
|
+
|
|
130
|
+
Run as a persistent background service with HTTP transport:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Start daemon (default port 4888)
|
|
134
|
+
npx @decibelsystems/tools --daemon
|
|
135
|
+
|
|
136
|
+
# Dual mode: stdio + HTTP from one process
|
|
137
|
+
npx @decibelsystems/tools --daemon --stdio
|
|
138
|
+
|
|
139
|
+
# macOS launchd management
|
|
140
|
+
npx @decibelsystems/tools --daemon install
|
|
141
|
+
npx @decibelsystems/tools --daemon uninstall
|
|
142
|
+
npx @decibelsystems/tools --daemon status
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The daemon includes log rotation, crash loop protection (5 crashes in 60s), graceful shutdown with request draining, and a `/health` endpoint.
|
|
146
|
+
|
|
147
|
+
### Configuration
|
|
148
|
+
|
|
149
|
+
Create `~/.decibel/config.yaml` to configure the daemon:
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
daemon:
|
|
153
|
+
port: 4888
|
|
154
|
+
host: localhost
|
|
155
|
+
auth_token: your-secret-token
|
|
156
|
+
log_max_size_mb: 10
|
|
157
|
+
log_max_files: 3
|
|
158
|
+
rate_limit_rpm: 60
|
|
159
|
+
license:
|
|
160
|
+
key: your-license-key
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
CLI flags override config file values. Send `SIGHUP` to reload config without restarting.
|
|
235
164
|
|
|
236
165
|
---
|
|
237
166
|
|
|
@@ -252,88 +181,41 @@ Data is stored in project-local `.decibel/` folders:
|
|
|
252
181
|
│ ├── proposals/ # DOJO-PROP-{nnnn}.yml
|
|
253
182
|
│ ├── experiments/ # DOJO-EXP-{nnnn}/
|
|
254
183
|
│ └── wishes/ # WISH-{nnnn}.yml
|
|
255
|
-
├── designer/ # Design decisions
|
|
184
|
+
├── designer/ # Design decisions, principles, crits
|
|
256
185
|
├── friction/ # Pain point logs
|
|
257
186
|
├── learnings/ # Knowledge documents
|
|
258
187
|
├── context/ # Pinned facts, events
|
|
188
|
+
├── guardian/ # Security scan results, allowlists
|
|
259
189
|
└── voice/inbox/ # Voice messages
|
|
260
190
|
```
|
|
261
191
|
|
|
262
|
-
##
|
|
192
|
+
## Environment Variables
|
|
193
|
+
|
|
194
|
+
### Core
|
|
263
195
|
|
|
264
196
|
| Variable | Default | Description |
|
|
265
197
|
|----------|---------|-------------|
|
|
266
198
|
| `DECIBEL_ENV` | `dev` | Environment (dev, staging, prod) |
|
|
267
|
-
| `DECIBEL_ORG` | `
|
|
199
|
+
| `DECIBEL_ORG` | `default` | Organization name |
|
|
268
200
|
| `DECIBEL_MCP_ROOT` | `~/.decibel` | Global data storage root |
|
|
201
|
+
| `DECIBEL_PROJECT_ROOT` | — | Current project root path |
|
|
202
|
+
| `DECIBEL_REGISTRY_PATH` | — | Custom registry file location |
|
|
269
203
|
|
|
270
|
-
Optional
|
|
271
|
-
- `SUPABASE_URL` - Supabase project URL
|
|
272
|
-
- `SUPABASE_SERVICE_KEY` - Supabase service role key
|
|
273
|
-
- `OPENAI_API_KEY` - For image generation
|
|
274
|
-
- `FIGMA_ACCESS_TOKEN` - For Figma integration (designer_sync_tokens, designer_review_figma)
|
|
204
|
+
### Optional Integrations
|
|
275
205
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
AI uses: project_init → sentinel_log_epic
|
|
284
|
-
|
|
285
|
-
Result: Creates .decibel/ folder structure and EPIC-0001.yml for "User Authentication"
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### Example 2: Track Work with Issues Linked to Epics
|
|
289
|
-
|
|
290
|
-
```
|
|
291
|
-
User: "Create issues for the auth epic: login form, password reset, and session management"
|
|
292
|
-
|
|
293
|
-
AI uses: sentinel_resolve_epic → sentinel_createIssue (×3)
|
|
294
|
-
|
|
295
|
-
Result: Creates ISS-0001, ISS-0002, ISS-0003 all linked to EPIC-0001
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Example 3: Record Architecture Decisions
|
|
299
|
-
|
|
300
|
-
```
|
|
301
|
-
User: "We decided to use JWT tokens instead of sessions. Document this ADR."
|
|
302
|
-
|
|
303
|
-
AI uses: architect_createAdr
|
|
304
|
-
|
|
305
|
-
Result: Creates ADR-0001.yml with context, decision, and consequences
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Example 4: AI Feature Incubation (Dojo)
|
|
309
|
-
|
|
310
|
-
```
|
|
311
|
-
User: "I wish we had a tool that detects rate limit patterns in logs"
|
|
312
|
-
|
|
313
|
-
AI uses: dojo_add_wish → dojo_create_proposal → dojo_scaffold_experiment
|
|
314
|
-
|
|
315
|
-
Result: WISH-0001.yml → DOJO-PROP-0001.yml → DOJO-EXP-0001/ with entrypoint ready to implement
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### Example 5: Get Recommended Next Actions
|
|
319
|
-
|
|
320
|
-
```
|
|
321
|
-
User: "What should I work on next?"
|
|
322
|
-
|
|
323
|
-
AI uses: oracle_next_actions
|
|
324
|
-
|
|
325
|
-
Result: Prioritized list based on stale issues, epic health, pending experiments
|
|
326
|
-
```
|
|
206
|
+
| Variable | Used By |
|
|
207
|
+
|----------|---------|
|
|
208
|
+
| `SUPABASE_URL` | Voice inbox, swarm sessions |
|
|
209
|
+
| `SUPABASE_SERVICE_KEY` | Supabase service role key |
|
|
210
|
+
| `FIGMA_ACCESS_TOKEN` | Designer: `sync_tokens`, `review_figma` |
|
|
211
|
+
| `OPENAI_API_KEY` | Studio: image generation |
|
|
212
|
+
| `TOGETHER_API_KEY` | Studio: alternative image generation |
|
|
327
213
|
|
|
328
214
|
## Privacy Policy
|
|
329
215
|
|
|
330
216
|
**Local Storage Only**: All project data is stored locally in `.decibel/` folders within your project directories. No data is sent to external servers by default.
|
|
331
217
|
|
|
332
|
-
**Optional Cloud Integrations**: Some tools optionally connect to external services when you explicitly configure API keys:
|
|
333
|
-
- **Figma API** (`designer_sync_tokens`, `designer_review_figma`) - requires `FIGMA_ACCESS_TOKEN`
|
|
334
|
-
- **Supabase** (voice inbox sync) - requires `SUPABASE_URL` and `SUPABASE_SERVICE_KEY`
|
|
335
|
-
|
|
336
|
-
These optional integrations are clearly marked with `openWorldHint: true` in their tool annotations.
|
|
218
|
+
**Optional Cloud Integrations**: Some tools optionally connect to external services when you explicitly configure API keys (Figma, Supabase, OpenAI). These are clearly marked with `openWorldHint: true` in their tool annotations.
|
|
337
219
|
|
|
338
220
|
**No Telemetry**: This MCP server does not collect telemetry, usage analytics, or any form of tracking data.
|
|
339
221
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import type { FacadeClientConfig, BatchCall, BatchResult } from './types.js';
|
|
2
|
+
import type { FacadeClientConfig, CallContext, BatchCall, BatchResult } from './types.js';
|
|
3
3
|
export declare class FacadeClient {
|
|
4
4
|
private transport;
|
|
5
5
|
private config;
|
|
@@ -18,18 +18,24 @@ export declare class FacadeClient {
|
|
|
18
18
|
/**
|
|
19
19
|
* Call a facade action.
|
|
20
20
|
*
|
|
21
|
+
* @param context Per-call context that overrides config-level defaults.
|
|
22
|
+
*
|
|
21
23
|
* @example
|
|
22
24
|
* const epics = await client.call('sentinel', 'list_epics');
|
|
23
25
|
* const issue = await client.call('sentinel', 'create_issue', { title: 'Fix login' });
|
|
26
|
+
* const scoped = await client.call('sentinel', 'list_epics', {}, { scope: 'portfolio' });
|
|
24
27
|
*/
|
|
25
|
-
call<T = unknown>(facade: string, action: string, params?: Record<string, unknown
|
|
28
|
+
call<T = unknown>(facade: string, action: string, params?: Record<string, unknown>, context?: CallContext): Promise<T>;
|
|
26
29
|
/**
|
|
27
30
|
* Batch multiple facade calls (max 20, parallel execution).
|
|
28
31
|
*
|
|
32
|
+
* @param context Batch-level context applied to all calls.
|
|
33
|
+
* Individual BatchCall.context merges with (and overrides) this.
|
|
34
|
+
*
|
|
29
35
|
* For HTTP transport, uses the daemon's /batch endpoint directly.
|
|
30
36
|
* For stdio transport, runs calls in parallel via Promise.all.
|
|
31
37
|
*/
|
|
32
|
-
batch(calls: BatchCall[]): Promise<BatchResult[]>;
|
|
38
|
+
batch(calls: BatchCall[], context?: CallContext): Promise<BatchResult[]>;
|
|
33
39
|
/** Whether the client is currently connected */
|
|
34
40
|
get isConnected(): boolean;
|
|
35
41
|
/** Current transport mode for diagnostics */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facade-client.d.ts","sourceRoot":"","sources":["../../src/client/facade-client.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"facade-client.d.ts","sourceRoot":"","sources":["../../src/client/facade-client.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAU1F,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,GAAG,CAAwB;IAEnC,QAAQ,CAAC,MAAM,wBAAsB;gBAEzB,MAAM,EAAE,kBAAkB;IAYtC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAc9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC;;;;;;;;;OASG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC;IAkEb;;;;;;;;OAQG;IACG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAsF9E,gDAAgD;IAChD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,6CAA6C;IAC7C,IAAI,IAAI,IAAI,MAAM,CAOjB;YAMa,SAAS;IAmCvB,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;CASzB"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// await client.disconnect();
|
|
16
16
|
// ============================================================================
|
|
17
17
|
import { EventEmitter } from 'events';
|
|
18
|
+
import { randomUUID } from 'crypto';
|
|
18
19
|
import { StdioTransport, HttpTransport, BridgeTransport, } from './transports.js';
|
|
19
20
|
const MAX_BATCH_SIZE = 20;
|
|
20
21
|
export class FacadeClient {
|
|
@@ -60,11 +61,14 @@ export class FacadeClient {
|
|
|
60
61
|
/**
|
|
61
62
|
* Call a facade action.
|
|
62
63
|
*
|
|
64
|
+
* @param context Per-call context that overrides config-level defaults.
|
|
65
|
+
*
|
|
63
66
|
* @example
|
|
64
67
|
* const epics = await client.call('sentinel', 'list_epics');
|
|
65
68
|
* const issue = await client.call('sentinel', 'create_issue', { title: 'Fix login' });
|
|
69
|
+
* const scoped = await client.call('sentinel', 'list_epics', {}, { scope: 'portfolio' });
|
|
66
70
|
*/
|
|
67
|
-
async call(facade, action, params) {
|
|
71
|
+
async call(facade, action, params, context) {
|
|
68
72
|
// Enforce allowlist
|
|
69
73
|
if (this.config.allowedFacades && !this.config.allowedFacades.includes(facade)) {
|
|
70
74
|
throw new Error(`Facade "${facade}" not in allowed scope. Allowed: [${this.config.allowedFacades.join(', ')}]`);
|
|
@@ -73,29 +77,36 @@ export class FacadeClient {
|
|
|
73
77
|
await this.connect();
|
|
74
78
|
// Build args: facade dispatch expects { action, ...params }
|
|
75
79
|
const args = { action, ...params };
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
// Resolve effective scope: per-call > config-level
|
|
81
|
+
const effectiveScope = context?.scope ?? this.config.projectId;
|
|
82
|
+
// Auto-inject project_id from effective scope if not already provided
|
|
83
|
+
if (effectiveScope && !args.project_id) {
|
|
84
|
+
args.project_id = effectiveScope;
|
|
79
85
|
}
|
|
86
|
+
// Generate request correlation ID
|
|
87
|
+
const requestId = randomUUID();
|
|
80
88
|
// Thread DispatchContext via _meta (MCP convention)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
// Per-call context merges with and overrides config-level defaults
|
|
90
|
+
args._meta = {
|
|
91
|
+
agentId: context?.agentId ?? this.config.agentId,
|
|
92
|
+
scope: effectiveScope,
|
|
93
|
+
runId: context?.runId,
|
|
94
|
+
engagementMode: context?.engagementMode,
|
|
95
|
+
userKey: context?.userKey,
|
|
96
|
+
requestId,
|
|
97
|
+
};
|
|
98
|
+
this.log(`call ${facade}.${action} (req=${requestId.slice(0, 8)})`);
|
|
88
99
|
const startTime = Date.now();
|
|
89
100
|
try {
|
|
90
101
|
const result = await this.transport.call(facade, args);
|
|
91
102
|
const duration = Date.now() - startTime;
|
|
92
|
-
this.events.emit('result', { facade, action, duration_ms: duration, success: true });
|
|
103
|
+
this.events.emit('result', { facade, action, duration_ms: duration, success: true, requestId });
|
|
93
104
|
return result;
|
|
94
105
|
}
|
|
95
106
|
catch (err) {
|
|
96
107
|
const duration = Date.now() - startTime;
|
|
97
108
|
const message = err instanceof Error ? err.message : String(err);
|
|
98
|
-
this.events.emit('error', { facade, action, duration_ms: duration, error: message });
|
|
109
|
+
this.events.emit('error', { facade, action, duration_ms: duration, error: message, requestId });
|
|
99
110
|
// Try to parse structured error from the server
|
|
100
111
|
if (err.isCallError && err.raw) {
|
|
101
112
|
try {
|
|
@@ -114,10 +125,13 @@ export class FacadeClient {
|
|
|
114
125
|
/**
|
|
115
126
|
* Batch multiple facade calls (max 20, parallel execution).
|
|
116
127
|
*
|
|
128
|
+
* @param context Batch-level context applied to all calls.
|
|
129
|
+
* Individual BatchCall.context merges with (and overrides) this.
|
|
130
|
+
*
|
|
117
131
|
* For HTTP transport, uses the daemon's /batch endpoint directly.
|
|
118
132
|
* For stdio transport, runs calls in parallel via Promise.all.
|
|
119
133
|
*/
|
|
120
|
-
async batch(calls) {
|
|
134
|
+
async batch(calls, context) {
|
|
121
135
|
if (calls.length === 0)
|
|
122
136
|
return [];
|
|
123
137
|
if (calls.length > MAX_BATCH_SIZE) {
|
|
@@ -132,33 +146,48 @@ export class FacadeClient {
|
|
|
132
146
|
}
|
|
133
147
|
}
|
|
134
148
|
await this.connect();
|
|
149
|
+
// Resolve effective batch-level context (per-batch > config defaults)
|
|
150
|
+
const effectiveScope = context?.scope ?? this.config.projectId;
|
|
151
|
+
const effectiveAgentId = context?.agentId ?? this.config.agentId;
|
|
135
152
|
// Try native /batch endpoint for HTTP transport
|
|
136
153
|
const httpTransport = this.getHttpTransport();
|
|
137
154
|
if (httpTransport) {
|
|
138
155
|
this.log(`batch (HTTP) — ${calls.length} calls`);
|
|
139
|
-
const
|
|
140
|
-
agentId:
|
|
141
|
-
scope:
|
|
156
|
+
const httpContext = {
|
|
157
|
+
agentId: effectiveAgentId,
|
|
158
|
+
scope: effectiveScope,
|
|
159
|
+
runId: context?.runId,
|
|
160
|
+
engagementMode: context?.engagementMode,
|
|
161
|
+
userKey: context?.userKey,
|
|
162
|
+
requestId: randomUUID(),
|
|
142
163
|
};
|
|
143
164
|
// Inject project_id into each call's params
|
|
144
|
-
const enrichedCalls = calls.map(c =>
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
const enrichedCalls = calls.map(c => {
|
|
166
|
+
const callScope = c.context?.scope ?? effectiveScope;
|
|
167
|
+
return {
|
|
168
|
+
facade: c.facade,
|
|
169
|
+
action: c.action,
|
|
170
|
+
params: {
|
|
171
|
+
...c.params,
|
|
172
|
+
...(callScope && !c.params?.project_id
|
|
173
|
+
? { project_id: callScope }
|
|
174
|
+
: {}),
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
const result = await httpTransport.batch(enrichedCalls, httpContext);
|
|
154
179
|
return result;
|
|
155
180
|
}
|
|
156
|
-
// Stdio fallback: parallel Promise.all
|
|
181
|
+
// Stdio fallback: parallel Promise.all (each call gets its own requestId via call())
|
|
157
182
|
this.log(`batch (stdio) — ${calls.length} calls`);
|
|
158
183
|
const results = await Promise.all(calls.map(async (c) => {
|
|
159
184
|
const start = Date.now();
|
|
185
|
+
// Per-call context merges: call-level > batch-level > config
|
|
186
|
+
const callCtx = c.context
|
|
187
|
+
? { ...context, ...c.context }
|
|
188
|
+
: context;
|
|
160
189
|
try {
|
|
161
|
-
const data = await this.call(c.facade, c.action, c.params);
|
|
190
|
+
const data = await this.call(c.facade, c.action, c.params, callCtx);
|
|
162
191
|
return {
|
|
163
192
|
facade: c.facade,
|
|
164
193
|
action: c.action,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facade-client.js","sourceRoot":"","sources":["../../src/client/facade-client.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oDAAoD;AACpD,+EAA+E;AAC/E,0DAA0D;AAC1D,gEAAgE;AAChE,EAAE;AACF,SAAS;AACT,sCAAsC;AACtC,iDAAiD;AACjD,mDAAmD;AACnD,wDAAwD;AACxD,QAAQ;AACR,4BAA4B;AAC5B,+DAA+D;AAC/D,+BAA+B;AAC/B,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"facade-client.js","sourceRoot":"","sources":["../../src/client/facade-client.ts"],"names":[],"mappings":"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"}
|