@kawacode/mcp 5.0.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/CLAUDE.md.example +80 -0
- package/LICENSE +35 -0
- package/README.md +322 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +231 -0
- package/build/index.js.map +1 -0
- package/build/prompts/intent-first-workflow.d.ts +24 -0
- package/build/prompts/intent-first-workflow.js +204 -0
- package/build/prompts/intent-first-workflow.js.map +1 -0
- package/build/resources/active-intent.d.ts +9 -0
- package/build/resources/active-intent.js +52 -0
- package/build/resources/active-intent.js.map +1 -0
- package/build/services/active-intent-store.d.ts +36 -0
- package/build/services/active-intent-store.js +45 -0
- package/build/services/active-intent-store.js.map +1 -0
- package/build/services/kawa-api.d.ts +131 -0
- package/build/services/kawa-api.js +239 -0
- package/build/services/kawa-api.js.map +1 -0
- package/build/services/muninn-ipc.d.ts +45 -0
- package/build/services/muninn-ipc.js +275 -0
- package/build/services/muninn-ipc.js.map +1 -0
- package/build/services/repo-encryption.d.ts +46 -0
- package/build/services/repo-encryption.js +92 -0
- package/build/services/repo-encryption.js.map +1 -0
- package/build/services/storage-decryption.d.ts +52 -0
- package/build/services/storage-decryption.js +162 -0
- package/build/services/storage-decryption.js.map +1 -0
- package/build/tools/assign-blocks.d.ts +87 -0
- package/build/tools/assign-blocks.js +49 -0
- package/build/tools/assign-blocks.js.map +1 -0
- package/build/tools/check-active-intent.d.ts +50 -0
- package/build/tools/check-active-intent.js +48 -0
- package/build/tools/check-active-intent.js.map +1 -0
- package/build/tools/complete-intent.d.ts +48 -0
- package/build/tools/complete-intent.js +53 -0
- package/build/tools/complete-intent.js.map +1 -0
- package/build/tools/create-intent.d.ts +58 -0
- package/build/tools/create-intent.js +49 -0
- package/build/tools/create-intent.js.map +1 -0
- package/build/tools/detect-intent-conflicts.d.ts +361 -0
- package/build/tools/detect-intent-conflicts.js +91 -0
- package/build/tools/detect-intent-conflicts.js.map +1 -0
- package/build/tools/edit-session-decision.d.ts +201 -0
- package/build/tools/edit-session-decision.js +50 -0
- package/build/tools/edit-session-decision.js.map +1 -0
- package/build/tools/evolve-decisions.d.ts +50 -0
- package/build/tools/evolve-decisions.js +45 -0
- package/build/tools/evolve-decisions.js.map +1 -0
- package/build/tools/get-intent-changes.d.ts +49 -0
- package/build/tools/get-intent-changes.js +58 -0
- package/build/tools/get-intent-changes.js.map +1 -0
- package/build/tools/get-intents-for-file.d.ts +57 -0
- package/build/tools/get-intents-for-file.js +57 -0
- package/build/tools/get-intents-for-file.js.map +1 -0
- package/build/tools/get-intents-for-lines.d.ts +71 -0
- package/build/tools/get-intents-for-lines.js +64 -0
- package/build/tools/get-intents-for-lines.js.map +1 -0
- package/build/tools/get-project-context.d.ts +82 -0
- package/build/tools/get-project-context.js +73 -0
- package/build/tools/get-project-context.js.map +1 -0
- package/build/tools/get-project-decisions.d.ts +51 -0
- package/build/tools/get-project-decisions.js +56 -0
- package/build/tools/get-project-decisions.js.map +1 -0
- package/build/tools/get-relevant-context.d.ts +89 -0
- package/build/tools/get-relevant-context.js +104 -0
- package/build/tools/get-relevant-context.js.map +1 -0
- package/build/tools/get-session-decisions.d.ts +57 -0
- package/build/tools/get-session-decisions.js +48 -0
- package/build/tools/get-session-decisions.js.map +1 -0
- package/build/tools/index.d.ts +656 -0
- package/build/tools/index.js +57 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/infer-history.d.ts +85 -0
- package/build/tools/infer-history.js +69 -0
- package/build/tools/infer-history.js.map +1 -0
- package/build/tools/list-team-intents.d.ts +51 -0
- package/build/tools/list-team-intents.js +57 -0
- package/build/tools/list-team-intents.js.map +1 -0
- package/build/tools/log-work.d.ts +45 -0
- package/build/tools/log-work.js +30 -0
- package/build/tools/log-work.js.map +1 -0
- package/build/tools/record-decision.d.ts +132 -0
- package/build/tools/record-decision.js +66 -0
- package/build/tools/record-decision.js.map +1 -0
- package/build/tools/resolve-origin.d.ts +13 -0
- package/build/tools/resolve-origin.js +33 -0
- package/build/tools/resolve-origin.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
<!-- Replace with a 1-2 sentence description of your project -->
|
|
8
|
+
[Your project name] is a [brief description of what it does].
|
|
9
|
+
|
|
10
|
+
## AI Code Implementation Workflow
|
|
11
|
+
|
|
12
|
+
**BEFORE exploring code or reading files** for any non-trivial task, follow these steps in order:
|
|
13
|
+
|
|
14
|
+
1. **Check active intent**: Call `check_active_intent` (kawa-intents MCP) to see if work is already tracked
|
|
15
|
+
2. **Get relevant context**: Call `get_relevant_context` with a description of the task to find past decisions and related intents that may inform your approach
|
|
16
|
+
3. **Then explore code**: Now read files, search the codebase, and analyze the problem
|
|
17
|
+
|
|
18
|
+
For trivial one-line fixes (typos, obvious bugs), skip the above and use `log_work` after completing the change. For everything else — especially bug fixes from issues, multi-file changes, or unfamiliar code — always start with steps 1-2.
|
|
19
|
+
|
|
20
|
+
**Recording decisions before commit**: When the user asks to finalize/commit, review the work done in the session and call `record_decision` for each significant decision or lesson *before* creating the commit. Apply a **high bar**: a decision is worth recording only if a future developer (or Claude in a future session) would genuinely benefit from knowing it — i.e., it would change how they approach the same area of code.
|
|
21
|
+
|
|
22
|
+
Record when you:
|
|
23
|
+
- Chose between meaningful alternatives (type: `fork`) — e.g., serde alias vs fixing all reconstruction sites
|
|
24
|
+
- Discovered non-obvious behavior that will recur or affect future work (type: `discovery`) — e.g., UI progress tracking requires completion events per phase
|
|
25
|
+
- Identified a hard constraint that future work must respect (type: `constraint`) — e.g., checkpoint cleanup must wait for persistence
|
|
26
|
+
- Made an explicit trade-off with lasting impact (type: `tradeoff`) — e.g., precision vs simplicity in rate limiting
|
|
27
|
+
- Tried and rejected an approach that looked reasonable (type: `abandoned`)
|
|
28
|
+
- Selected a library or dependency after comparing alternatives (type: `dependency`) — e.g., chose `reqwest` over `hyper` for HTTP
|
|
29
|
+
|
|
30
|
+
Do NOT record:
|
|
31
|
+
- Routine refactors, obvious bug fixes, version bumps, formatting changes
|
|
32
|
+
- Session-only debugging artifacts (e.g., a stray `test.only` or `console.log` that was removed)
|
|
33
|
+
- Anything where the "lesson" is obvious in hindsight or already clear from the code/diff
|
|
34
|
+
- Gotchas with no future recurrence risk (one-off typos, copy-paste errors, trivial config mistakes)
|
|
35
|
+
- Decisions with no meaningful alternatives considered
|
|
36
|
+
|
|
37
|
+
**Committing pre-existing changes**: When uncommitted changes exist that weren't made under an active intent, infer intents retroactively: read the diffs, group changes by semantic purpose, call `list_team_intents` to find existing intents that accurately match each group, then commit each group under its matched intent (create a new intent if no accurate match found). Present the grouping plan to the user before committing. Use `log_work` for trivial standalone changes.
|
|
38
|
+
|
|
39
|
+
## Repository Origin and Path
|
|
40
|
+
|
|
41
|
+
Use these values for ALL MCP tool calls:
|
|
42
|
+
|
|
43
|
+
<!-- Replace with your actual values -->
|
|
44
|
+
- `repoOrigin`: `git@github.com:your-org/your-repo.git`
|
|
45
|
+
- `repoPath`: `/absolute/path/to/your-repo`
|
|
46
|
+
|
|
47
|
+
**Important**: `repoPath` must point to the directory containing the `.git` folder.
|
|
48
|
+
|
|
49
|
+
<!-- ============================================================
|
|
50
|
+
EVERYTHING BELOW IS OPTIONAL — add what's useful for your project
|
|
51
|
+
============================================================ -->
|
|
52
|
+
|
|
53
|
+
<!-- OPTIONAL: For monorepos or multi-project workspaces, replace the
|
|
54
|
+
single repoOrigin/repoPath above with a table:
|
|
55
|
+
|
|
56
|
+
### Repository Origins and Paths
|
|
57
|
+
|
|
58
|
+
Each sub-project has its own `.git` directory. When calling MCP tools, use the **sub-project path** (not the parent directory) as `repoPath`:
|
|
59
|
+
|
|
60
|
+
| Sub-project | `repoOrigin` | `repoPath` |
|
|
61
|
+
|-------------|-----------------------------------------|----------------------------------|
|
|
62
|
+
| my-api | `git@github.com:my-org/my-api.git` | `/path/to/workspace/my-api` |
|
|
63
|
+
| my-frontend | `git@github.com:my-org/my-frontend.git` | `/path/to/workspace/my-frontend` |
|
|
64
|
+
-->
|
|
65
|
+
|
|
66
|
+
<!-- OPTIONAL: Add project-specific sections as needed.
|
|
67
|
+
Examples of what to include:
|
|
68
|
+
|
|
69
|
+
## Development Commands
|
|
70
|
+
- How to run tests, lint, build, etc.
|
|
71
|
+
|
|
72
|
+
## Code Style
|
|
73
|
+
- Project conventions Claude should follow
|
|
74
|
+
|
|
75
|
+
## Architecture
|
|
76
|
+
- Key architectural decisions or patterns
|
|
77
|
+
|
|
78
|
+
## Important Files
|
|
79
|
+
- Files Claude should know about
|
|
80
|
+
-->
|
package/LICENSE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Code Awareness Source Available License (CASAL) v1.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Code Awareness LLC
|
|
4
|
+
|
|
5
|
+
Permission is granted to use, copy, modify, and run this
|
|
6
|
+
software for personal use, research, or internal organizational
|
|
7
|
+
use when interacting with Code Awareness tools.
|
|
8
|
+
|
|
9
|
+
You may:
|
|
10
|
+
|
|
11
|
+
• Run the software locally
|
|
12
|
+
• Modify the software for internal purposes
|
|
13
|
+
• Study the source code
|
|
14
|
+
• Submit contributions
|
|
15
|
+
|
|
16
|
+
You may NOT:
|
|
17
|
+
|
|
18
|
+
• Use this software to build or operate a competing
|
|
19
|
+
AI memory, intent-tracking, or development governance system.
|
|
20
|
+
|
|
21
|
+
• Offer this software or derivatives as a hosted service.
|
|
22
|
+
|
|
23
|
+
• Redistribute this software as part of a commercial product
|
|
24
|
+
without written permission from Code Awareness LLC.
|
|
25
|
+
|
|
26
|
+
PATENT RIGHTS
|
|
27
|
+
|
|
28
|
+
This license does not grant rights to any patents owned by
|
|
29
|
+
Code Awareness LLC except as necessary to use the software
|
|
30
|
+
under this license.
|
|
31
|
+
|
|
32
|
+
DISCLAIMER
|
|
33
|
+
|
|
34
|
+
The software is provided "as is", without warranty of any kind.
|
|
35
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# kawa.mcp
|
|
2
|
+
|
|
3
|
+
Reference implementation of the Kawa Code MCP protocol.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Kawa Code MCP server provides the communication layer used by
|
|
8
|
+
Kawa Code to record and align development intent between
|
|
9
|
+
developers and AI systems.
|
|
10
|
+
|
|
11
|
+
It enables:
|
|
12
|
+
|
|
13
|
+
• Persistent AI reasoning context
|
|
14
|
+
• Intent tracking during development workflows
|
|
15
|
+
• Alignment between human and AI decisions over time
|
|
16
|
+
|
|
17
|
+
This repository contains the reference implementation of the
|
|
18
|
+
Kawa MCP server used by Kawa Code tools.
|
|
19
|
+
|
|
20
|
+
This MCP server enables AI coding assistants to understand what you're working on and maintain context across sessions. It connects to the Kawa Code desktop application to provide:
|
|
21
|
+
|
|
22
|
+
- **Intent tracking**: Create and manage development intents with decision history
|
|
23
|
+
- **Team collaboration**: See what teammates are working on, detect conflicts
|
|
24
|
+
- **Decision recording**: Track architectural decisions and trade-offs with constraint validation
|
|
25
|
+
- **Code block assignment**: Associate code changes with intents for better commit history
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
The MCP server works together with Kawa Code, AI code generators such as Cursor, Claude Code,
|
|
30
|
+
and the Kawa Code extensions.
|
|
31
|
+
|
|
32
|
+
## Key Features
|
|
33
|
+
|
|
34
|
+
- **Context Persistence**: Never lose track of what you were working on across AI sessions
|
|
35
|
+
- **Smart Context Retrieval**: Relevance-based context loading - only fetch what's needed for the current task
|
|
36
|
+
- **Zero-Knowledge Encryption**: Code blocks encrypted client-side before cloud sync, API cannot decrypt
|
|
37
|
+
- **Team Conflict Detection**: Know when teammates are working on the same files/lines
|
|
38
|
+
- **Decision Tracking**: Record architectural decisions with constraint validation and conflict detection
|
|
39
|
+
- **Commit Integration**: Link all code changes to intent context for better git history
|
|
40
|
+
- **Cross-Platform**: Works with Claude Code and Cursor AI via MCP protocol
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
### Required
|
|
45
|
+
|
|
46
|
+
- **Node.js >= 18.0.0** — runtime for the MCP server
|
|
47
|
+
- **[Kawa Code](https://codeawareness.com/product) desktop app running** — kawa.mcp is a thin MCP-to-IPC adapter; all git operations, storage, and API communication happen in Kawa Code
|
|
48
|
+
- **Active Kawa Code account** — for cloud sync and team features
|
|
49
|
+
|
|
50
|
+
### Optional (for history inference)
|
|
51
|
+
|
|
52
|
+
- **Anthropic API key** — your own Claude API key, passed as a parameter to the inference tools
|
|
53
|
+
- **[GitHub CLI (`gh`)](https://cli.github.com/)** — enables richer data tiers (PR descriptions, review comments, issue discussions). Without `gh`, tiers 2 and 4 are skipped automatically
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Clone the repository (if not already cloned)
|
|
59
|
+
cd /path/to/kawa.mcp
|
|
60
|
+
|
|
61
|
+
# Install dependencies
|
|
62
|
+
npm install
|
|
63
|
+
|
|
64
|
+
# Build the TypeScript source
|
|
65
|
+
npm run build
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
1. **Start Kawa Code**: Launch the Kawa Code desktop app and log in
|
|
71
|
+
2. **Configure MCP**: Add kawa.mcp to your AI assistant's MCP configuration (see Configuration section)
|
|
72
|
+
3. **Restart AI**: Restart Claude Code or Cursor to load the MCP server
|
|
73
|
+
4. **Test connection**: The server will try to connect to Kawa Code on startup
|
|
74
|
+
5. **Start coding**: Use `check_active_intent` to begin tracking your work
|
|
75
|
+
|
|
76
|
+
## Setting Up CLAUDE.md
|
|
77
|
+
|
|
78
|
+
For Claude Code to use the MCP tools effectively, your project needs a `CLAUDE.md` file that tells Claude *when* to call the tools and provides your repository coordinates.
|
|
79
|
+
|
|
80
|
+
Copy the example template into your project root and fill in the placeholders:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cp /path/to/kawa.mcp/CLAUDE.md.example /path/to/your-project/CLAUDE.md
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or just merge the example with your own content.
|
|
87
|
+
See [`CLAUDE.md.example`](./CLAUDE.md.example) for the full template with optional sections for monorepos, code style, and architecture.
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### Claude Code
|
|
92
|
+
|
|
93
|
+
Create a `.mcp.json` file in your project root (recommended for teams — commit it to git):
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"kawa-intents": {
|
|
99
|
+
"type": "stdio",
|
|
100
|
+
"command": "node",
|
|
101
|
+
"args": ["/absolute/path/to/kawa.mcp/build/index.js"]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Or add it at user level (available across all your projects):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
claude mcp add --transport stdio kawa-intents --scope user -- node /absolute/path/to/kawa.mcp/build/index.js
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Cursor AI
|
|
114
|
+
|
|
115
|
+
Add to your Cursor MCP configuration (`~/.cursor/mcp.json`):
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"kawa-intents": {
|
|
121
|
+
"command": "node",
|
|
122
|
+
"args": ["/absolute/path/to/kawa.mcp/build/index.js"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Important:** Use absolute paths, not relative paths or `~` shortcuts.
|
|
129
|
+
|
|
130
|
+
## Available Tools
|
|
131
|
+
|
|
132
|
+
### Context & Discovery
|
|
133
|
+
|
|
134
|
+
| Tool | Description |
|
|
135
|
+
|------------------------|-----------------------------------------|
|
|
136
|
+
| `get_relevant_context` | Get context relevant to a specific task |
|
|
137
|
+
|
|
138
|
+
### Intent Management
|
|
139
|
+
|
|
140
|
+
| Tool | Description |
|
|
141
|
+
|------------------------------|------------------------------------------------------------|
|
|
142
|
+
| `check_active_intent` | Check if there's an active intent before starting new work |
|
|
143
|
+
| `create_and_activate_intent` | Create and activate a new intent for a development task |
|
|
144
|
+
| `get_intents_for_file` | Get intents (team and self) affecting a specific file |
|
|
145
|
+
| `get_intents_for_lines` | Get intents affecting specific line ranges in a file |
|
|
146
|
+
| `assign_blocks_to_intent` | Assign modified line ranges to the active intent |
|
|
147
|
+
| `get_intent_changes` | Get uncommitted changes for the active intent |
|
|
148
|
+
| `complete_intent` | Complete an intent (committed/done/abandoned) |
|
|
149
|
+
| `list_team_intents` | List what teammates are currently working on |
|
|
150
|
+
|
|
151
|
+
### Decision Recording
|
|
152
|
+
|
|
153
|
+
| Tool | Description |
|
|
154
|
+
|---------------------------|---------------------------------------------------------------------------|
|
|
155
|
+
| `record_decision` | Record an architectural decision with rationale and constraint validation |
|
|
156
|
+
| `get_session_decisions` | Get decisions recorded during the current session |
|
|
157
|
+
| `get_project_decisions` | Get all decisions across all intents for the project |
|
|
158
|
+
| `edit_session_decision` | Edit or delete a decision before intent completion |
|
|
159
|
+
| `detect_intent_conflicts` | Detect if current intent decisions conflict with team decisions |
|
|
160
|
+
|
|
161
|
+
### History Inference
|
|
162
|
+
|
|
163
|
+
| Tool | Description |
|
|
164
|
+
|--------------------|------------------------------------------------------------------------|
|
|
165
|
+
| `infer_history` | Analyze git commit history to extract development stories and decisions |
|
|
166
|
+
| `evolve_decisions` | Build a decision evolution graph from previously extracted stories |
|
|
167
|
+
|
|
168
|
+
### Lightweight Logging
|
|
169
|
+
|
|
170
|
+
| Tool | Description |
|
|
171
|
+
|------------|------------------------------------------------------------------------------------------------|
|
|
172
|
+
| `log_work` | Log completed work without the full intent lifecycle — use for quick fixes and trivial changes |
|
|
173
|
+
|
|
174
|
+
## MCP Capabilities
|
|
175
|
+
|
|
176
|
+
### Prompts
|
|
177
|
+
|
|
178
|
+
The server exposes prompts that can be loaded into your AI coding session:
|
|
179
|
+
|
|
180
|
+
- **`implementation_workflow`**: Standard workflow for implementing code changes with intent tracking. Provides step-by-step guidance on checking for active intents, creating new intents, checking for conflicts, and assigning blocks.
|
|
181
|
+
|
|
182
|
+
### Resources
|
|
183
|
+
|
|
184
|
+
The server exposes resources that can be monitored:
|
|
185
|
+
|
|
186
|
+
- **`kawa://intent/active`**: Real-time view of the currently active intent for the connected repository (JSON format)
|
|
187
|
+
|
|
188
|
+
## History Inference
|
|
189
|
+
|
|
190
|
+
Two MCP tools analyze git commit history to extract structured development knowledge — useful for bootstrapping a repository with historical context.
|
|
191
|
+
|
|
192
|
+
### `infer_history`
|
|
193
|
+
|
|
194
|
+
Runs the full pipeline automatically: **infer → evolve → persist**.
|
|
195
|
+
|
|
196
|
+
1. **Pass 1**: Groups commits into coherent development stories with value hints (high/low/none)
|
|
197
|
+
2. **Pass 2**: Deep analysis of high/low-value stories to extract architectural decisions and lessons learned
|
|
198
|
+
3. **Evolution**: Curates decisions by finding relationships (supersedes, reinforces, contradicts, specializes)
|
|
199
|
+
4. **Persist**: Stores curated stories as intents with decisions and lessons (auto-syncs to cloud)
|
|
200
|
+
|
|
201
|
+
The pipeline runs asynchronously inside Kawa Code. Progress is shown in the Kawa Code desktop app via a progress bar. The pipeline supports checkpointing — if interrupted, re-running resumes from where it left off.
|
|
202
|
+
|
|
203
|
+
**Usage in Claude Code:**
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
Use the infer_history tool with estimateOnly: true to preview the cost first,
|
|
207
|
+
then run it with estimateOnly: false.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Parameters:**
|
|
211
|
+
|
|
212
|
+
| Parameter | Type | Default | Description |
|
|
213
|
+
|------------------------|---------|----------------------------|------------------------------------------------------------------------|
|
|
214
|
+
| `repoPath` | string | *(required)* | Local path to the repository root |
|
|
215
|
+
| `apiKey` | string | *(required)* | Your Anthropic API key |
|
|
216
|
+
| `commits` | number | 50 | Number of recent commits to analyze |
|
|
217
|
+
| `tier` | number | 4 | Data enrichment tier (1-5, see below) |
|
|
218
|
+
| `model` | string | claude-sonnet-4-20250514 | Anthropic model to use |
|
|
219
|
+
| `maxStories` | number | 0 | Limit stories to analyze in Pass 2 (0 = unlimited) |
|
|
220
|
+
| `allowCommitSplitting` | boolean | false | Allow splitting a commit into multiple stories when it contains unrelated changes (recommended for repos with messy commit history) |
|
|
221
|
+
| `contextIssues` | boolean | false | Include context issues from commit date range (tier 4 only) |
|
|
222
|
+
| `estimateOnly` | boolean | false | Preview token cost without running the pipeline |
|
|
223
|
+
|
|
224
|
+
### `evolve_decisions`
|
|
225
|
+
|
|
226
|
+
Builds a decision evolution graph from previously extracted stories — identifying how decisions relate across stories over time. Note: `infer_history` already chains evolve + persist automatically. Use this tool only if you want to run evolution separately on a pre-existing set of stories.
|
|
227
|
+
|
|
228
|
+
1. **Bucketing**: Groups stories by file overlap and keyword similarity
|
|
229
|
+
2. **Edge classification**: Uses LLM to identify relationships (supersedes, reinforces, contradicts, specializes)
|
|
230
|
+
3. **Annotation**: Labels each decision as stable, orphan, evolved, or abandoned
|
|
231
|
+
4. **Curation**: Keeps stable + orphan decisions, drops evolved + abandoned
|
|
232
|
+
|
|
233
|
+
If `repoPath` is provided, curated stories are automatically persisted as intents with decisions and lessons after evolution completes.
|
|
234
|
+
|
|
235
|
+
**Parameters:**
|
|
236
|
+
|
|
237
|
+
| Parameter | Type | Default | Description |
|
|
238
|
+
|--------------|--------|-------------------------------|--------------------------------------------------------------------|
|
|
239
|
+
| `stories` | array | *(required)* | Story objects from a previous `infer_history` run |
|
|
240
|
+
| `apiKey` | string | *(required)* | Your Anthropic API key |
|
|
241
|
+
| `model` | string | claude-haiku-4-5-20251001 | Anthropic model (cheaper model recommended) |
|
|
242
|
+
| `repoPath` | string | *(optional)* | Local path to repository root (required for auto-persist) |
|
|
243
|
+
| `repoOrigin` | string | *(optional)* | Git remote origin URL (auto-detected from repoPath if not provided)|
|
|
244
|
+
|
|
245
|
+
### Data Tiers
|
|
246
|
+
|
|
247
|
+
Each tier adds more context for better inference. Higher tiers require the [`gh` CLI](https://cli.github.com/) authenticated.
|
|
248
|
+
|
|
249
|
+
| Tier | Data source | Requires `gh` |
|
|
250
|
+
|------|----------------------------------------------------|---------------|
|
|
251
|
+
| 1 | Commit messages + numstat | No |
|
|
252
|
+
| 2 | + PR descriptions and review comments | Yes |
|
|
253
|
+
| 3 | + Diffs for revert commits | No |
|
|
254
|
+
| 4 | + Referenced GitHub issues (default) | Yes |
|
|
255
|
+
| 5 | + Diffs for all commits with annotation extraction | No |
|
|
256
|
+
|
|
257
|
+
## Development
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
# Watch mode (auto-rebuild on file changes)
|
|
261
|
+
npm run dev
|
|
262
|
+
|
|
263
|
+
# Build TypeScript to JavaScript
|
|
264
|
+
npm run build
|
|
265
|
+
|
|
266
|
+
# Clean build artifacts
|
|
267
|
+
npm run clean
|
|
268
|
+
|
|
269
|
+
# Run the MCP server directly
|
|
270
|
+
npm start
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Testing the MCP Server
|
|
274
|
+
|
|
275
|
+
To test the MCP server without integrating it into an AI assistant:
|
|
276
|
+
|
|
277
|
+
1. Build the project: `npm run build`
|
|
278
|
+
2. Run the server: `npm start`
|
|
279
|
+
3. The server communicates via stdio (standard input/output)
|
|
280
|
+
4. You can send MCP protocol messages via stdin to test tool functionality
|
|
281
|
+
|
|
282
|
+
### Development Tips
|
|
283
|
+
|
|
284
|
+
- Use `npm run dev` to auto-rebuild during development
|
|
285
|
+
- Check stderr for server logs (stdout is reserved for MCP protocol)
|
|
286
|
+
- Ensure Kawa Code is running before testing
|
|
287
|
+
|
|
288
|
+
## Architecture
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
Claude Code / Cursor AI
|
|
292
|
+
↓ MCP Protocol (stdio)
|
|
293
|
+
kawa.mcp (this server)
|
|
294
|
+
↓ Huginn IPC (Unix socket / Named pipe)
|
|
295
|
+
Kawa Code Desktop App
|
|
296
|
+
├─ Gardener Module (Rust)
|
|
297
|
+
│ └─ Intent/Decision storage
|
|
298
|
+
└─ HTTP Client
|
|
299
|
+
↓ REST + SSE
|
|
300
|
+
Kawa API (cloud)
|
|
301
|
+
└─ Team sync & encryption
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The MCP server communicates with Kawa Code using the Huginn IPC protocol:
|
|
305
|
+
- **Context queries**: Intents, decisions, relevant context
|
|
306
|
+
- **Intent operations**: Create, update, assign blocks, complete
|
|
307
|
+
- **Decision tracking**: Record, retrieve, edit, conflict detection
|
|
308
|
+
|
|
309
|
+
Kawa Code's Gardener module handles all git operations, diff generation, and local storage of encrypted data.
|
|
310
|
+
|
|
311
|
+
## Contributing
|
|
312
|
+
|
|
313
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTION.md) and [CLA.md](CLA.md).
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
This project is source-available under the
|
|
318
|
+
Kawa Code Source Available License.
|
|
319
|
+
|
|
320
|
+
You may run and modify the software for personal or internal use.
|
|
321
|
+
|
|
322
|
+
See [LICENSE](LICENSE) for details.
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { connectToMuninn, ensureRepo } from './services/muninn-ipc.js';
|
|
6
|
+
import { allTools, getRelevantContext, checkActiveIntent, createAndActivateIntent, getIntentsForFile, getIntentsForLines, assignBlocksToIntent, listTeamIntents, getIntentChanges, completeIntent, logWork, recordDecision, getSessionDecisions, getProjectDecisions, editSessionDecision, detectIntentConflicts, inferHistory, evolveDecisions } from './tools/index.js';
|
|
7
|
+
import { prompts } from './prompts/intent-first-workflow.js';
|
|
8
|
+
import { resources, readActiveIntentResource } from './resources/active-intent.js';
|
|
9
|
+
// Create MCP server
|
|
10
|
+
const server = new Server({
|
|
11
|
+
name: 'kawa-intents',
|
|
12
|
+
version: '0.3.0'
|
|
13
|
+
}, {
|
|
14
|
+
capabilities: {
|
|
15
|
+
tools: {},
|
|
16
|
+
prompts: {},
|
|
17
|
+
resources: {}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// Handle tool listing
|
|
21
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
22
|
+
return {
|
|
23
|
+
tools: allTools.map(tool => ({
|
|
24
|
+
name: tool.name,
|
|
25
|
+
description: tool.description,
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: Object.fromEntries(Object.entries(tool.inputSchema.shape).map(([key, value]) => [
|
|
29
|
+
key,
|
|
30
|
+
{
|
|
31
|
+
...getZodSchema(value),
|
|
32
|
+
description: value._def?.description || ''
|
|
33
|
+
}
|
|
34
|
+
])),
|
|
35
|
+
required: Object.entries(tool.inputSchema.shape)
|
|
36
|
+
.filter(([_, value]) => isRequired(value))
|
|
37
|
+
.map(([key]) => key)
|
|
38
|
+
}
|
|
39
|
+
}))
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
// Handle tool calls
|
|
43
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
44
|
+
const { name, arguments: args } = request.params;
|
|
45
|
+
try {
|
|
46
|
+
const repoPath = args?.repoPath;
|
|
47
|
+
if (repoPath) {
|
|
48
|
+
await ensureRepo(repoPath);
|
|
49
|
+
}
|
|
50
|
+
let result;
|
|
51
|
+
switch (name) {
|
|
52
|
+
case 'get_relevant_context':
|
|
53
|
+
result = await getRelevantContext(args);
|
|
54
|
+
break;
|
|
55
|
+
case 'check_active_intent':
|
|
56
|
+
result = await checkActiveIntent(args);
|
|
57
|
+
break;
|
|
58
|
+
case 'create_and_activate_intent':
|
|
59
|
+
result = await createAndActivateIntent(args);
|
|
60
|
+
break;
|
|
61
|
+
case 'get_intents_for_file':
|
|
62
|
+
result = await getIntentsForFile(args);
|
|
63
|
+
break;
|
|
64
|
+
case 'get_intents_for_lines':
|
|
65
|
+
result = await getIntentsForLines(args);
|
|
66
|
+
break;
|
|
67
|
+
case 'assign_blocks_to_intent':
|
|
68
|
+
result = await assignBlocksToIntent(args);
|
|
69
|
+
break;
|
|
70
|
+
case 'list_team_intents':
|
|
71
|
+
result = await listTeamIntents(args);
|
|
72
|
+
break;
|
|
73
|
+
case 'get_intent_changes':
|
|
74
|
+
result = await getIntentChanges(args);
|
|
75
|
+
break;
|
|
76
|
+
case 'complete_intent':
|
|
77
|
+
result = await completeIntent(args);
|
|
78
|
+
break;
|
|
79
|
+
case 'log_work':
|
|
80
|
+
result = await logWork(args);
|
|
81
|
+
break;
|
|
82
|
+
case 'record_decision':
|
|
83
|
+
result = await recordDecision(args);
|
|
84
|
+
break;
|
|
85
|
+
case 'get_session_decisions':
|
|
86
|
+
result = await getSessionDecisions(args);
|
|
87
|
+
break;
|
|
88
|
+
case 'get_project_decisions':
|
|
89
|
+
result = await getProjectDecisions(args);
|
|
90
|
+
break;
|
|
91
|
+
case 'edit_session_decision':
|
|
92
|
+
result = await editSessionDecision(args);
|
|
93
|
+
break;
|
|
94
|
+
case 'detect_intent_conflicts':
|
|
95
|
+
result = await detectIntentConflicts(args);
|
|
96
|
+
break;
|
|
97
|
+
case 'infer_history':
|
|
98
|
+
result = await inferHistory(args);
|
|
99
|
+
break;
|
|
100
|
+
case 'evolve_decisions':
|
|
101
|
+
result = await evolveDecisions(args);
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
content: [
|
|
108
|
+
{
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: JSON.stringify(result, null, 2)
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
const message = error instanceof Error ? error.message : 'Tool execution failed';
|
|
117
|
+
throw new McpError(ErrorCode.InternalError, message);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Handle prompt listing
|
|
121
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
122
|
+
return {
|
|
123
|
+
prompts: prompts.map(p => ({
|
|
124
|
+
name: p.name,
|
|
125
|
+
description: p.description,
|
|
126
|
+
arguments: p.arguments
|
|
127
|
+
}))
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
// Handle prompt retrieval
|
|
131
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
132
|
+
const { name, arguments: args } = request.params;
|
|
133
|
+
const prompt = prompts.find(p => p.name === name);
|
|
134
|
+
if (!prompt) {
|
|
135
|
+
throw new McpError(ErrorCode.InvalidRequest, `Unknown prompt: ${name}`);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
description: prompt.description,
|
|
139
|
+
messages: [
|
|
140
|
+
{
|
|
141
|
+
role: 'user',
|
|
142
|
+
content: {
|
|
143
|
+
type: 'text',
|
|
144
|
+
text: prompt.getPrompt(args)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
// Handle resource listing
|
|
151
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
152
|
+
return {
|
|
153
|
+
resources: resources.map(r => ({
|
|
154
|
+
uri: r.uri,
|
|
155
|
+
name: r.name,
|
|
156
|
+
description: r.description,
|
|
157
|
+
mimeType: r.mimeType
|
|
158
|
+
}))
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
// Handle resource reading
|
|
162
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
163
|
+
const { uri } = request.params;
|
|
164
|
+
if (uri === 'kawa://intent/active') {
|
|
165
|
+
const content = await readActiveIntentResource();
|
|
166
|
+
return {
|
|
167
|
+
contents: [
|
|
168
|
+
{
|
|
169
|
+
uri,
|
|
170
|
+
mimeType: 'application/json',
|
|
171
|
+
text: content
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
throw new McpError(ErrorCode.InvalidRequest, `Unknown resource: ${uri}`);
|
|
177
|
+
});
|
|
178
|
+
// Helper to convert Zod types to JSON Schema property objects
|
|
179
|
+
function getZodSchema(zodType) {
|
|
180
|
+
const typeName = zodType._def?.typeName;
|
|
181
|
+
switch (typeName) {
|
|
182
|
+
case 'ZodString':
|
|
183
|
+
return { type: 'string' };
|
|
184
|
+
case 'ZodNumber':
|
|
185
|
+
return { type: 'number' };
|
|
186
|
+
case 'ZodBoolean':
|
|
187
|
+
return { type: 'boolean' };
|
|
188
|
+
case 'ZodArray':
|
|
189
|
+
return { type: 'array', items: getZodSchema(zodType._def.type) };
|
|
190
|
+
case 'ZodObject':
|
|
191
|
+
return { type: 'object' };
|
|
192
|
+
case 'ZodEnum':
|
|
193
|
+
return { type: 'string', enum: zodType._def.values };
|
|
194
|
+
case 'ZodOptional':
|
|
195
|
+
case 'ZodDefault':
|
|
196
|
+
return getZodSchema(zodType._def.innerType);
|
|
197
|
+
case 'ZodAny':
|
|
198
|
+
case 'ZodUnknown':
|
|
199
|
+
case 'ZodRecord':
|
|
200
|
+
return { type: 'object' };
|
|
201
|
+
default:
|
|
202
|
+
return { type: 'string' };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function isRequired(zodType) {
|
|
206
|
+
const typeName = zodType._def?.typeName;
|
|
207
|
+
return typeName !== 'ZodOptional' && typeName !== 'ZodDefault';
|
|
208
|
+
}
|
|
209
|
+
// Main entry point
|
|
210
|
+
async function main() {
|
|
211
|
+
// Log to stderr (stdout is reserved for MCP protocol)
|
|
212
|
+
console.error('Kawa Intents MCP Server starting (Muninn IPC mode)...');
|
|
213
|
+
// Connect to Muninn before starting MCP transport
|
|
214
|
+
try {
|
|
215
|
+
await connectToMuninn();
|
|
216
|
+
console.error('Connected to Muninn');
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.error(`Warning: ${err.message}`);
|
|
220
|
+
console.error('MCP server will start but tools will fail until Muninn is running.');
|
|
221
|
+
}
|
|
222
|
+
// Start the stdio transport
|
|
223
|
+
const transport = new StdioServerTransport();
|
|
224
|
+
await server.connect(transport);
|
|
225
|
+
console.error('Kawa Intents MCP Server running');
|
|
226
|
+
}
|
|
227
|
+
main().catch((error) => {
|
|
228
|
+
console.error('Fatal error:', error);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=index.js.map
|