@pathmode/mcp-server 1.2.2 β 1.3.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 +188 -104
- package/dist/api-client.d.ts +102 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/index.js +237 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,153 +1,237 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @pathmode/mcp-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build structured intent specs through Socratic AI conversation β right in your terminal.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
No signup. No API key. Just add the MCP server and start talking.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Intent Compiler
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The Intent Compiler turns Claude Code into a Socratic product thinking partner. Describe a problem, paste a support ticket, or explain what's broken β Claude challenges vague thinking, asks pointed questions, and builds a structured spec.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
```
|
|
12
|
+
> Help me write an intent spec for our checkout flow
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **Tadas Antanavicius** (PulseMCP) [@tadasant](https://github.com/tadasant)
|
|
16
|
-
- **Toby Padilla** (GitHub) [@toby](https://github.com/toby)
|
|
17
|
-
- **Radoslav (Rado) Dimitrov** (Stacklok) [@rdimitrov](https://github.com/rdimitrov)
|
|
14
|
+
What's broken about it? When you say "checkout flow" β is the whole
|
|
15
|
+
thing failing, or is there one specific moment where users bail?
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
> Payment step times out and users get confused
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
When you say "times out" β is that 5 seconds or 30? And what does
|
|
20
|
+
the user actually see? A spinner? A blank screen? An error?
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
> About 8 seconds, they see a spinner with no feedback
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- **[Pull Requests](https://github.com/modelcontextprotocol/registry/pulls)** - Contribute work towards issues
|
|
24
|
+
Proposed Objective: "Reduce cart abandonment caused by payment step
|
|
25
|
+
timeouts exceeding 3 seconds, where users see a spinner with no
|
|
26
|
+
status feedback or recovery path."
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
Does that capture it, or is there more to the pain?
|
|
29
|
+
```
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
When the spec is ready, Claude saves it as `intent.md` and optionally exports as `.cursorrules` or `CLAUDE.md` β so every AI agent in your project sees the intent as its implementation context.
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
- **Go 1.24.x**
|
|
36
|
-
- **ko** - Container image builder for Go ([installation instructions](https://ko.build/install/))
|
|
37
|
-
- **golangci-lint v2.4.0**
|
|
33
|
+
### Quick Start
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
Add to `.claude/settings.json`:
|
|
40
36
|
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"pathmode": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["@pathmode/mcp-server"]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
Then in Claude Code:
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
```
|
|
51
|
+
> Help me write an intent spec for [your problem here]
|
|
52
|
+
```
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
That's it. No API key needed.
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
<summary>Alternative: Running a pre-built Docker image</summary>
|
|
56
|
+
### What You Get
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
**intent.md** β Structured spec with YAML frontmatter:
|
|
59
|
+
```markdown
|
|
60
|
+
---
|
|
61
|
+
id: "intent_17291..."
|
|
62
|
+
version: 1
|
|
63
|
+
status: "draft"
|
|
64
|
+
---
|
|
65
|
+
# Fix Checkout Payment Timeout
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
## Objective
|
|
68
|
+
Reduce cart abandonment caused by payment step
|
|
69
|
+
timeouts exceeding 3 seconds.
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
|
|
71
|
+
## Outcomes
|
|
72
|
+
- [ ] Payment completes in under 3 seconds (p95)
|
|
73
|
+
- [ ] Users see real-time status during processing
|
|
74
|
+
- [ ] Failed payments show actionable error with retry
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
## Edge Cases
|
|
77
|
+
- **Network timeout during payment**: Show retry button, no double-charge
|
|
78
|
+
- **Unknown provider status**: Hold order, notify user within 30s
|
|
79
|
+
```
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
**.cursorrules** β Agent-directive format for Cursor:
|
|
82
|
+
```
|
|
83
|
+
# CURRENT OBJECTIVE
|
|
84
|
+
You are implementing: "Fix Checkout Payment Timeout"
|
|
85
|
+
|
|
86
|
+
# SUCCESS OUTCOMES
|
|
87
|
+
Your implementation MUST satisfy ALL of these:
|
|
88
|
+
- Payment completes in under 3 seconds (p95)
|
|
89
|
+
- Users see real-time status during processing
|
|
90
|
+
- Failed payments show actionable error with retry
|
|
71
91
|
```
|
|
72
92
|
|
|
73
|
-
**
|
|
74
|
-
- **Releases**: `latest`, `v1.0.0`, `v1.1.0`, etc.
|
|
75
|
-
- **Continuous**: `main` (latest main branch build)
|
|
76
|
-
- **Development**: `main-<date>-<sha>` (specific commit builds)
|
|
93
|
+
**CLAUDE.md** β Appends a `<!-- PATHMODE:START -->` section so Claude Code sees the intent in every conversation.
|
|
77
94
|
|
|
78
|
-
|
|
95
|
+
### Intent Compiler Tools
|
|
79
96
|
|
|
80
|
-
|
|
97
|
+
| Tool | Description |
|
|
98
|
+
|------|-------------|
|
|
99
|
+
| `intent_save` | Save an intent spec to `intent.md` in the project root |
|
|
100
|
+
| `intent_export` | Export as `.cursorrules` or `CLAUDE.md` section |
|
|
81
101
|
|
|
82
|
-
|
|
102
|
+
### Intent Compiler Prompt
|
|
83
103
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
| Prompt | Description |
|
|
105
|
+
|--------|-------------|
|
|
106
|
+
| `compile-intent` | Start a Socratic conversation to build an intent spec |
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
./bin/mcp-publisher --help
|
|
90
|
-
```
|
|
108
|
+
---
|
|
91
109
|
|
|
92
|
-
|
|
110
|
+
## Team Features (API Key Required)
|
|
93
111
|
|
|
94
|
-
|
|
112
|
+
For teams shipping with AI agents, connect to your [Pathmode](https://pathmode.io) workspace for dependency tracking, strategic context, and governance.
|
|
95
113
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
### Setup with API Key
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"pathmode": {
|
|
120
|
+
"command": "npx",
|
|
121
|
+
"args": ["@pathmode/mcp-server"],
|
|
122
|
+
"env": {
|
|
123
|
+
"PATHMODE_API_KEY": "pm_live_..."
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
99
128
|
```
|
|
100
129
|
|
|
101
|
-
|
|
130
|
+
Works with Claude Code (`.claude/settings.json`), Claude Desktop (`claude_desktop_config.json`), and Cursor (`.cursor/mcp.json`).
|
|
102
131
|
|
|
103
|
-
|
|
104
|
-
For Claude and other AI tools: Always prefer make targets over custom commands where possible.
|
|
105
|
-
-->
|
|
132
|
+
Get your API key from **Settings > API Keys** in the [Pathmode app](https://pathmode.io).
|
|
106
133
|
|
|
107
|
-
|
|
134
|
+
### Local Mode (Offline)
|
|
108
135
|
|
|
109
|
-
|
|
136
|
+
Read `intent.md` files from your project directory without an API key:
|
|
110
137
|
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"pathmode": {
|
|
142
|
+
"command": "npx",
|
|
143
|
+
"args": ["@pathmode/mcp-server", "--local"]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
111
147
|
```
|
|
112
|
-
βββ cmd/ # Application entry points
|
|
113
|
-
β βββ publisher/ # Server publishing tool
|
|
114
|
-
βββ data/ # Seed data
|
|
115
|
-
βββ deploy/ # Deployment configuration (Pulumi)
|
|
116
|
-
βββ docs/ # Documentation
|
|
117
|
-
βββ internal/ # Private application code
|
|
118
|
-
β βββ api/ # HTTP handlers and routing
|
|
119
|
-
β βββ auth/ # Authentication (GitHub OAuth, JWT, namespace blocking)
|
|
120
|
-
β βββ config/ # Configuration management
|
|
121
|
-
β βββ database/ # Data persistence (PostgreSQL)
|
|
122
|
-
β βββ service/ # Business logic
|
|
123
|
-
β βββ telemetry/ # Metrics and monitoring
|
|
124
|
-
β βββ validators/ # Input validation
|
|
125
|
-
βββ pkg/ # Public packages
|
|
126
|
-
β βββ api/ # API types and structures
|
|
127
|
-
β β βββ v0/ # Version 0 API types
|
|
128
|
-
β βββ model/ # Data models for server.json
|
|
129
|
-
βββ scripts/ # Development and testing scripts
|
|
130
|
-
βββ tests/ # Integration tests
|
|
131
|
-
βββ tools/ # CLI tools and utilities
|
|
132
|
-
βββ validate-*.sh # Schema validation tools
|
|
133
|
-
```
|
|
134
148
|
|
|
135
|
-
###
|
|
149
|
+
### Configuration
|
|
150
|
+
|
|
151
|
+
| Method | Details |
|
|
152
|
+
|--------|---------|
|
|
153
|
+
| Environment variable | `PATHMODE_API_KEY=pm_live_...` |
|
|
154
|
+
| Config file | `~/.pathmode/config.json` with `apiKey`, `apiUrl`, `workspaceId` |
|
|
155
|
+
| Local mode | `--local` flag β reads `intent.md` and `.pathmode/intents/*.md` |
|
|
156
|
+
| No config | Intent Compiler works without any configuration |
|
|
157
|
+
|
|
158
|
+
### Team Tools
|
|
159
|
+
|
|
160
|
+
#### Intent Management
|
|
161
|
+
|
|
162
|
+
| Tool | Description |
|
|
163
|
+
|------|-------------|
|
|
164
|
+
| `get_current_intent` | Get the active intent (first approved, or most recent) |
|
|
165
|
+
| `get_intent` | Get a single intent by ID with full details |
|
|
166
|
+
| `list_intents` | List all intents, optionally filtered by status |
|
|
167
|
+
| `search_intents` | Search intents by keyword across goals, objectives, and outcomes |
|
|
168
|
+
| `update_intent_status` | Update intent status (draft > validated > approved > shipped > verified) |
|
|
169
|
+
| `log_implementation_note` | Record a technical decision or implementation note |
|
|
170
|
+
|
|
171
|
+
#### Strategic Analysis
|
|
172
|
+
|
|
173
|
+
| Tool | Description |
|
|
174
|
+
|------|-------------|
|
|
175
|
+
| `analyze_intent_graph` | Analyze dependency graph for critical path, cycles, bottlenecks |
|
|
176
|
+
| `get_intent_relations` | Get the dependency graph for a specific intent |
|
|
177
|
+
|
|
178
|
+
#### Context & Export
|
|
179
|
+
|
|
180
|
+
| Tool | Description |
|
|
181
|
+
|------|-------------|
|
|
182
|
+
| `export_context` | Generate CLAUDE.md, .cursorrules, or intent.md files |
|
|
183
|
+
| `get_agent_prompt` | Get a structured execution prompt for an intent |
|
|
184
|
+
| `get_workspace` | Get workspace details including strategy and constitution |
|
|
185
|
+
| `get_constitution` | Get mandatory constraint rules for the workspace |
|
|
186
|
+
|
|
187
|
+
#### Team Prompts
|
|
188
|
+
|
|
189
|
+
| Prompt | Description |
|
|
190
|
+
|--------|-------------|
|
|
191
|
+
| `implement-intent` | Full implementation workflow for a specific intent |
|
|
192
|
+
| `review-risks` | Analyze the intent graph for architectural risks |
|
|
193
|
+
| `what-next` | Suggest the highest-priority intent to work on next |
|
|
194
|
+
|
|
195
|
+
#### Resources
|
|
196
|
+
|
|
197
|
+
| URI | Description |
|
|
198
|
+
|-----|-------------|
|
|
199
|
+
| `intent://current` | Currently active intent |
|
|
200
|
+
| `intent://graph` | Full intent dependency graph |
|
|
201
|
+
| `intent://workspace-strategy` | Workspace vision, principles, and active constitution rules |
|
|
202
|
+
|
|
203
|
+
## Troubleshooting
|
|
204
|
+
|
|
205
|
+
**"No Pathmode configuration found"**
|
|
206
|
+
This no longer causes an error. The Intent Compiler works without any configuration. Team features require an API key.
|
|
207
|
+
|
|
208
|
+
**Tools return "not available in local mode"**
|
|
209
|
+
Most team tools require cloud mode. Set up an API key, or use `--local` for basic intent reading.
|
|
210
|
+
|
|
211
|
+
**Connection timeout**
|
|
212
|
+
Ensure your API key is valid and has the correct scopes. Check your network connection to `pathmode.io`.
|
|
213
|
+
|
|
214
|
+
## Privacy Policy
|
|
215
|
+
|
|
216
|
+
This MCP server connects to the Pathmode API (`pathmode.io`) to read and write intent specifications, workspace data, and constitution rules on behalf of the authenticated user.
|
|
217
|
+
|
|
218
|
+
The **Intent Compiler** works entirely offline β no data is sent to Pathmode servers. Specs are saved locally to your project directory.
|
|
219
|
+
|
|
220
|
+
**Data collected (team features only):** The server transmits your API key for authentication and sends/receives workspace data via the Pathmode API.
|
|
221
|
+
|
|
222
|
+
**Data storage:** The MCP server does not store data locally (except `intent.md` files it creates and in `--local` mode). Persistent data is stored in Pathmode's cloud infrastructure.
|
|
136
223
|
|
|
137
|
-
|
|
138
|
-
- **GitHub OAuth** - For publishing by logging into GitHub
|
|
139
|
-
- **GitHub OIDC** - For publishing from GitHub Actions
|
|
140
|
-
- **DNS verification** - For proving ownership of a domain and its subdomains
|
|
141
|
-
- **HTTP verification** - For proving ownership of a domain
|
|
224
|
+
**Third-party sharing:** No data is shared with third parties. The server communicates exclusively with the Pathmode API.
|
|
142
225
|
|
|
143
|
-
|
|
144
|
-
- `io.github.domdomegg/my-cool-mcp` you must login to GitHub as `domdomegg`, or be in a GitHub Action on domdomegg's repos
|
|
145
|
-
- `me.adamjones/my-cool-mcp` you must prove ownership of `adamjones.me` via DNS or HTTP challenge
|
|
226
|
+
Full privacy policy: [pathmode.io/privacy](https://pathmode.io/privacy)
|
|
146
227
|
|
|
147
|
-
##
|
|
228
|
+
## Links
|
|
148
229
|
|
|
149
|
-
|
|
230
|
+
- [Intent Compiler page](https://pathmode.io/intent-compiler) β Overview and setup guide
|
|
231
|
+
- [Try in browser](https://pathmode.io/sandbox) β Interactive sandbox, no install needed
|
|
232
|
+
- [Pathmode](https://pathmode.io) β Full platform for teams
|
|
233
|
+
- [Issues](https://github.com/pathmodeio/mcp-server/issues)
|
|
150
234
|
|
|
151
|
-
##
|
|
235
|
+
## License
|
|
152
236
|
|
|
153
|
-
|
|
237
|
+
MIT
|
package/dist/api-client.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface PathmodeConfig {
|
|
|
10
10
|
export interface ApiIntent {
|
|
11
11
|
id: string;
|
|
12
12
|
workspaceId: string;
|
|
13
|
+
productId?: string;
|
|
13
14
|
journeyId?: string;
|
|
14
15
|
stageId?: string;
|
|
15
16
|
stageName?: string;
|
|
@@ -26,6 +27,7 @@ export interface ApiIntent {
|
|
|
26
27
|
constraints: string[];
|
|
27
28
|
verification: Record<string, any>;
|
|
28
29
|
externalLinks: any[];
|
|
30
|
+
evidenceAnchors: Record<string, string[]>;
|
|
29
31
|
createdAt: string;
|
|
30
32
|
updatedAt: string;
|
|
31
33
|
shippedAt?: string;
|
|
@@ -41,6 +43,92 @@ export interface ApiIntent {
|
|
|
41
43
|
type: string;
|
|
42
44
|
}[];
|
|
43
45
|
}
|
|
46
|
+
export interface CreateIntentInput {
|
|
47
|
+
title: string;
|
|
48
|
+
objective: string;
|
|
49
|
+
productId: string;
|
|
50
|
+
outcomes?: string[];
|
|
51
|
+
constraints?: string[];
|
|
52
|
+
healthMetrics?: string[];
|
|
53
|
+
edgeCases?: {
|
|
54
|
+
scenario: string;
|
|
55
|
+
expectedBehavior: string;
|
|
56
|
+
}[];
|
|
57
|
+
verification?: {
|
|
58
|
+
manualChecks?: string[];
|
|
59
|
+
unitTests?: string[];
|
|
60
|
+
e2eTests?: string[];
|
|
61
|
+
};
|
|
62
|
+
problemSeverity?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface UpdateIntentInput {
|
|
65
|
+
title?: string;
|
|
66
|
+
objective?: string;
|
|
67
|
+
outcomes?: string[];
|
|
68
|
+
constraints?: string[];
|
|
69
|
+
healthMetrics?: string[];
|
|
70
|
+
edgeCases?: {
|
|
71
|
+
scenario: string;
|
|
72
|
+
expectedBehavior: string;
|
|
73
|
+
}[];
|
|
74
|
+
verification?: {
|
|
75
|
+
manualChecks?: string[];
|
|
76
|
+
unitTests?: string[];
|
|
77
|
+
e2eTests?: string[];
|
|
78
|
+
};
|
|
79
|
+
problemSeverity?: string;
|
|
80
|
+
evidenceAnchors?: Record<string, string[]>;
|
|
81
|
+
}
|
|
82
|
+
export interface EvidenceQuery {
|
|
83
|
+
productId?: string;
|
|
84
|
+
type?: string;
|
|
85
|
+
severity?: string;
|
|
86
|
+
tags?: string;
|
|
87
|
+
search?: string;
|
|
88
|
+
limit?: number;
|
|
89
|
+
}
|
|
90
|
+
export interface CreateEvidenceInput {
|
|
91
|
+
content: string;
|
|
92
|
+
type: string;
|
|
93
|
+
productId: string;
|
|
94
|
+
source?: string;
|
|
95
|
+
sourceUrl?: string;
|
|
96
|
+
severity?: string;
|
|
97
|
+
sentiment?: string;
|
|
98
|
+
tags?: string[];
|
|
99
|
+
stage?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface LinkEvidenceInput {
|
|
102
|
+
link?: string[];
|
|
103
|
+
unlink?: string[];
|
|
104
|
+
}
|
|
105
|
+
export interface ApiVerificationResult {
|
|
106
|
+
pass: boolean;
|
|
107
|
+
score: number;
|
|
108
|
+
results: {
|
|
109
|
+
item: string;
|
|
110
|
+
category: string;
|
|
111
|
+
status: string;
|
|
112
|
+
reasoning: string;
|
|
113
|
+
}[];
|
|
114
|
+
summary: string;
|
|
115
|
+
}
|
|
116
|
+
export interface ApiEvidence {
|
|
117
|
+
id: string;
|
|
118
|
+
productId: string;
|
|
119
|
+
workspaceId: string;
|
|
120
|
+
type: string;
|
|
121
|
+
content: string;
|
|
122
|
+
source?: string;
|
|
123
|
+
sourceUrl?: string;
|
|
124
|
+
severity?: string;
|
|
125
|
+
sentiment?: string;
|
|
126
|
+
tags: string[];
|
|
127
|
+
stage?: string;
|
|
128
|
+
linkedIntentIds: string[];
|
|
129
|
+
createdAt: string;
|
|
130
|
+
updatedAt: string;
|
|
131
|
+
}
|
|
44
132
|
export interface ApiWorkspace {
|
|
45
133
|
id: string;
|
|
46
134
|
name: string;
|
|
@@ -90,4 +178,18 @@ export declare class PathmodeClient {
|
|
|
90
178
|
getConstitution(): Promise<any>;
|
|
91
179
|
exportClaudeMd(): Promise<string>;
|
|
92
180
|
exportContext(format: 'claude-md' | 'cursorrules' | 'intent-md', intentId?: string): Promise<string>;
|
|
181
|
+
createIntent(input: CreateIntentInput): Promise<ApiIntent>;
|
|
182
|
+
updateIntent(id: string, updates: UpdateIntentInput): Promise<ApiIntent>;
|
|
183
|
+
queryEvidence(filters?: EvidenceQuery): Promise<{
|
|
184
|
+
evidence: ApiEvidence[];
|
|
185
|
+
count: number;
|
|
186
|
+
}>;
|
|
187
|
+
createEvidence(input: CreateEvidenceInput): Promise<ApiEvidence>;
|
|
188
|
+
linkEvidence(intentId: string, body: LinkEvidenceInput): Promise<{
|
|
189
|
+
intentId: string;
|
|
190
|
+
evidenceIds: string[];
|
|
191
|
+
linked: number;
|
|
192
|
+
unlinked: number;
|
|
193
|
+
}>;
|
|
194
|
+
verifyImplementation(intentId: string, summary: string, codeChanges?: string): Promise<ApiVerificationResult>;
|
|
93
195
|
}
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;KACrC,GAAG,IAAI,CAAC;IACT,iBAAiB,EAAE;QACf,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;CACP;AAKD,wBAAgB,UAAU,IAAI,cAAc,GAAG,IAAI,CAmBlD;AAED,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,cAAc;YAMpB,KAAK;
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11403,6 +11403,7 @@ class PathmodeClient {
|
|
|
11403
11403
|
}
|
|
11404
11404
|
async fetch(path, options = {}) {
|
|
11405
11405
|
const url = `${this.apiUrl}/api/v1${path}`;
|
|
11406
|
+
console.error(`[pathmode-mcp] fetch: ${url}, key prefix: ${this.apiKey.substring(0, 16)}`);
|
|
11406
11407
|
const response = await fetch(url, {
|
|
11407
11408
|
...options,
|
|
11408
11409
|
headers: {
|
|
@@ -11413,6 +11414,7 @@ class PathmodeClient {
|
|
|
11413
11414
|
});
|
|
11414
11415
|
if (!response.ok) {
|
|
11415
11416
|
const body = await response.json().catch(() => ({ error: response.statusText }));
|
|
11417
|
+
console.error(`[pathmode-mcp] ${response.status}: ${JSON.stringify(body)}, key length: ${this.apiKey.length}`);
|
|
11416
11418
|
throw new Error(`API error (${response.status}): ${body.error || response.statusText}`);
|
|
11417
11419
|
}
|
|
11418
11420
|
return response;
|
|
@@ -11464,6 +11466,52 @@ class PathmodeClient {
|
|
|
11464
11466
|
const res = await this.fetch(`/export?${params.toString()}`);
|
|
11465
11467
|
return res.text();
|
|
11466
11468
|
}
|
|
11469
|
+
// --- Write operations (v1.3.0) ---
|
|
11470
|
+
async createIntent(input) {
|
|
11471
|
+
const res = await this.fetch('/intents', {
|
|
11472
|
+
method: 'POST',
|
|
11473
|
+
body: JSON.stringify(input),
|
|
11474
|
+
});
|
|
11475
|
+
return res.json();
|
|
11476
|
+
}
|
|
11477
|
+
async updateIntent(id, updates) {
|
|
11478
|
+
const res = await this.fetch(`/intents/${id}`, {
|
|
11479
|
+
method: 'PATCH',
|
|
11480
|
+
body: JSON.stringify(updates),
|
|
11481
|
+
});
|
|
11482
|
+
return res.json();
|
|
11483
|
+
}
|
|
11484
|
+
async queryEvidence(filters = {}) {
|
|
11485
|
+
const params = new URLSearchParams();
|
|
11486
|
+
for (const [key, val] of Object.entries(filters)) {
|
|
11487
|
+
if (val !== undefined && val !== null)
|
|
11488
|
+
params.set(key, String(val));
|
|
11489
|
+
}
|
|
11490
|
+
const qs = params.toString();
|
|
11491
|
+
const res = await this.fetch(`/evidence${qs ? `?${qs}` : ''}`);
|
|
11492
|
+
return res.json();
|
|
11493
|
+
}
|
|
11494
|
+
async createEvidence(input) {
|
|
11495
|
+
const res = await this.fetch('/evidence', {
|
|
11496
|
+
method: 'POST',
|
|
11497
|
+
body: JSON.stringify(input),
|
|
11498
|
+
});
|
|
11499
|
+
return res.json();
|
|
11500
|
+
}
|
|
11501
|
+
async linkEvidence(intentId, body) {
|
|
11502
|
+
const res = await this.fetch(`/intents/${intentId}/evidence`, {
|
|
11503
|
+
method: 'POST',
|
|
11504
|
+
body: JSON.stringify(body),
|
|
11505
|
+
});
|
|
11506
|
+
return res.json();
|
|
11507
|
+
}
|
|
11508
|
+
async verifyImplementation(intentId, summary, codeChanges) {
|
|
11509
|
+
const res = await this.fetch(`/intents/${intentId}/verify`, {
|
|
11510
|
+
method: 'POST',
|
|
11511
|
+
body: JSON.stringify({ summary, codeChanges }),
|
|
11512
|
+
});
|
|
11513
|
+
return res.json();
|
|
11514
|
+
}
|
|
11467
11515
|
}
|
|
11468
11516
|
exports.PathmodeClient = PathmodeClient;
|
|
11469
11517
|
|
|
@@ -39709,6 +39757,7 @@ const isLocalMode = process.argv.includes('--local');
|
|
|
39709
39757
|
let client = null;
|
|
39710
39758
|
if (!isLocalMode) {
|
|
39711
39759
|
const config = (0, api_client_1.loadConfig)();
|
|
39760
|
+
console.error(`[pathmode-mcp] API key present: ${!!config?.apiKey}, prefix: ${config?.apiKey?.substring(0, 16) || 'none'}, url: ${config?.apiUrl || 'none'}`);
|
|
39712
39761
|
if (config) {
|
|
39713
39762
|
client = new api_client_1.PathmodeClient(config);
|
|
39714
39763
|
}
|
|
@@ -39719,7 +39768,7 @@ if (!isLocalMode) {
|
|
|
39719
39768
|
// ============================================================
|
|
39720
39769
|
const server = new mcp_js_1.McpServer({
|
|
39721
39770
|
name: 'pathmode',
|
|
39722
|
-
version: '1.
|
|
39771
|
+
version: '1.3.0',
|
|
39723
39772
|
});
|
|
39724
39773
|
// Annotation presets
|
|
39725
39774
|
const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
@@ -40164,6 +40213,179 @@ server.registerTool('log_implementation_note', {
|
|
|
40164
40213
|
}]
|
|
40165
40214
|
};
|
|
40166
40215
|
});
|
|
40216
|
+
server.registerTool('create_intent', {
|
|
40217
|
+
title: 'Create Intent',
|
|
40218
|
+
description: 'Create a new intent spec in the workspace. Requires at minimum a title, objective, and productId. Returns the created intent with its ID. Use list_intents first to see existing intents and avoid duplicates.',
|
|
40219
|
+
inputSchema: {
|
|
40220
|
+
title: zod_1.z.string().describe('Short name for the intent (e.g., "Improve onboarding flow")'),
|
|
40221
|
+
objective: zod_1.z.string().describe('Why this matters β the problem and who has it'),
|
|
40222
|
+
productId: zod_1.z.string().describe('Product (Space) ID this intent belongs to. Use get_workspace to find product IDs.'),
|
|
40223
|
+
outcomes: zod_1.z.array(zod_1.z.string()).optional().describe('Observable, testable state changes'),
|
|
40224
|
+
constraints: zod_1.z.array(zod_1.z.string()).optional().describe('Hard limits the implementation must respect'),
|
|
40225
|
+
healthMetrics: zod_1.z.array(zod_1.z.string()).optional().describe('What to monitor after shipping'),
|
|
40226
|
+
edgeCases: zod_1.z.array(zod_1.z.object({
|
|
40227
|
+
scenario: zod_1.z.string(),
|
|
40228
|
+
expectedBehavior: zod_1.z.string(),
|
|
40229
|
+
})).optional().describe('Failure modes and boundary conditions'),
|
|
40230
|
+
verification: zod_1.z.object({
|
|
40231
|
+
manualChecks: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40232
|
+
unitTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40233
|
+
e2eTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40234
|
+
}).optional().describe('How to confirm it works'),
|
|
40235
|
+
problemSeverity: zod_1.z.enum(['low', 'medium', 'high', 'critical']).optional().describe('How severe the problem is'),
|
|
40236
|
+
},
|
|
40237
|
+
annotations: WRITE_OP,
|
|
40238
|
+
}, async ({ productId, ...rest }) => {
|
|
40239
|
+
if (isLocalMode) {
|
|
40240
|
+
return { content: [{ type: 'text', text: 'Creating intents requires cloud mode. Use PATHMODE_API_KEY to connect.' }] };
|
|
40241
|
+
}
|
|
40242
|
+
const result = await client.createIntent({ productId, ...rest });
|
|
40243
|
+
return {
|
|
40244
|
+
content: [{
|
|
40245
|
+
type: 'text',
|
|
40246
|
+
text: `Intent created: ${result.id}\nTitle: "${result.title}"\nStatus: ${result.status}\nProduct: ${result.productId || productId}`
|
|
40247
|
+
}]
|
|
40248
|
+
};
|
|
40249
|
+
});
|
|
40250
|
+
server.registerTool('update_intent', {
|
|
40251
|
+
title: 'Update Intent',
|
|
40252
|
+
description: "Update an existing intent's content. Provide only the fields you want to change. Does NOT change intent status (use update_intent_status for that).",
|
|
40253
|
+
inputSchema: {
|
|
40254
|
+
intentId: zod_1.z.string().describe('The intent ID to update'),
|
|
40255
|
+
title: zod_1.z.string().optional().describe('New title'),
|
|
40256
|
+
objective: zod_1.z.string().optional().describe('Updated objective'),
|
|
40257
|
+
outcomes: zod_1.z.array(zod_1.z.string()).optional().describe('Replace all outcomes'),
|
|
40258
|
+
constraints: zod_1.z.array(zod_1.z.string()).optional().describe('Replace all constraints'),
|
|
40259
|
+
healthMetrics: zod_1.z.array(zod_1.z.string()).optional().describe('Replace all health metrics'),
|
|
40260
|
+
edgeCases: zod_1.z.array(zod_1.z.object({
|
|
40261
|
+
scenario: zod_1.z.string(),
|
|
40262
|
+
expectedBehavior: zod_1.z.string(),
|
|
40263
|
+
})).optional().describe('Replace all edge cases'),
|
|
40264
|
+
verification: zod_1.z.object({
|
|
40265
|
+
manualChecks: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40266
|
+
unitTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40267
|
+
e2eTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40268
|
+
}).optional().describe('Replace verification plan'),
|
|
40269
|
+
problemSeverity: zod_1.z.enum(['low', 'medium', 'high', 'critical']).optional(),
|
|
40270
|
+
},
|
|
40271
|
+
annotations: { ...WRITE_OP, idempotentHint: true },
|
|
40272
|
+
}, async ({ intentId, ...updates }) => {
|
|
40273
|
+
if (isLocalMode) {
|
|
40274
|
+
return { content: [{ type: 'text', text: 'Updating intents requires cloud mode.' }] };
|
|
40275
|
+
}
|
|
40276
|
+
const result = await client.updateIntent(intentId, updates);
|
|
40277
|
+
const changedFields = Object.keys(updates).filter(k => updates[k] !== undefined);
|
|
40278
|
+
return {
|
|
40279
|
+
content: [{
|
|
40280
|
+
type: 'text',
|
|
40281
|
+
text: `Intent ${intentId} updated. Fields changed: ${changedFields.join(', ')}`
|
|
40282
|
+
}]
|
|
40283
|
+
};
|
|
40284
|
+
});
|
|
40285
|
+
server.registerTool('query_evidence', {
|
|
40286
|
+
title: 'Query Evidence',
|
|
40287
|
+
description: 'Search evidence items (friction points, user quotes, observations, metrics, feature requests) by product, type, severity, or text. Returns matching evidence with IDs that can be linked to intents.',
|
|
40288
|
+
inputSchema: {
|
|
40289
|
+
productId: zod_1.z.string().optional().describe('Filter by product (Space) ID'),
|
|
40290
|
+
type: zod_1.z.enum(['friction', 'quote', 'observation', 'metric', 'request']).optional().describe('Filter by evidence type'),
|
|
40291
|
+
severity: zod_1.z.enum(['low', 'medium', 'high', 'critical']).optional().describe('Filter by severity'),
|
|
40292
|
+
search: zod_1.z.string().optional().describe('Text search across evidence content'),
|
|
40293
|
+
tags: zod_1.z.string().optional().describe('Comma-separated tags to filter by'),
|
|
40294
|
+
limit: zod_1.z.number().optional().describe('Max results (default 50, max 200)'),
|
|
40295
|
+
},
|
|
40296
|
+
annotations: READ_ONLY,
|
|
40297
|
+
}, async (filters) => {
|
|
40298
|
+
if (isLocalMode) {
|
|
40299
|
+
return { content: [{ type: 'text', text: 'Evidence queries require cloud mode.' }] };
|
|
40300
|
+
}
|
|
40301
|
+
const result = await client.queryEvidence(filters);
|
|
40302
|
+
return {
|
|
40303
|
+
content: [{
|
|
40304
|
+
type: 'text',
|
|
40305
|
+
text: JSON.stringify(result, null, 2)
|
|
40306
|
+
}]
|
|
40307
|
+
};
|
|
40308
|
+
});
|
|
40309
|
+
server.registerTool('create_evidence', {
|
|
40310
|
+
title: 'Create Evidence',
|
|
40311
|
+
description: 'Create a new evidence item (e.g., a discovered bug, user feedback quote, behavioral observation, or feature request). Evidence can later be linked to intents to support prioritization.',
|
|
40312
|
+
inputSchema: {
|
|
40313
|
+
content: zod_1.z.string().describe('The evidence content β a finding, quote, or observation'),
|
|
40314
|
+
type: zod_1.z.enum(['friction', 'quote', 'observation', 'metric', 'request']).describe('Type of evidence'),
|
|
40315
|
+
productId: zod_1.z.string().describe('Product (Space) ID this evidence belongs to'),
|
|
40316
|
+
source: zod_1.z.string().optional().describe('Where this evidence came from (e.g., "User interview", "Bug report", "Support ticket")'),
|
|
40317
|
+
sourceUrl: zod_1.z.string().optional().describe('URL to the original source'),
|
|
40318
|
+
severity: zod_1.z.enum(['low', 'medium', 'high', 'critical']).optional().describe('Severity level (required for friction type)'),
|
|
40319
|
+
sentiment: zod_1.z.enum(['positive', 'negative', 'neutral', 'mixed']).optional().describe('Emotional sentiment'),
|
|
40320
|
+
tags: zod_1.z.array(zod_1.z.string()).optional().describe('Category tags (e.g., ["Onboarding", "Performance"])'),
|
|
40321
|
+
stage: zod_1.z.string().optional().describe('User journey stage (e.g., "Discovery", "Checkout")'),
|
|
40322
|
+
},
|
|
40323
|
+
annotations: WRITE_OP,
|
|
40324
|
+
}, async ({ productId, ...rest }) => {
|
|
40325
|
+
if (isLocalMode) {
|
|
40326
|
+
return { content: [{ type: 'text', text: 'Creating evidence requires cloud mode.' }] };
|
|
40327
|
+
}
|
|
40328
|
+
const result = await client.createEvidence({ productId, ...rest });
|
|
40329
|
+
return {
|
|
40330
|
+
content: [{
|
|
40331
|
+
type: 'text',
|
|
40332
|
+
text: `Evidence created: ${result.id}\nType: ${result.type}\nContent: "${(result.content || '').slice(0, 80)}${(result.content || '').length > 80 ? '...' : ''}"`
|
|
40333
|
+
}]
|
|
40334
|
+
};
|
|
40335
|
+
});
|
|
40336
|
+
server.registerTool('link_evidence', {
|
|
40337
|
+
title: 'Link Evidence to Intent',
|
|
40338
|
+
description: 'Link or unlink evidence items to/from an intent. Linking evidence to intents establishes traceability between user problems and planned solutions.',
|
|
40339
|
+
inputSchema: {
|
|
40340
|
+
intentId: zod_1.z.string().describe('The intent ID to link evidence to'),
|
|
40341
|
+
link: zod_1.z.array(zod_1.z.string()).optional().describe('Evidence IDs to link to this intent'),
|
|
40342
|
+
unlink: zod_1.z.array(zod_1.z.string()).optional().describe('Evidence IDs to unlink from this intent'),
|
|
40343
|
+
},
|
|
40344
|
+
annotations: WRITE_OP,
|
|
40345
|
+
}, async ({ intentId, link, unlink }) => {
|
|
40346
|
+
if (isLocalMode) {
|
|
40347
|
+
return { content: [{ type: 'text', text: 'Evidence linking requires cloud mode.' }] };
|
|
40348
|
+
}
|
|
40349
|
+
const result = await client.linkEvidence(intentId, { link, unlink });
|
|
40350
|
+
const actions = [];
|
|
40351
|
+
if (link && link.length > 0)
|
|
40352
|
+
actions.push(`linked ${result.linked} evidence items`);
|
|
40353
|
+
if (unlink && unlink.length > 0)
|
|
40354
|
+
actions.push(`unlinked ${result.unlinked} evidence items`);
|
|
40355
|
+
return {
|
|
40356
|
+
content: [{
|
|
40357
|
+
type: 'text',
|
|
40358
|
+
text: `Intent ${intentId}: ${actions.join(', ')}. Total evidence linked: ${result.evidenceIds.length}`
|
|
40359
|
+
}]
|
|
40360
|
+
};
|
|
40361
|
+
});
|
|
40362
|
+
server.registerTool('verify_implementation', {
|
|
40363
|
+
title: 'Verify Implementation',
|
|
40364
|
+
description: 'AI-grade your implementation against the intent spec. Checks each outcome, constraint, constitution rule, and edge case. Returns pass/fail per item with reasoning and an overall score. Also logs the result as an implementation note.',
|
|
40365
|
+
inputSchema: {
|
|
40366
|
+
intentId: zod_1.z.string().describe('The intent ID to verify against'),
|
|
40367
|
+
summary: zod_1.z.string().describe('Description of what was implemented and how'),
|
|
40368
|
+
codeChanges: zod_1.z.string().optional().describe('Summary of code changes (file list, key modifications)'),
|
|
40369
|
+
},
|
|
40370
|
+
annotations: WRITE_OP,
|
|
40371
|
+
}, async ({ intentId, summary, codeChanges }) => {
|
|
40372
|
+
if (isLocalMode) {
|
|
40373
|
+
return { content: [{ type: 'text', text: 'Verification requires cloud mode.' }] };
|
|
40374
|
+
}
|
|
40375
|
+
try {
|
|
40376
|
+
const result = await client.verifyImplementation(intentId, summary, codeChanges);
|
|
40377
|
+
let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n\n`;
|
|
40378
|
+
text += `${result.summary}\n\n`;
|
|
40379
|
+
for (const r of result.results) {
|
|
40380
|
+
const icon = r.status === 'pass' ? '[PASS]' : r.status === 'fail' ? '[FAIL]' : '[????]';
|
|
40381
|
+
text += `${icon} [${r.category}] ${r.item}\n ${r.reasoning}\n`;
|
|
40382
|
+
}
|
|
40383
|
+
return { content: [{ type: 'text', text }] };
|
|
40384
|
+
}
|
|
40385
|
+
catch (e) {
|
|
40386
|
+
return { content: [{ type: 'text', text: `Verification failed: ${e.message}` }] };
|
|
40387
|
+
}
|
|
40388
|
+
});
|
|
40167
40389
|
// ============================================================
|
|
40168
40390
|
// Prompts
|
|
40169
40391
|
// ============================================================
|
|
@@ -40175,7 +40397,7 @@ server.prompt('implement-intent', 'Get full implementation context for a specifi
|
|
|
40175
40397
|
role: 'user',
|
|
40176
40398
|
content: {
|
|
40177
40399
|
type: 'text',
|
|
40178
|
-
text: `I need to implement intent ${intentId}. Please:\n1. Use the get_agent_prompt tool to fetch the full execution prompt for this intent\n2. Use get_constitution to check for workspace constraints I must respect\n3. Review the intent details and create an implementation plan\n4. After implementation, use update_intent_status to mark it as "shipped"\
|
|
40400
|
+
text: `I need to implement intent ${intentId}. Please:\n1. Use the get_agent_prompt tool to fetch the full execution prompt for this intent\n2. Use get_constitution to check for workspace constraints I must respect\n3. Review the intent details and create an implementation plan\n4. After implementation, use verify_implementation to AI-grade your work against the spec\n5. If verification passes, use update_intent_status to mark it as "shipped"\n6. Use log_implementation_note to document key technical decisions`,
|
|
40179
40401
|
},
|
|
40180
40402
|
}],
|
|
40181
40403
|
};
|
|
@@ -40202,6 +40424,19 @@ server.prompt('what-next', 'Suggest the highest-priority intent to work on next,
|
|
|
40202
40424
|
}],
|
|
40203
40425
|
};
|
|
40204
40426
|
});
|
|
40427
|
+
server.prompt('create-from-evidence', 'Search for evidence items, identify patterns, and create an intent based on the strongest evidence cluster.', {
|
|
40428
|
+
productId: zod_1.z.string().describe('The product ID to search evidence for'),
|
|
40429
|
+
}, async ({ productId }) => {
|
|
40430
|
+
return {
|
|
40431
|
+
messages: [{
|
|
40432
|
+
role: 'user',
|
|
40433
|
+
content: {
|
|
40434
|
+
type: 'text',
|
|
40435
|
+
text: `Help me create a new intent from evidence:\n1. Use query_evidence with productId "${productId}" to see what evidence exists\n2. Look for patterns β multiple friction points about the same issue, or high-severity items\n3. Propose an intent based on the strongest evidence cluster\n4. Use create_intent to create the intent\n5. Use link_evidence to link the relevant evidence items to the new intent`,
|
|
40436
|
+
},
|
|
40437
|
+
}],
|
|
40438
|
+
};
|
|
40439
|
+
});
|
|
40205
40440
|
// ============================================================
|
|
40206
40441
|
// Intent Compiler β Zero-config tools (no API key needed)
|
|
40207
40442
|
// ============================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pathmode/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"mcpName": "io.github.pathmodeio/mcp-server",
|
|
5
5
|
"description": "Pathmode MCP Server β Build structured intent specs through Socratic AI conversation (zero-config), or connect to your Intent Layer for strategic context, dependency graphs, and implementation prompts.",
|
|
6
6
|
"main": "dist/index.js",
|