@telora/mcp-products 0.21.1
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 +276 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +94 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/handlers/agentHandlers.d.ts +3 -0
- package/dist/handlers/agentHandlers.js +97 -0
- package/dist/handlers/agentHandlers.js.map +1 -0
- package/dist/handlers/connectorHandlers.d.ts +3 -0
- package/dist/handlers/connectorHandlers.js +401 -0
- package/dist/handlers/connectorHandlers.js.map +1 -0
- package/dist/handlers/contextHandlers.d.ts +8 -0
- package/dist/handlers/contextHandlers.js +169 -0
- package/dist/handlers/contextHandlers.js.map +1 -0
- package/dist/handlers/deliveryHandlers.d.ts +3 -0
- package/dist/handlers/deliveryHandlers.js +122 -0
- package/dist/handlers/deliveryHandlers.js.map +1 -0
- package/dist/handlers/deploymentProfileHandlers.d.ts +3 -0
- package/dist/handlers/deploymentProfileHandlers.js +104 -0
- package/dist/handlers/deploymentProfileHandlers.js.map +1 -0
- package/dist/handlers/discoverHandler.d.ts +23 -0
- package/dist/handlers/discoverHandler.js +83 -0
- package/dist/handlers/discoverHandler.js.map +1 -0
- package/dist/handlers/factoryHandlers.d.ts +3 -0
- package/dist/handlers/factoryHandlers.js +484 -0
- package/dist/handlers/factoryHandlers.js.map +1 -0
- package/dist/handlers/ideaHandlers.d.ts +3 -0
- package/dist/handlers/ideaHandlers.js +245 -0
- package/dist/handlers/ideaHandlers.js.map +1 -0
- package/dist/handlers/index.d.ts +15 -0
- package/dist/handlers/index.js +19 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/infrastructureHandlers.d.ts +3 -0
- package/dist/handlers/infrastructureHandlers.js +335 -0
- package/dist/handlers/infrastructureHandlers.js.map +1 -0
- package/dist/handlers/issueHandlers.d.ts +3 -0
- package/dist/handlers/issueHandlers.js +94 -0
- package/dist/handlers/issueHandlers.js.map +1 -0
- package/dist/handlers/okrHandlers.d.ts +3 -0
- package/dist/handlers/okrHandlers.js +194 -0
- package/dist/handlers/okrHandlers.js.map +1 -0
- package/dist/handlers/playbookHandlers.d.ts +3 -0
- package/dist/handlers/playbookHandlers.js +93 -0
- package/dist/handlers/playbookHandlers.js.map +1 -0
- package/dist/handlers/productHandlers.d.ts +3 -0
- package/dist/handlers/productHandlers.js +129 -0
- package/dist/handlers/productHandlers.js.map +1 -0
- package/dist/handlers/reportHandlers.d.ts +3 -0
- package/dist/handlers/reportHandlers.js +59 -0
- package/dist/handlers/reportHandlers.js.map +1 -0
- package/dist/handlers/strategyHandlers.d.ts +3 -0
- package/dist/handlers/strategyHandlers.js +116 -0
- package/dist/handlers/strategyHandlers.js.map +1 -0
- package/dist/handlers/workflowHandlers.d.ts +3 -0
- package/dist/handlers/workflowHandlers.js +93 -0
- package/dist/handlers/workflowHandlers.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +284 -0
- package/dist/index.js.map +1 -0
- package/dist/shared.d.ts +77 -0
- package/dist/shared.js +147 -0
- package/dist/shared.js.map +1 -0
- package/package.json +47 -0
- package/scripts/postinstall.js +96 -0
package/README.md
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# @telora/mcp-products
|
|
2
|
+
|
|
3
|
+
MCP server that exposes Telora product operations to Claude Code. Tools use a consolidated action-based API — each tool handles multiple actions via an `action` parameter (e.g., `telora_product` with `action: "list"` or `action: "create"`).
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### 1. Add to your project
|
|
8
|
+
|
|
9
|
+
Create `.mcp.json` in your project root, pointing to the local build:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"telora-products": {
|
|
15
|
+
"command": "node",
|
|
16
|
+
"args": ["mcp/telora-products/dist/index.js"],
|
|
17
|
+
"env": {
|
|
18
|
+
"TELORA_TRACKER_ID": "your-tracker-uuid",
|
|
19
|
+
"TELORA_URL": "http://your-supabase-url:54321",
|
|
20
|
+
"TELORA_MCP_PROFILE": "human"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> **Note:** Earlier versions used `npx @telora/mcp-products`, but `npx` resolves to a globally installed version which may be outdated. The local build path prevents version drift.
|
|
28
|
+
|
|
29
|
+
### 2. Register credentials (once per machine)
|
|
30
|
+
|
|
31
|
+
Ask your Telora org admin to create an AI tracker for you, then register with the code:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
telora-ai register <registration-code>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Alternatively, set environment variables `TELORA_TRACKER_ID` and `TELORA_URL` in `.mcp.json`.
|
|
38
|
+
|
|
39
|
+
### 3. Build the MCP server
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cd mcp/telora-products && npm run build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 4. Restart Claude Code
|
|
46
|
+
|
|
47
|
+
The tools will be available immediately.
|
|
48
|
+
|
|
49
|
+
## Profiles
|
|
50
|
+
|
|
51
|
+
The `TELORA_MCP_PROFILE` environment variable controls which tools are registered:
|
|
52
|
+
|
|
53
|
+
| Profile | Use case | Behavior |
|
|
54
|
+
|---------|----------|----------|
|
|
55
|
+
| `human` | Interactive Claude Code sessions | Core tools at startup + `telora_discover` for on-demand loading |
|
|
56
|
+
| `full` | Default, all tools | Everything registered at startup |
|
|
57
|
+
| `execution` | Daemon strategy execution | Delivery/issue/agent tools, no OKR/ideas/workflows |
|
|
58
|
+
| `factory` | Daemon factory execution | Factory + product tools only |
|
|
59
|
+
|
|
60
|
+
## Tool Discovery (Human Profile)
|
|
61
|
+
|
|
62
|
+
The human profile uses a two-tier loading strategy to stay within Claude Code's deferred tool budget:
|
|
63
|
+
|
|
64
|
+
**Startup tools (always available, 21 decomposed):**
|
|
65
|
+
- `telora_product` — 5 actions: list, create, get, update, overview
|
|
66
|
+
- `telora_product_strategy` — 4 actions: list, create, update, reorder
|
|
67
|
+
- `telora_product_delivery` — 6 actions: list, create, update, operationalize, delete, reorder
|
|
68
|
+
- `telora_product_issue` — 4 actions: list, create, update, delete
|
|
69
|
+
- `telora_discover` — 2 actions: list, load
|
|
70
|
+
|
|
71
|
+
**Deferred domains (loaded on demand via `telora_discover`):**
|
|
72
|
+
|
|
73
|
+
| Domain | Tools | Actions | Why deferred |
|
|
74
|
+
|--------|-------|---------|--------------|
|
|
75
|
+
| agent | `telora_agent` | 5 | Escalations are infrequent in interactive sessions |
|
|
76
|
+
| context | `telora_product_context`, `telora_product_context_link` | 7 | Context doc management is occasional setup work |
|
|
77
|
+
| connector | `telora_connector_start` | 1 | Daemon launch is a one-time operation |
|
|
78
|
+
| factory | `telora_factory_blueprint_list`, `telora_factory_spec`, `telora_factory_instance` | 8 | Factory workflows are a separate domain |
|
|
79
|
+
| okr | `telora_objective`, `telora_key_result`, `telora_strategy_key_result` | 10 | Goal-setting is periodic, not daily |
|
|
80
|
+
| ideas | `telora_idea`, `telora_idea_connection`, `telora_idea_cluster` | 12 | Brainstorming is a distinct activity |
|
|
81
|
+
| workflows | `telora_workflow` | 5 | Workflow config is admin setup |
|
|
82
|
+
| playbooks | `telora_playbook` | 4 | Template usage is infrequent |
|
|
83
|
+
| profiles | `telora_deployment_profile` | 5 | CI/CD config is setup work |
|
|
84
|
+
|
|
85
|
+
**Total after full discover: 78 decomposed tools (within the 80 budget).**
|
|
86
|
+
|
|
87
|
+
### Using telora_discover
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
# List all domains with their tool indexes (shows what's available before loading)
|
|
91
|
+
telora_discover(action: "list")
|
|
92
|
+
|
|
93
|
+
# Load a specific domain
|
|
94
|
+
telora_discover(action: "load", domain: "factory")
|
|
95
|
+
|
|
96
|
+
# Load everything at once
|
|
97
|
+
telora_discover(action: "load", domain: "all")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The `list` action returns a `toolIndex` per domain — tool names, summaries, available actions, and keywords — so you can decide which domain to load without guessing.
|
|
101
|
+
|
|
102
|
+
## Available Tools
|
|
103
|
+
|
|
104
|
+
### Product Management
|
|
105
|
+
| Tool | Actions | Description |
|
|
106
|
+
|------|---------|-------------|
|
|
107
|
+
| `telora_product` | list, create, get, update, overview | Product registry: manage software products and their settings |
|
|
108
|
+
|
|
109
|
+
### Strategy Management
|
|
110
|
+
| Tool | Actions | Description |
|
|
111
|
+
|------|---------|-------------|
|
|
112
|
+
| `telora_product_strategy` | list, create, update, reorder | Execution roadmap: group deliveries into themed work scopes |
|
|
113
|
+
|
|
114
|
+
### Delivery Management
|
|
115
|
+
| Tool | Actions | Description |
|
|
116
|
+
|------|---------|-------------|
|
|
117
|
+
| `telora_product_delivery` | list, create, update, operationalize, delete, reorder | Work packages: shippable increments with acceptance criteria |
|
|
118
|
+
|
|
119
|
+
### Issue Tracking
|
|
120
|
+
| Tool | Actions | Description |
|
|
121
|
+
|------|---------|-------------|
|
|
122
|
+
| `telora_product_issue` | list, create, update, delete | Task tracking: issues, bugs, and context groups within deliveries |
|
|
123
|
+
|
|
124
|
+
### Agent & Escalation
|
|
125
|
+
| Tool | Actions | Description |
|
|
126
|
+
|------|---------|-------------|
|
|
127
|
+
| `telora_agent` | role_list, escalate, escalation_list, escalation_get, escalation_update | AI agent roles and human-AI escalation requests |
|
|
128
|
+
|
|
129
|
+
### Context Documents
|
|
130
|
+
| Tool | Actions | Description |
|
|
131
|
+
|------|---------|-------------|
|
|
132
|
+
| `telora_product_context` | list, create, update, delete, reorder | Knowledge base: product context documents for AI agents |
|
|
133
|
+
| `telora_product_context_link` | link, unlink | Attach/detach context documents to strategies or deliveries |
|
|
134
|
+
|
|
135
|
+
### Factory
|
|
136
|
+
| Tool | Actions | Description |
|
|
137
|
+
|------|---------|-------------|
|
|
138
|
+
| `telora_factory_blueprint_list` | _(no action param)_ | List factory blueprints with gate configs and resource limits |
|
|
139
|
+
| `telora_factory_spec` | create, get, list, update, validate | Define what to build via conversational spec authoring |
|
|
140
|
+
| `telora_factory_instance` | get, update | View and control running factory instances (pause, cancel) |
|
|
141
|
+
|
|
142
|
+
### OKR Management
|
|
143
|
+
| Tool | Actions | Description |
|
|
144
|
+
|------|---------|-------------|
|
|
145
|
+
| `telora_objective` | create, get, list, update | Strategic objectives with cascading alignment |
|
|
146
|
+
| `telora_key_result` | create, list, update, delete | Measurable targets with metric types and confidence levels |
|
|
147
|
+
| `telora_strategy_key_result` | link, unlink | Connect strategies to key results for traceability |
|
|
148
|
+
|
|
149
|
+
### Idea Cloud
|
|
150
|
+
| Tool | Actions | Description |
|
|
151
|
+
|------|---------|-------------|
|
|
152
|
+
| `telora_idea` | create, list, update, delete | Capture ideas: observations, hypotheses, references |
|
|
153
|
+
| `telora_idea_connection` | create, list, update, delete | Map relationships between ideas (supports, causes, contradicts) |
|
|
154
|
+
| `telora_idea_cluster` | create, list, update, delete | Group related ideas into clusters |
|
|
155
|
+
|
|
156
|
+
### Workflows
|
|
157
|
+
| Tool | Actions | Description |
|
|
158
|
+
|------|---------|-------------|
|
|
159
|
+
| `telora_workflow` | list, get, create, update, assign | Configure lifecycle stages, transition guards, and assignments |
|
|
160
|
+
|
|
161
|
+
### Playbooks
|
|
162
|
+
| Tool | Actions | Description |
|
|
163
|
+
|------|---------|-------------|
|
|
164
|
+
| `telora_playbook` | list, get, create, instantiate | Template strategies with pre-configured deliveries and issues |
|
|
165
|
+
|
|
166
|
+
### Deployment Profiles
|
|
167
|
+
| Tool | Actions | Description |
|
|
168
|
+
|------|---------|-------------|
|
|
169
|
+
| `telora_deployment_profile` | create, list, get, update, link_to_product | Define target environments and deployment guidelines |
|
|
170
|
+
|
|
171
|
+
### Connector
|
|
172
|
+
| Tool | Actions | Description |
|
|
173
|
+
|------|---------|-------------|
|
|
174
|
+
| `telora_connector_start` | _(no action param)_ | Launch Telora daemon for autonomous agent execution |
|
|
175
|
+
|
|
176
|
+
## Usage
|
|
177
|
+
|
|
178
|
+
Just ask Claude Code naturally:
|
|
179
|
+
|
|
180
|
+
- "Show me my products in Telora"
|
|
181
|
+
- "Create a new strategy called 'Q1 Launch' for my product"
|
|
182
|
+
- "List all issues for the current delivery"
|
|
183
|
+
- "Create a P0 bug under delivery X"
|
|
184
|
+
|
|
185
|
+
## Common Workflows
|
|
186
|
+
|
|
187
|
+
### Create a product with strategy and delivery
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
1. telora_product(action: "create", name: "My App")
|
|
191
|
+
2. telora_product_strategy(action: "create", productId: "<id>", name: "MVP Launch")
|
|
192
|
+
3. telora_product_delivery(action: "create", productId: "<id>", name: "Core Features", strategyId: "<id>")
|
|
193
|
+
4. telora_product_issue(action: "create", deliveryId: "<id>", title: "Build login page", issueType: "Task")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Track work on issues
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
1. telora_product_issue(action: "list", deliveryId: "<id>")
|
|
200
|
+
2. telora_product_issue(action: "update", issueId: "<id>", status: "In Progress")
|
|
201
|
+
3. telora_product_issue(action: "update", issueId: "<id>", status: "Done")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Set up OKRs linked to strategy
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
1. telora_objective(action: "create", title: "Increase user retention")
|
|
208
|
+
2. telora_key_result(action: "create", objectiveId: "<id>", title: "Reduce churn to 5%", targetValue: 5, unit: "%")
|
|
209
|
+
3. telora_strategy_key_result(action: "link", strategyId: "<id>", keyResultId: "<id>")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Load a playbook
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
1. telora_playbook(action: "list")
|
|
216
|
+
2. telora_playbook(action: "get", playbookId: "<id>")
|
|
217
|
+
3. telora_playbook(action: "instantiate", playbookId: "<id>", productId: "<id>")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Manage context documents
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
1. telora_product_context(action: "create", productId: "<id>", title: "Architecture Guide", content: "...", includeMode: "always")
|
|
224
|
+
2. telora_product_context_link(action: "link", documentId: "<id>", entityType: "strategy", entityId: "<id>")
|
|
225
|
+
3. telora_product_context(action: "list", productId: "<id>", strategyId: "<id>")
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Assign a workflow to a delivery
|
|
229
|
+
|
|
230
|
+
```text
|
|
231
|
+
1. telora_workflow(action: "list", entityType: "delivery")
|
|
232
|
+
2. telora_workflow(action: "assign", workflowId: "<id>", entityType: "delivery", entityId: "<id>")
|
|
233
|
+
3. telora_workflow(action: "get", workflowId: "<id>")
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Build an idea cloud
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
1. telora_idea(action: "create", productId: "<id>", content: "Users want faster onboarding", sourceType: "observation")
|
|
240
|
+
2. telora_idea(action: "create", productId: "<id>", content: "Reduce sign-up steps to 2", sourceType: "hypothesis")
|
|
241
|
+
3. telora_idea_connection(action: "create", sourceIdeaId: "<id1>", targetIdeaId: "<id2>", connectionType: "supports")
|
|
242
|
+
4. telora_idea_cluster(action: "create", productId: "<id>", name: "Onboarding", centerIdeaIds: ["<id1>", "<id2>"])
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Error Handling
|
|
246
|
+
|
|
247
|
+
All tools return errors in a consistent format. Common errors:
|
|
248
|
+
|
|
249
|
+
| Error | Cause | Resolution |
|
|
250
|
+
|-------|-------|------------|
|
|
251
|
+
| "Invalid access token" | Tracker ID expired or invalid | Regenerate tracker ID in Telora UI |
|
|
252
|
+
| "Rate limit exceeded" | Too many requests | Wait and retry |
|
|
253
|
+
| "Not found" | Resource doesn't exist | Check the ID |
|
|
254
|
+
| "Insufficient permissions" | User lacks access to the org unit | Request access from admin |
|
|
255
|
+
|
|
256
|
+
## Credential Sources
|
|
257
|
+
|
|
258
|
+
Credentials are loaded in this order (first found wins):
|
|
259
|
+
|
|
260
|
+
1. **Environment variables**: `TELORA_TRACKER_ID` and `TELORA_URL`
|
|
261
|
+
2. **telora-ai database**: `~/.syntelyos/ai_tracking.db` (created by `telora-ai register`)
|
|
262
|
+
|
|
263
|
+
Legacy `TELORA_ACCESS_TOKEN` is still supported but deprecated. Use `TELORA_TRACKER_ID` (UUID) instead.
|
|
264
|
+
|
|
265
|
+
### Authentication Details
|
|
266
|
+
|
|
267
|
+
The MCP server authenticates to the Telora `product-api` edge function using a Profile Tracker ID. This is a UUID associated with your user profile.
|
|
268
|
+
|
|
269
|
+
**To get your Tracker ID:**
|
|
270
|
+
1. Go to Telora > Settings > AI Work Trackers
|
|
271
|
+
2. Click "Generate Tracker ID" on your profile
|
|
272
|
+
3. Copy the UUID
|
|
273
|
+
|
|
274
|
+
**Tracker expiry:** Tracker IDs expire after 90 days of inactivity. Each successful API call auto-refreshes the expiry.
|
|
275
|
+
|
|
276
|
+
See [Authentication Guide](../../docs/AUTHENTICATION.md) for full details.
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// `npx @telora/mcp-products init` -- interactive setup for Telora MCP server
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { createInterface } from "node:readline/promises";
|
|
6
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { callProductApi } from "../shared.js";
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Prompt helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
async function prompt(rl, question, defaultValue) {
|
|
14
|
+
const suffix = defaultValue ? ` (${defaultValue})` : "";
|
|
15
|
+
const answer = await rl.question(`${question}${suffix}: `);
|
|
16
|
+
return answer.trim() || defaultValue || "";
|
|
17
|
+
}
|
|
18
|
+
async function validateToken(creds) {
|
|
19
|
+
const result = await callProductApi(creds, { action: "whoami" });
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
function writeMcpConfig(configPath, trackerId, teloraUrl) {
|
|
23
|
+
let existing = {};
|
|
24
|
+
if (existsSync(configPath)) {
|
|
25
|
+
try {
|
|
26
|
+
existing = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Malformed JSON -- overwrite with fresh config
|
|
30
|
+
existing = {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!existing.mcpServers || typeof existing.mcpServers !== "object") {
|
|
34
|
+
existing.mcpServers = {};
|
|
35
|
+
}
|
|
36
|
+
existing.mcpServers["telora-products"] = {
|
|
37
|
+
command: "npx",
|
|
38
|
+
args: ["-y", "@telora/mcp-products"],
|
|
39
|
+
env: {
|
|
40
|
+
TELORA_TRACKER_ID: trackerId,
|
|
41
|
+
TELORA_URL: teloraUrl,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
// Ensure parent directory exists (for ~/.claude/.mcp.json)
|
|
45
|
+
const dir = join(configPath, "..");
|
|
46
|
+
if (!existsSync(dir)) {
|
|
47
|
+
mkdirSync(dir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Main init flow
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
export async function runInit(argv) {
|
|
55
|
+
const isGlobal = argv.includes("--global");
|
|
56
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
57
|
+
try {
|
|
58
|
+
console.log("\nTelora MCP Server Setup\n");
|
|
59
|
+
const trackerId = await prompt(rl, "Tracker ID");
|
|
60
|
+
if (!trackerId) {
|
|
61
|
+
console.error("Tracker ID is required.");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const teloraUrl = await prompt(rl, "API URL", "https://api.syntelyos.com");
|
|
65
|
+
// Validate token
|
|
66
|
+
console.log("\nValidating tracker ID...");
|
|
67
|
+
const creds = { accessToken: trackerId, teloraUrl };
|
|
68
|
+
let whoami;
|
|
69
|
+
try {
|
|
70
|
+
whoami = await validateToken(creds);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
console.error("\nInvalid tracker ID -- check your token and try again.");
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
// Write config
|
|
77
|
+
const configPath = isGlobal
|
|
78
|
+
? join(homedir(), ".claude", ".mcp.json")
|
|
79
|
+
: join(process.cwd(), ".mcp.json");
|
|
80
|
+
writeMcpConfig(configPath, trackerId, teloraUrl);
|
|
81
|
+
// Success message
|
|
82
|
+
const orgName = whoami.trackerName || whoami.organizationId;
|
|
83
|
+
console.log(`\nConfiguration written to ${configPath}`);
|
|
84
|
+
console.log(`Organization: ${orgName}`);
|
|
85
|
+
if (isGlobal) {
|
|
86
|
+
console.log("(Global config -- applies to all projects)");
|
|
87
|
+
}
|
|
88
|
+
console.log("\nRestart Claude Code to activate the MCP server.");
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
rl.close();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Agent orchestration tool handler (consolidated):
|
|
3
|
+
// telora_agent (role_list | escalate | escalation_list | escalation_get | escalation_update)
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { callProductApi, successResult, validationError, buildFields, wrapHandler, } from "../shared.js";
|
|
7
|
+
export function registerAgentTools(server, getCreds) {
|
|
8
|
+
server.tool("telora_agent", "AI agent orchestration: manage agent roles and human-AI escalation requests. " +
|
|
9
|
+
"Agent roles define capabilities assigned to strategies. Escalations are requests from AI agents to humans when blocked. " +
|
|
10
|
+
"Actions: role_list (list available AI agent roles), escalate (create escalation to human), " +
|
|
11
|
+
"escalation_list (view pending escalations), escalation_get (details), escalation_update (resolve or dismiss).", {
|
|
12
|
+
action: z.enum(["role_list", "escalate", "escalation_list", "escalation_get", "escalation_update"]).describe("Action to perform"),
|
|
13
|
+
escalationId: z.string().uuid().optional().describe("Escalation UUID (required for escalation_get, escalation_update)"),
|
|
14
|
+
issueId: z.string().uuid().optional().describe("Issue UUID being worked on (escalate only)"),
|
|
15
|
+
reasonType: z.enum([
|
|
16
|
+
"decision_needed", "error_encountered", "out_of_scope",
|
|
17
|
+
"blocked_by_external", "needs_clarification", "security_concern",
|
|
18
|
+
]).optional().describe("Type of escalation (required for escalate)"),
|
|
19
|
+
description: z.string().max(5000).optional().describe("What happened and why escalation is needed (required for escalate)"),
|
|
20
|
+
whatWasTried: z.string().max(5000).optional().describe("What approaches were attempted (escalate only)"),
|
|
21
|
+
helpNeeded: z.string().max(5000).optional().describe("Specific help or decision needed from human (escalate only)"),
|
|
22
|
+
status: z.enum(["pending", "in_review", "resolved", "dismissed"]).optional().describe("Escalation status (escalation_list: filter; escalation_update: new status)"),
|
|
23
|
+
resolutionNotes: z.string().max(5000).optional().describe("Resolution notes (escalation_update only)"),
|
|
24
|
+
limit: z.number().int().min(1).max(500).optional().describe("Max results (1-500, default 50)"),
|
|
25
|
+
offset: z.number().int().min(0).optional().describe("Number of results to skip (default 0)"),
|
|
26
|
+
detail: z.enum(["titles", "summary", "full"]).optional().describe("Response detail level"),
|
|
27
|
+
}, wrapHandler(async (params) => {
|
|
28
|
+
switch (params.action) {
|
|
29
|
+
case "role_list": {
|
|
30
|
+
const body = { action: "agent_role_list" };
|
|
31
|
+
if (params.limit !== undefined)
|
|
32
|
+
body.limit = params.limit;
|
|
33
|
+
if (params.offset !== undefined)
|
|
34
|
+
body.offset = params.offset;
|
|
35
|
+
if (params.detail !== undefined)
|
|
36
|
+
body.detail = params.detail;
|
|
37
|
+
const result = await callProductApi(getCreds(), body);
|
|
38
|
+
return successResult({ items: result.roles, totalCount: result.totalCount });
|
|
39
|
+
}
|
|
40
|
+
case "escalate": {
|
|
41
|
+
if (!params.reasonType)
|
|
42
|
+
return validationError("reasonType required for escalate");
|
|
43
|
+
if (!params.description)
|
|
44
|
+
return validationError("description required for escalate");
|
|
45
|
+
const fields = buildFields(params, ['reasonType', 'description', 'issueId', 'whatWasTried', 'helpNeeded']);
|
|
46
|
+
const result = await callProductApi(getCreds(), {
|
|
47
|
+
action: "escalation_create",
|
|
48
|
+
fields,
|
|
49
|
+
});
|
|
50
|
+
return successResult(`Escalation created. A human will review your request.\n\n${JSON.stringify(result.escalation, null, 2)}`);
|
|
51
|
+
}
|
|
52
|
+
case "escalation_list": {
|
|
53
|
+
const fields = {};
|
|
54
|
+
if (params.status !== undefined)
|
|
55
|
+
fields.status = params.status;
|
|
56
|
+
const body = {
|
|
57
|
+
action: "escalation_list",
|
|
58
|
+
fields: Object.keys(fields).length > 0 ? fields : undefined,
|
|
59
|
+
};
|
|
60
|
+
if (params.limit !== undefined)
|
|
61
|
+
body.limit = params.limit;
|
|
62
|
+
if (params.offset !== undefined)
|
|
63
|
+
body.offset = params.offset;
|
|
64
|
+
if (params.detail !== undefined)
|
|
65
|
+
body.detail = params.detail;
|
|
66
|
+
const result = await callProductApi(getCreds(), body);
|
|
67
|
+
return successResult({ items: result.escalations, totalCount: result.totalCount });
|
|
68
|
+
}
|
|
69
|
+
case "escalation_get": {
|
|
70
|
+
if (!params.escalationId)
|
|
71
|
+
return validationError("escalationId required for escalation_get");
|
|
72
|
+
const result = await callProductApi(getCreds(), {
|
|
73
|
+
action: "escalation_get",
|
|
74
|
+
escalationId: params.escalationId,
|
|
75
|
+
});
|
|
76
|
+
return successResult(result.escalation);
|
|
77
|
+
}
|
|
78
|
+
case "escalation_update": {
|
|
79
|
+
if (!params.escalationId)
|
|
80
|
+
return validationError("escalationId required for escalation_update");
|
|
81
|
+
const fields = buildFields({ status: params.status, resolutionNotes: params.resolutionNotes });
|
|
82
|
+
if (Object.keys(fields).length === 0) {
|
|
83
|
+
return validationError("At least one field (status, resolutionNotes) must be provided");
|
|
84
|
+
}
|
|
85
|
+
const result = await callProductApi(getCreds(), {
|
|
86
|
+
action: "escalation_update",
|
|
87
|
+
escalationId: params.escalationId,
|
|
88
|
+
fields,
|
|
89
|
+
});
|
|
90
|
+
return successResult(result.escalation);
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
return validationError(`Unknown action: ${params.action}`);
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=agentHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentHandlers.js","sourceRoot":"","sources":["../../src/handlers/agentHandlers.ts"],"names":[],"mappings":"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"}
|