hive-mcp-server 1.0.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 +115 -0
- package/dist/db.d.ts +36 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +164 -0
- package/dist/db.js.map +1 -0
- package/dist/embed.d.ts +14 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +83 -0
- package/dist/embed.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +55 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/plan.d.ts +5 -0
- package/dist/tools/plan.d.ts.map +1 -0
- package/dist/tools/plan.js +246 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/session.d.ts +5 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +201 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# @studioraming/hive-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for AI dev session logs, development plans, and semantic search. Built on Supabase pgvector.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **14 MCP tools** — Session tracking (start/log/end/list/read/search), Plan management (create/update/read/list/check/archive), Index (read/current)
|
|
8
|
+
- **Semantic search** — Hybrid vector + full-text search with RRF fusion via pgvector
|
|
9
|
+
- **Multi-agent** — Works with Claude Code, Codex CLI, Gemini CLI, Cursor
|
|
10
|
+
- **Auto-embedding** — Automatically embeds session logs and plans using OpenAI `text-embedding-3-small` (dim=512)
|
|
11
|
+
|
|
12
|
+
## Quick Setup
|
|
13
|
+
|
|
14
|
+
### 1. Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g @studioraming/hive-mcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Configure Claude Code
|
|
21
|
+
|
|
22
|
+
Add to your project's `.claude/mcp.json`:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"mcpServers": {
|
|
27
|
+
"hive": {
|
|
28
|
+
"command": "hive-mcp",
|
|
29
|
+
"env": {
|
|
30
|
+
"SUPABASE_URL": "https://your-project.supabase.co",
|
|
31
|
+
"SUPABASE_SERVICE_ROLE_KEY": "your-service-role-key",
|
|
32
|
+
"OPENAI_API_KEY": "sk-...",
|
|
33
|
+
"HIVE_TEAM_ID": "your-team-uuid",
|
|
34
|
+
"HIVE_PROJECT_ID": "my-project"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 3. Or use npx (no install)
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"hive": {
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["-y", "@studioraming/hive-mcp"],
|
|
49
|
+
"env": {
|
|
50
|
+
"SUPABASE_URL": "https://your-project.supabase.co",
|
|
51
|
+
"SUPABASE_SERVICE_ROLE_KEY": "your-service-role-key",
|
|
52
|
+
"OPENAI_API_KEY": "sk-...",
|
|
53
|
+
"HIVE_TEAM_ID": "your-team-uuid",
|
|
54
|
+
"HIVE_PROJECT_ID": "my-project"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Environment Variables
|
|
62
|
+
|
|
63
|
+
| Variable | Required | Description |
|
|
64
|
+
| --------------------------- | -------- | ------------------------------------ |
|
|
65
|
+
| `SUPABASE_URL` | Yes | Supabase project URL |
|
|
66
|
+
| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Supabase service role key |
|
|
67
|
+
| `OPENAI_API_KEY` | Yes | OpenAI API key (for embeddings) |
|
|
68
|
+
| `HIVE_TEAM_ID` | Yes | Team UUID from Hive |
|
|
69
|
+
| `HIVE_PROJECT_ID` | No | Project identifier (default: `hive`) |
|
|
70
|
+
|
|
71
|
+
## Database Setup
|
|
72
|
+
|
|
73
|
+
Apply the migration to your Supabase project. See `supabase/migrations/013_dev_logs_semantic.sql` in the [Hive repo](https://github.com/StudioRaming/hive).
|
|
74
|
+
|
|
75
|
+
This creates:
|
|
76
|
+
|
|
77
|
+
- `dev_sessions` — Session logs with atomic sequence numbers
|
|
78
|
+
- `dev_plans` — 3-doc plans (plan/context/checklist) with version history
|
|
79
|
+
- `memory_chunks` — pgvector(512) embeddings for semantic search
|
|
80
|
+
- `hybrid_search_sessions` — RRF-fused vector + full-text search RPC
|
|
81
|
+
|
|
82
|
+
## Tools
|
|
83
|
+
|
|
84
|
+
### Session Tools
|
|
85
|
+
|
|
86
|
+
| Tool | Description |
|
|
87
|
+
| ---------------- | ---------------------------------------------- |
|
|
88
|
+
| `session_start` | Start a new dev session (auto-seq, auto-embed) |
|
|
89
|
+
| `session_log` | Append steps and files to an active session |
|
|
90
|
+
| `session_end` | End session with result, embed full summary |
|
|
91
|
+
| `session_list` | List recent sessions |
|
|
92
|
+
| `session_read` | Read session by ID or seq number |
|
|
93
|
+
| `session_search` | Semantic + full-text hybrid search |
|
|
94
|
+
|
|
95
|
+
### Plan Tools
|
|
96
|
+
|
|
97
|
+
| Tool | Description |
|
|
98
|
+
| -------------- | -------------------------------------------- |
|
|
99
|
+
| `plan_create` | Create a 3-doc plan (plan/context/checklist) |
|
|
100
|
+
| `plan_update` | Update a specific document |
|
|
101
|
+
| `plan_read` | Read plan docs |
|
|
102
|
+
| `plan_list` | List plans with progress stats |
|
|
103
|
+
| `plan_check` | Toggle checklist items |
|
|
104
|
+
| `plan_archive` | Archive or delete a plan |
|
|
105
|
+
|
|
106
|
+
### Index Tools
|
|
107
|
+
|
|
108
|
+
| Tool | Description |
|
|
109
|
+
| --------------- | -------------------------------------- |
|
|
110
|
+
| `index_read` | Session index (like .session-index.md) |
|
|
111
|
+
| `index_current` | Current active session |
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
import type { ServerConfig, DevSession, DevPlan, MemoryChunk, HybridSearchResult } from './types.js';
|
|
3
|
+
export declare function getSupabase(config: ServerConfig): SupabaseClient;
|
|
4
|
+
export declare function nextSeq(db: SupabaseClient, teamId: string, projectId: string): Promise<number>;
|
|
5
|
+
export declare function insertSession(db: SupabaseClient, session: Omit<DevSession, 'id' | 'ended_at'>): Promise<DevSession>;
|
|
6
|
+
export declare function updateSession(db: SupabaseClient, id: string, updates: Partial<DevSession>): Promise<DevSession>;
|
|
7
|
+
export declare function getSession(db: SupabaseClient, teamId: string, projectId: string, idOrSeq: string | number): Promise<DevSession | null>;
|
|
8
|
+
export declare function listSessions(db: SupabaseClient, teamId: string, projectId: string, opts: {
|
|
9
|
+
limit?: number;
|
|
10
|
+
offset?: number;
|
|
11
|
+
status?: string;
|
|
12
|
+
}): Promise<DevSession[]>;
|
|
13
|
+
export declare function hybridSearchSessions(db: SupabaseClient, queryText: string, queryEmbedding: number[], teamId: string, projectId: string | null, limit: number): Promise<HybridSearchResult[]>;
|
|
14
|
+
export declare function insertPlan(db: SupabaseClient, plan: Omit<DevPlan, 'id' | 'version' | 'created_at' | 'updated_at'>): Promise<DevPlan>;
|
|
15
|
+
export declare function updatePlan(db: SupabaseClient, teamId: string, projectId: string, slug: string, updates: Partial<DevPlan>): Promise<DevPlan>;
|
|
16
|
+
export declare function getPlan(db: SupabaseClient, teamId: string, projectId: string, slug: string): Promise<DevPlan | null>;
|
|
17
|
+
export declare function listPlans(db: SupabaseClient, teamId: string, projectId: string, opts: {
|
|
18
|
+
status?: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
}): Promise<DevPlan[]>;
|
|
21
|
+
export declare function deletePlan(db: SupabaseClient, teamId: string, projectId: string, slug: string): Promise<void>;
|
|
22
|
+
export declare function upsertChunks(db: SupabaseClient, chunks: Omit<MemoryChunk, 'id' | 'created_at'>[]): Promise<void>;
|
|
23
|
+
export declare function matchChunks(db: SupabaseClient, queryEmbedding: number[], opts: {
|
|
24
|
+
matchCount?: number;
|
|
25
|
+
teamId?: string;
|
|
26
|
+
project?: string;
|
|
27
|
+
category?: string;
|
|
28
|
+
}): Promise<Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
content: string;
|
|
31
|
+
category: string;
|
|
32
|
+
source_id: string;
|
|
33
|
+
metadata: Record<string, unknown>;
|
|
34
|
+
similarity: number;
|
|
35
|
+
}>>;
|
|
36
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createClient } from '@supabase/supabase-js';
|
|
2
|
+
let client = null;
|
|
3
|
+
export function getSupabase(config) {
|
|
4
|
+
if (!client) {
|
|
5
|
+
client = createClient(config.supabaseUrl, config.supabaseServiceKey, {
|
|
6
|
+
auth: { persistSession: false },
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
return client;
|
|
10
|
+
}
|
|
11
|
+
// Atomic sequence generation
|
|
12
|
+
export async function nextSeq(db, teamId, projectId) {
|
|
13
|
+
const { data, error } = await db.rpc('next_dev_session_seq', {
|
|
14
|
+
p_team_id: teamId,
|
|
15
|
+
p_project_id: projectId,
|
|
16
|
+
});
|
|
17
|
+
if (error)
|
|
18
|
+
throw new Error(`Failed to get next seq: ${error.message}`);
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
// === Sessions ===
|
|
22
|
+
export async function insertSession(db, session) {
|
|
23
|
+
const { data, error } = await db.from('dev_sessions').insert(session).select().single();
|
|
24
|
+
if (error)
|
|
25
|
+
throw new Error(`Failed to insert session: ${error.message}`);
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
export async function updateSession(db, id, updates) {
|
|
29
|
+
const { data, error } = await db
|
|
30
|
+
.from('dev_sessions')
|
|
31
|
+
.update(updates)
|
|
32
|
+
.eq('id', id)
|
|
33
|
+
.select()
|
|
34
|
+
.single();
|
|
35
|
+
if (error)
|
|
36
|
+
throw new Error(`Failed to update session: ${error.message}`);
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
export async function getSession(db, teamId, projectId, idOrSeq) {
|
|
40
|
+
let query = db.from('dev_sessions').select('*');
|
|
41
|
+
if (typeof idOrSeq === 'number') {
|
|
42
|
+
query = query.eq('team_id', teamId).eq('project_id', projectId).eq('seq', idOrSeq);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
query = query.eq('id', idOrSeq);
|
|
46
|
+
}
|
|
47
|
+
const { data, error } = await query.single();
|
|
48
|
+
if (error)
|
|
49
|
+
return null;
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
export async function listSessions(db, teamId, projectId, opts) {
|
|
53
|
+
let query = db
|
|
54
|
+
.from('dev_sessions')
|
|
55
|
+
.select('*')
|
|
56
|
+
.eq('team_id', teamId)
|
|
57
|
+
.eq('project_id', projectId)
|
|
58
|
+
.order('seq', { ascending: false })
|
|
59
|
+
.range(opts.offset ?? 0, (opts.offset ?? 0) + (opts.limit ?? 20) - 1);
|
|
60
|
+
if (opts.status) {
|
|
61
|
+
query = query.eq('status', opts.status);
|
|
62
|
+
}
|
|
63
|
+
const { data, error } = await query;
|
|
64
|
+
if (error)
|
|
65
|
+
throw new Error(`Failed to list sessions: ${error.message}`);
|
|
66
|
+
return data ?? [];
|
|
67
|
+
}
|
|
68
|
+
export async function hybridSearchSessions(db, queryText, queryEmbedding, teamId, projectId, limit) {
|
|
69
|
+
const { data, error } = await db.rpc('hybrid_search_sessions', {
|
|
70
|
+
query_text: queryText,
|
|
71
|
+
query_embedding: JSON.stringify(queryEmbedding),
|
|
72
|
+
p_team_id: teamId,
|
|
73
|
+
p_project_id: projectId,
|
|
74
|
+
result_limit: limit,
|
|
75
|
+
});
|
|
76
|
+
if (error)
|
|
77
|
+
throw new Error(`Hybrid search failed: ${error.message}`);
|
|
78
|
+
return data ?? [];
|
|
79
|
+
}
|
|
80
|
+
// === Plans ===
|
|
81
|
+
export async function insertPlan(db, plan) {
|
|
82
|
+
const { data, error } = await db.from('dev_plans').insert(plan).select().single();
|
|
83
|
+
if (error)
|
|
84
|
+
throw new Error(`Failed to insert plan: ${error.message}`);
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
export async function updatePlan(db, teamId, projectId, slug, updates) {
|
|
88
|
+
const { data, error } = await db
|
|
89
|
+
.from('dev_plans')
|
|
90
|
+
.update({ ...updates, updated_at: new Date().toISOString() })
|
|
91
|
+
.eq('team_id', teamId)
|
|
92
|
+
.eq('project_id', projectId)
|
|
93
|
+
.eq('slug', slug)
|
|
94
|
+
.select()
|
|
95
|
+
.single();
|
|
96
|
+
if (error)
|
|
97
|
+
throw new Error(`Failed to update plan: ${error.message}`);
|
|
98
|
+
return data;
|
|
99
|
+
}
|
|
100
|
+
export async function getPlan(db, teamId, projectId, slug) {
|
|
101
|
+
const { data, error } = await db
|
|
102
|
+
.from('dev_plans')
|
|
103
|
+
.select('*')
|
|
104
|
+
.eq('team_id', teamId)
|
|
105
|
+
.eq('project_id', projectId)
|
|
106
|
+
.eq('slug', slug)
|
|
107
|
+
.single();
|
|
108
|
+
if (error)
|
|
109
|
+
return null;
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
export async function listPlans(db, teamId, projectId, opts) {
|
|
113
|
+
let query = db
|
|
114
|
+
.from('dev_plans')
|
|
115
|
+
.select('*')
|
|
116
|
+
.eq('team_id', teamId)
|
|
117
|
+
.eq('project_id', projectId)
|
|
118
|
+
.order('updated_at', { ascending: false })
|
|
119
|
+
.limit(opts.limit ?? 20);
|
|
120
|
+
if (opts.status) {
|
|
121
|
+
query = query.eq('status', opts.status);
|
|
122
|
+
}
|
|
123
|
+
const { data, error } = await query;
|
|
124
|
+
if (error)
|
|
125
|
+
throw new Error(`Failed to list plans: ${error.message}`);
|
|
126
|
+
return data ?? [];
|
|
127
|
+
}
|
|
128
|
+
export async function deletePlan(db, teamId, projectId, slug) {
|
|
129
|
+
const { error } = await db
|
|
130
|
+
.from('dev_plans')
|
|
131
|
+
.delete()
|
|
132
|
+
.eq('team_id', teamId)
|
|
133
|
+
.eq('project_id', projectId)
|
|
134
|
+
.eq('slug', slug);
|
|
135
|
+
if (error)
|
|
136
|
+
throw new Error(`Failed to delete plan: ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
// === Memory Chunks ===
|
|
139
|
+
export async function upsertChunks(db, chunks) {
|
|
140
|
+
// Delete existing chunks for same source
|
|
141
|
+
if (chunks.length > 0 && chunks[0].source_id) {
|
|
142
|
+
await db.from('memory_chunks').delete().eq('source_id', chunks[0].source_id);
|
|
143
|
+
}
|
|
144
|
+
const rows = chunks.map((c) => ({
|
|
145
|
+
...c,
|
|
146
|
+
embedding: JSON.stringify(c.embedding),
|
|
147
|
+
}));
|
|
148
|
+
const { error } = await db.from('memory_chunks').insert(rows);
|
|
149
|
+
if (error)
|
|
150
|
+
throw new Error(`Failed to upsert chunks: ${error.message}`);
|
|
151
|
+
}
|
|
152
|
+
export async function matchChunks(db, queryEmbedding, opts) {
|
|
153
|
+
const { data, error } = await db.rpc('match_chunks', {
|
|
154
|
+
query_embedding: JSON.stringify(queryEmbedding),
|
|
155
|
+
match_count: opts.matchCount ?? 10,
|
|
156
|
+
filter_team_id: opts.teamId ?? null,
|
|
157
|
+
filter_project: opts.project ?? null,
|
|
158
|
+
filter_category: opts.category ?? null,
|
|
159
|
+
});
|
|
160
|
+
if (error)
|
|
161
|
+
throw new Error(`Match chunks failed: ${error.message}`);
|
|
162
|
+
return data ?? [];
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/embed.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function initEmbedder(key: string): void;
|
|
2
|
+
/** Generate embedding for a single text */
|
|
3
|
+
export declare function embed(text: string): Promise<number[]>;
|
|
4
|
+
/** Generate embeddings for multiple texts in a single API call */
|
|
5
|
+
export declare function embedBatch(texts: string[]): Promise<number[][]>;
|
|
6
|
+
/** Split text into chunks suitable for embedding */
|
|
7
|
+
export declare function chunkText(text: string, maxChars?: number): string[];
|
|
8
|
+
/** Embed text with automatic chunking, returns array of {content, embedding} */
|
|
9
|
+
export declare function embedWithChunking(text: string): Promise<Array<{
|
|
10
|
+
content: string;
|
|
11
|
+
embedding: number[];
|
|
12
|
+
chunkIndex: number;
|
|
13
|
+
}>>;
|
|
14
|
+
//# sourceMappingURL=embed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,2CAA2C;AAC3C,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG3D;AAED,kEAAkE;AAClE,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAgCrE;AAED,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAkB,GAAG,MAAM,EAAE,CA+B5E;AAED,gFAAgF;AAChF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAS9E"}
|
package/dist/embed.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const OPENAI_EMBED_URL = 'https://api.openai.com/v1/embeddings';
|
|
2
|
+
const MODEL = 'text-embedding-3-small';
|
|
3
|
+
const DIMENSIONS = 512;
|
|
4
|
+
const MAX_CHUNK_CHARS = 2000;
|
|
5
|
+
let apiKey = null;
|
|
6
|
+
export function initEmbedder(key) {
|
|
7
|
+
apiKey = key;
|
|
8
|
+
}
|
|
9
|
+
/** Generate embedding for a single text */
|
|
10
|
+
export async function embed(text) {
|
|
11
|
+
const results = await embedBatch([text]);
|
|
12
|
+
return results[0];
|
|
13
|
+
}
|
|
14
|
+
/** Generate embeddings for multiple texts in a single API call */
|
|
15
|
+
export async function embedBatch(texts) {
|
|
16
|
+
if (!apiKey)
|
|
17
|
+
throw new Error('OpenAI API key not configured');
|
|
18
|
+
if (texts.length === 0)
|
|
19
|
+
return [];
|
|
20
|
+
// Truncate texts that exceed reasonable length
|
|
21
|
+
const truncated = texts.map((t) => t.slice(0, 8000));
|
|
22
|
+
const response = await fetch(OPENAI_EMBED_URL, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
Authorization: `Bearer ${apiKey}`,
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
model: MODEL,
|
|
30
|
+
input: truncated,
|
|
31
|
+
dimensions: DIMENSIONS,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const errBody = await response.text();
|
|
36
|
+
throw new Error(`OpenAI embedding failed (${response.status}): ${errBody}`);
|
|
37
|
+
}
|
|
38
|
+
const json = (await response.json());
|
|
39
|
+
// Sort by index to preserve order
|
|
40
|
+
const sorted = json.data.sort((a, b) => a.index - b.index);
|
|
41
|
+
return sorted.map((d) => d.embedding);
|
|
42
|
+
}
|
|
43
|
+
/** Split text into chunks suitable for embedding */
|
|
44
|
+
export function chunkText(text, maxChars = MAX_CHUNK_CHARS) {
|
|
45
|
+
if (text.length <= maxChars)
|
|
46
|
+
return [text];
|
|
47
|
+
const chunks = [];
|
|
48
|
+
let pos = 0;
|
|
49
|
+
while (pos < text.length) {
|
|
50
|
+
let end = Math.min(pos + maxChars, text.length);
|
|
51
|
+
// Try to break at paragraph boundary
|
|
52
|
+
if (end < text.length) {
|
|
53
|
+
const lastParagraph = text.lastIndexOf('\n\n', end);
|
|
54
|
+
if (lastParagraph > pos + maxChars * 0.3) {
|
|
55
|
+
end = lastParagraph + 2;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Fall back to newline
|
|
59
|
+
const lastNewline = text.lastIndexOf('\n', end);
|
|
60
|
+
if (lastNewline > pos + maxChars * 0.3) {
|
|
61
|
+
end = lastNewline + 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const chunk = text.slice(pos, end).trim();
|
|
66
|
+
if (chunk.length > 0) {
|
|
67
|
+
chunks.push(chunk);
|
|
68
|
+
}
|
|
69
|
+
pos = end;
|
|
70
|
+
}
|
|
71
|
+
return chunks;
|
|
72
|
+
}
|
|
73
|
+
/** Embed text with automatic chunking, returns array of {content, embedding} */
|
|
74
|
+
export async function embedWithChunking(text) {
|
|
75
|
+
const chunks = chunkText(text);
|
|
76
|
+
const embeddings = await embedBatch(chunks);
|
|
77
|
+
return chunks.map((content, i) => ({
|
|
78
|
+
content,
|
|
79
|
+
embedding: embeddings[i],
|
|
80
|
+
chunkIndex: i,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { FastMCP } from 'fastmcp';
|
|
3
|
+
import { getSupabase } from './db.js';
|
|
4
|
+
import { initEmbedder } from './embed.js';
|
|
5
|
+
import { registerSessionTools } from './tools/session.js';
|
|
6
|
+
import { registerPlanTools } from './tools/plan.js';
|
|
7
|
+
import { registerIndexTools } from './tools/index.js';
|
|
8
|
+
function getConfig() {
|
|
9
|
+
const required = (key) => {
|
|
10
|
+
const val = process.env[key];
|
|
11
|
+
if (!val)
|
|
12
|
+
throw new Error(`Missing env: ${key}`);
|
|
13
|
+
return val;
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
supabaseUrl: required('SUPABASE_URL'),
|
|
17
|
+
supabaseServiceKey: required('SUPABASE_SERVICE_ROLE_KEY'),
|
|
18
|
+
openaiApiKey: required('OPENAI_API_KEY'),
|
|
19
|
+
teamId: required('HIVE_TEAM_ID'),
|
|
20
|
+
projectId: process.env['HIVE_PROJECT_ID'] ?? 'hive',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const config = getConfig();
|
|
24
|
+
const db = getSupabase(config);
|
|
25
|
+
initEmbedder(config.openaiApiKey);
|
|
26
|
+
const server = new FastMCP({
|
|
27
|
+
name: 'hive',
|
|
28
|
+
version: '1.0.0',
|
|
29
|
+
});
|
|
30
|
+
// Register all 14 tools
|
|
31
|
+
registerSessionTools(server, db, config);
|
|
32
|
+
registerPlanTools(server, db, config);
|
|
33
|
+
registerIndexTools(server, db, config);
|
|
34
|
+
// Start with stdio transport
|
|
35
|
+
server.start({ transportType: 'stdio' });
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAGrD,SAAS,SAAS;IAChB,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAU,EAAE;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAA;QAChD,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;IAED,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC;QACrC,kBAAkB,EAAE,QAAQ,CAAC,2BAA2B,CAAC;QACzD,YAAY,EAAE,QAAQ,CAAC,gBAAgB,CAAC;QACxC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC;QAChC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM;KACpD,CAAA;AACH,CAAC;AAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;AAC1B,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;AAC9B,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;AAEjC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,OAAO;CACjB,CAAC,CAAA;AAEF,wBAAwB;AACxB,oBAAoB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AACxC,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AACrC,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AAEtC,6BAA6B;AAC7B,MAAM,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FastMCP } from 'fastmcp';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
import type { ServerConfig } from '../types.js';
|
|
4
|
+
export declare function registerIndexTools(server: FastMCP, db: SupabaseClient, config: ServerConfig): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG/C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,QAyD3F"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listSessions } from '../db.js';
|
|
3
|
+
export function registerIndexTools(server, db, config) {
|
|
4
|
+
// === index_read ===
|
|
5
|
+
server.addTool({
|
|
6
|
+
name: 'index_read',
|
|
7
|
+
description: 'Read the session index — recent sessions formatted like .session-index.md',
|
|
8
|
+
parameters: z.object({
|
|
9
|
+
limit: z.number().default(30).describe('How many sessions to include'),
|
|
10
|
+
}),
|
|
11
|
+
execute: async (args) => {
|
|
12
|
+
const sessions = await listSessions(db, config.teamId, config.projectId, {
|
|
13
|
+
limit: args.limit,
|
|
14
|
+
});
|
|
15
|
+
const lines = [`# idx`, `P: ${config.projectId} | Hive MCP`, ''];
|
|
16
|
+
// Sessions are in DESC order, reverse for display
|
|
17
|
+
const reversed = [...sessions].reverse();
|
|
18
|
+
for (const s of reversed) {
|
|
19
|
+
const prefix = s.status === 'active' ? 'C: ' : '';
|
|
20
|
+
const resultTag = s.result ? ` [${s.result}]` : s.status === 'active' ? ' [active]' : '';
|
|
21
|
+
lines.push(`${prefix}#${s.seq} ${s.type} ${s.short_desc}${resultTag}`);
|
|
22
|
+
}
|
|
23
|
+
return lines.join('\n');
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
// === index_current ===
|
|
27
|
+
server.addTool({
|
|
28
|
+
name: 'index_current',
|
|
29
|
+
description: 'Get the current (last active) session, or null if none active.',
|
|
30
|
+
parameters: z.object({}),
|
|
31
|
+
execute: async () => {
|
|
32
|
+
const sessions = await listSessions(db, config.teamId, config.projectId, {
|
|
33
|
+
limit: 1,
|
|
34
|
+
status: 'active',
|
|
35
|
+
});
|
|
36
|
+
if (sessions.length === 0) {
|
|
37
|
+
return JSON.stringify({ active: false, message: 'No active session' });
|
|
38
|
+
}
|
|
39
|
+
const s = sessions[0];
|
|
40
|
+
return JSON.stringify({
|
|
41
|
+
active: true,
|
|
42
|
+
id: s.id,
|
|
43
|
+
seq: s.seq,
|
|
44
|
+
type: s.type,
|
|
45
|
+
short_desc: s.short_desc,
|
|
46
|
+
agent: s.agent,
|
|
47
|
+
request: s.request,
|
|
48
|
+
steps: s.steps,
|
|
49
|
+
files_changed: s.files_changed,
|
|
50
|
+
started_at: s.started_at,
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FastMCP } from 'fastmcp';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
import type { ServerConfig } from '../types.js';
|
|
4
|
+
export declare function registerPlanTools(server: FastMCP, db: SupabaseClient, config: ServerConfig): void;
|
|
5
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI/C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,QA0O1F"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { insertPlan, updatePlan, getPlan, listPlans, deletePlan, upsertChunks } from '../db.js';
|
|
3
|
+
import { embedWithChunking } from '../embed.js';
|
|
4
|
+
export function registerPlanTools(server, db, config) {
|
|
5
|
+
// === plan_create ===
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'plan_create',
|
|
8
|
+
description: 'Create a new development plan with 3-doc structure (plan, context, checklist).',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
slug: z
|
|
11
|
+
.string()
|
|
12
|
+
.regex(/^[a-z0-9-]+$/)
|
|
13
|
+
.describe('URL-friendly slug (lowercase, hyphens)'),
|
|
14
|
+
plan_md: z.string().describe('Main plan markdown'),
|
|
15
|
+
context_md: z.string().default('').describe('Decisions & constraints markdown'),
|
|
16
|
+
checklist_md: z.string().default('').describe('Checklist markdown (- [ ] items)'),
|
|
17
|
+
}),
|
|
18
|
+
execute: async (args) => {
|
|
19
|
+
const { totalItems, doneItems } = parseChecklist(args.checklist_md);
|
|
20
|
+
const plan = await insertPlan(db, {
|
|
21
|
+
team_id: config.teamId,
|
|
22
|
+
project_id: config.projectId,
|
|
23
|
+
slug: args.slug,
|
|
24
|
+
status: 'active',
|
|
25
|
+
plan_md: args.plan_md,
|
|
26
|
+
context_md: args.context_md,
|
|
27
|
+
checklist_md: args.checklist_md,
|
|
28
|
+
total_items: totalItems,
|
|
29
|
+
done_items: doneItems,
|
|
30
|
+
});
|
|
31
|
+
// Embed plan content
|
|
32
|
+
embedPlanContent(db, config, plan.id, args.plan_md, args.slug).catch((err) => console.error('Failed to embed plan:', err));
|
|
33
|
+
return JSON.stringify({
|
|
34
|
+
id: plan.id,
|
|
35
|
+
slug: plan.slug,
|
|
36
|
+
total_items: totalItems,
|
|
37
|
+
done_items: doneItems,
|
|
38
|
+
message: `Plan "${args.slug}" created`,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
// === plan_update ===
|
|
43
|
+
server.addTool({
|
|
44
|
+
name: 'plan_update',
|
|
45
|
+
description: 'Update a specific document in a plan (plan, context, or checklist).',
|
|
46
|
+
parameters: z.object({
|
|
47
|
+
slug: z.string().describe('Plan slug'),
|
|
48
|
+
doc: z.enum(['plan', 'context', 'checklist']).describe('Which document to update'),
|
|
49
|
+
content: z.string().describe('New content for the document'),
|
|
50
|
+
}),
|
|
51
|
+
execute: async (args) => {
|
|
52
|
+
const existing = await getPlan(db, config.teamId, config.projectId, args.slug);
|
|
53
|
+
if (!existing)
|
|
54
|
+
return JSON.stringify({ error: 'Plan not found' });
|
|
55
|
+
const updates = {
|
|
56
|
+
version: existing.version + 1,
|
|
57
|
+
};
|
|
58
|
+
if (args.doc === 'plan') {
|
|
59
|
+
updates.plan_md = args.content;
|
|
60
|
+
}
|
|
61
|
+
else if (args.doc === 'context') {
|
|
62
|
+
updates.context_md = args.content;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
updates.checklist_md = args.content;
|
|
66
|
+
const { totalItems, doneItems } = parseChecklist(args.content);
|
|
67
|
+
updates.total_items = totalItems;
|
|
68
|
+
updates.done_items = doneItems;
|
|
69
|
+
}
|
|
70
|
+
const updated = await updatePlan(db, config.teamId, config.projectId, args.slug, updates);
|
|
71
|
+
// Re-embed if plan doc changed
|
|
72
|
+
if (args.doc === 'plan') {
|
|
73
|
+
embedPlanContent(db, config, updated.id, args.content, args.slug).catch((err) => console.error('Failed to re-embed plan:', err));
|
|
74
|
+
}
|
|
75
|
+
return JSON.stringify({
|
|
76
|
+
slug: updated.slug,
|
|
77
|
+
version: updated.version,
|
|
78
|
+
total_items: updated.total_items,
|
|
79
|
+
done_items: updated.done_items,
|
|
80
|
+
message: `Plan "${args.slug}" ${args.doc} updated (v${updated.version})`,
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
// === plan_read ===
|
|
85
|
+
server.addTool({
|
|
86
|
+
name: 'plan_read',
|
|
87
|
+
description: 'Read a plan. Returns all 3 docs by default, or a specific one.',
|
|
88
|
+
parameters: z.object({
|
|
89
|
+
slug: z.string().describe('Plan slug'),
|
|
90
|
+
doc: z
|
|
91
|
+
.enum(['all', 'plan', 'context', 'checklist'])
|
|
92
|
+
.default('all')
|
|
93
|
+
.describe('Which document(s) to return'),
|
|
94
|
+
}),
|
|
95
|
+
execute: async (args) => {
|
|
96
|
+
const plan = await getPlan(db, config.teamId, config.projectId, args.slug);
|
|
97
|
+
if (!plan)
|
|
98
|
+
return JSON.stringify({ error: 'Plan not found' });
|
|
99
|
+
if (args.doc === 'all') {
|
|
100
|
+
return JSON.stringify({
|
|
101
|
+
slug: plan.slug,
|
|
102
|
+
status: plan.status,
|
|
103
|
+
version: plan.version,
|
|
104
|
+
total_items: plan.total_items,
|
|
105
|
+
done_items: plan.done_items,
|
|
106
|
+
plan_md: plan.plan_md,
|
|
107
|
+
context_md: plan.context_md,
|
|
108
|
+
checklist_md: plan.checklist_md,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const docKey = `${args.doc}_md`;
|
|
112
|
+
return JSON.stringify({
|
|
113
|
+
slug: plan.slug,
|
|
114
|
+
doc: args.doc,
|
|
115
|
+
content: plan[docKey],
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
// === plan_list ===
|
|
120
|
+
server.addTool({
|
|
121
|
+
name: 'plan_list',
|
|
122
|
+
description: 'List development plans with progress stats.',
|
|
123
|
+
parameters: z.object({
|
|
124
|
+
status: z.enum(['active', 'completed', 'archived']).optional().describe('Filter by status'),
|
|
125
|
+
limit: z.number().default(20).describe('Max results'),
|
|
126
|
+
}),
|
|
127
|
+
execute: async (args) => {
|
|
128
|
+
const plans = await listPlans(db, config.teamId, config.projectId, args);
|
|
129
|
+
return JSON.stringify(plans.map((p) => ({
|
|
130
|
+
slug: p.slug,
|
|
131
|
+
status: p.status,
|
|
132
|
+
version: p.version,
|
|
133
|
+
total_items: p.total_items,
|
|
134
|
+
done_items: p.done_items,
|
|
135
|
+
progress: p.total_items > 0 ? Math.round((p.done_items / p.total_items) * 100) : 0,
|
|
136
|
+
updated_at: p.updated_at,
|
|
137
|
+
})));
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
// === plan_check ===
|
|
141
|
+
server.addTool({
|
|
142
|
+
name: 'plan_check',
|
|
143
|
+
description: 'Toggle a checklist item in a plan. Index is 0-based.',
|
|
144
|
+
parameters: z.object({
|
|
145
|
+
slug: z.string().describe('Plan slug'),
|
|
146
|
+
item_index: z.number().int().min(0).describe('0-based index of checklist item'),
|
|
147
|
+
checked: z.boolean().describe('Check (true) or uncheck (false)'),
|
|
148
|
+
}),
|
|
149
|
+
execute: async (args) => {
|
|
150
|
+
const plan = await getPlan(db, config.teamId, config.projectId, args.slug);
|
|
151
|
+
if (!plan)
|
|
152
|
+
return JSON.stringify({ error: 'Plan not found' });
|
|
153
|
+
const lines = plan.checklist_md.split('\n');
|
|
154
|
+
let checkboxIndex = -1;
|
|
155
|
+
for (let i = 0; i < lines.length; i++) {
|
|
156
|
+
if (/^- \[[ x]\] /.test(lines[i])) {
|
|
157
|
+
checkboxIndex++;
|
|
158
|
+
if (checkboxIndex === args.item_index) {
|
|
159
|
+
lines[i] = args.checked
|
|
160
|
+
? lines[i].replace('- [ ] ', '- [x] ')
|
|
161
|
+
: lines[i].replace('- [x] ', '- [ ] ');
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (checkboxIndex < args.item_index) {
|
|
167
|
+
return JSON.stringify({
|
|
168
|
+
error: `Item index ${args.item_index} out of range (max: ${checkboxIndex})`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const newChecklist = lines.join('\n');
|
|
172
|
+
const { totalItems, doneItems } = parseChecklist(newChecklist);
|
|
173
|
+
await updatePlan(db, config.teamId, config.projectId, args.slug, {
|
|
174
|
+
checklist_md: newChecklist,
|
|
175
|
+
total_items: totalItems,
|
|
176
|
+
done_items: doneItems,
|
|
177
|
+
version: plan.version + 1,
|
|
178
|
+
});
|
|
179
|
+
return JSON.stringify({
|
|
180
|
+
slug: args.slug,
|
|
181
|
+
item_index: args.item_index,
|
|
182
|
+
checked: args.checked,
|
|
183
|
+
total_items: totalItems,
|
|
184
|
+
done_items: doneItems,
|
|
185
|
+
progress: totalItems > 0 ? Math.round((doneItems / totalItems) * 100) : 0,
|
|
186
|
+
message: `Checklist item ${args.item_index} ${args.checked ? 'checked' : 'unchecked'}`,
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
// === plan_archive ===
|
|
191
|
+
server.addTool({
|
|
192
|
+
name: 'plan_archive',
|
|
193
|
+
description: 'Archive or permanently delete a plan.',
|
|
194
|
+
parameters: z.object({
|
|
195
|
+
slug: z.string().describe('Plan slug'),
|
|
196
|
+
hard_delete: z.boolean().default(false).describe('Permanently delete instead of archive'),
|
|
197
|
+
}),
|
|
198
|
+
execute: async (args) => {
|
|
199
|
+
if (args.hard_delete) {
|
|
200
|
+
await deletePlan(db, config.teamId, config.projectId, args.slug);
|
|
201
|
+
return JSON.stringify({
|
|
202
|
+
slug: args.slug,
|
|
203
|
+
message: `Plan "${args.slug}" permanently deleted`,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
await updatePlan(db, config.teamId, config.projectId, args.slug, {
|
|
207
|
+
status: 'archived',
|
|
208
|
+
});
|
|
209
|
+
return JSON.stringify({
|
|
210
|
+
slug: args.slug,
|
|
211
|
+
message: `Plan "${args.slug}" archived`,
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
// Helper: parse checklist markdown to count items
|
|
217
|
+
function parseChecklist(md) {
|
|
218
|
+
const lines = md.split('\n');
|
|
219
|
+
let totalItems = 0;
|
|
220
|
+
let doneItems = 0;
|
|
221
|
+
for (const line of lines) {
|
|
222
|
+
if (/^- \[ \] /.test(line)) {
|
|
223
|
+
totalItems++;
|
|
224
|
+
}
|
|
225
|
+
else if (/^- \[x\] /.test(line)) {
|
|
226
|
+
totalItems++;
|
|
227
|
+
doneItems++;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return { totalItems, doneItems };
|
|
231
|
+
}
|
|
232
|
+
// Helper: embed plan content and store as memory chunks
|
|
233
|
+
async function embedPlanContent(db, config, planId, planMd, slug) {
|
|
234
|
+
const chunks = await embedWithChunking(planMd);
|
|
235
|
+
await upsertChunks(db, chunks.map((c) => ({
|
|
236
|
+
team_id: config.teamId,
|
|
237
|
+
project_id: config.projectId,
|
|
238
|
+
category: 'plan',
|
|
239
|
+
source_id: planId,
|
|
240
|
+
content: c.content,
|
|
241
|
+
embedding: c.embedding,
|
|
242
|
+
chunk_index: c.chunkIndex,
|
|
243
|
+
metadata: { slug },
|
|
244
|
+
})));
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FastMCP } from 'fastmcp';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
import type { ServerConfig } from '../types.js';
|
|
4
|
+
export declare function registerSessionTools(server: FastMCP, db: SupabaseClient, config: ServerConfig): void;
|
|
5
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAY/C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,QAwN7F"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { nextSeq, insertSession, updateSession, getSession, listSessions, hybridSearchSessions, } from '../db.js';
|
|
3
|
+
import { embed, embedWithChunking } from '../embed.js';
|
|
4
|
+
import { upsertChunks } from '../db.js';
|
|
5
|
+
export function registerSessionTools(server, db, config) {
|
|
6
|
+
// === session_start ===
|
|
7
|
+
server.addTool({
|
|
8
|
+
name: 'session_start',
|
|
9
|
+
description: 'Start a new dev session. Returns session ID and seq number. Auto-embeds the request for semantic search.',
|
|
10
|
+
parameters: z.object({
|
|
11
|
+
type: z
|
|
12
|
+
.enum(['fix', 'feat', 'refactor', 'style', 'config', 'docs', 'perf'])
|
|
13
|
+
.describe('Session type'),
|
|
14
|
+
short_desc: z.string().describe('One-line description'),
|
|
15
|
+
request: z.string().optional().describe('What was requested'),
|
|
16
|
+
agent: z
|
|
17
|
+
.enum(['claude', 'codex', 'gemini', 'cursor', 'other'])
|
|
18
|
+
.default('claude')
|
|
19
|
+
.describe('Which AI agent'),
|
|
20
|
+
}),
|
|
21
|
+
execute: async (args) => {
|
|
22
|
+
const seq = await nextSeq(db, config.teamId, config.projectId);
|
|
23
|
+
const session = await insertSession(db, {
|
|
24
|
+
team_id: config.teamId,
|
|
25
|
+
project_id: config.projectId,
|
|
26
|
+
seq,
|
|
27
|
+
type: args.type,
|
|
28
|
+
short_desc: args.short_desc,
|
|
29
|
+
agent: args.agent,
|
|
30
|
+
status: 'active',
|
|
31
|
+
result: null,
|
|
32
|
+
request: args.request ?? null,
|
|
33
|
+
steps: null,
|
|
34
|
+
files_changed: [],
|
|
35
|
+
result_note: null,
|
|
36
|
+
started_at: new Date().toISOString(),
|
|
37
|
+
});
|
|
38
|
+
// Embed request in background (don't block)
|
|
39
|
+
if (args.request) {
|
|
40
|
+
embedAndStore(db, config, session.id, 'session', args.request, {
|
|
41
|
+
seq,
|
|
42
|
+
type: args.type,
|
|
43
|
+
}).catch((err) => console.error('Failed to embed session start:', err));
|
|
44
|
+
}
|
|
45
|
+
return JSON.stringify({
|
|
46
|
+
id: session.id,
|
|
47
|
+
seq: session.seq,
|
|
48
|
+
status: 'active',
|
|
49
|
+
message: `Session #${seq} started: ${args.short_desc}`,
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
// === session_log ===
|
|
54
|
+
server.addTool({
|
|
55
|
+
name: 'session_log',
|
|
56
|
+
description: 'Log progress to an active session. Appends steps and files changed.',
|
|
57
|
+
parameters: z.object({
|
|
58
|
+
session_id: z.string().uuid().describe('Session ID'),
|
|
59
|
+
steps: z.string().optional().describe('Steps performed (appended)'),
|
|
60
|
+
files_changed: z.array(z.string()).optional().describe('Files changed (merged)'),
|
|
61
|
+
}),
|
|
62
|
+
execute: async (args) => {
|
|
63
|
+
const existing = await getSession(db, config.teamId, config.projectId, args.session_id);
|
|
64
|
+
if (!existing)
|
|
65
|
+
return JSON.stringify({ error: 'Session not found' });
|
|
66
|
+
const updates = {};
|
|
67
|
+
if (args.steps) {
|
|
68
|
+
updates.steps = existing.steps ? `${existing.steps}\n${args.steps}` : args.steps;
|
|
69
|
+
}
|
|
70
|
+
if (args.files_changed) {
|
|
71
|
+
const merged = [...new Set([...existing.files_changed, ...args.files_changed])];
|
|
72
|
+
updates.files_changed = merged;
|
|
73
|
+
}
|
|
74
|
+
const updated = await updateSession(db, args.session_id, updates);
|
|
75
|
+
return JSON.stringify({
|
|
76
|
+
id: updated.id,
|
|
77
|
+
seq: updated.seq,
|
|
78
|
+
files_count: updated.files_changed.length,
|
|
79
|
+
message: 'Session updated',
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
// === session_end ===
|
|
84
|
+
server.addTool({
|
|
85
|
+
name: 'session_end',
|
|
86
|
+
description: 'End a dev session. Sets result and embeds full summary for semantic search.',
|
|
87
|
+
parameters: z.object({
|
|
88
|
+
session_id: z.string().uuid().describe('Session ID'),
|
|
89
|
+
result: z.enum(['success', 'warning', 'failure']).describe('Session result'),
|
|
90
|
+
result_note: z.string().optional().describe('Result note'),
|
|
91
|
+
}),
|
|
92
|
+
execute: async (args) => {
|
|
93
|
+
const updated = await updateSession(db, args.session_id, {
|
|
94
|
+
status: 'completed',
|
|
95
|
+
result: args.result,
|
|
96
|
+
result_note: args.result_note ?? null,
|
|
97
|
+
ended_at: new Date().toISOString(),
|
|
98
|
+
});
|
|
99
|
+
// Embed full summary for semantic search
|
|
100
|
+
const summaryText = [
|
|
101
|
+
`#${updated.seq} ${updated.type}: ${updated.short_desc}`,
|
|
102
|
+
updated.request ? `Request: ${updated.request}` : '',
|
|
103
|
+
updated.steps ? `Steps: ${updated.steps}` : '',
|
|
104
|
+
updated.result_note ? `Result: ${updated.result_note}` : '',
|
|
105
|
+
updated.files_changed.length > 0 ? `Files: ${updated.files_changed.join(', ')}` : '',
|
|
106
|
+
]
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.join('\n');
|
|
109
|
+
embedAndStore(db, config, updated.id, 'session', summaryText, {
|
|
110
|
+
seq: updated.seq,
|
|
111
|
+
type: updated.type,
|
|
112
|
+
result: updated.result,
|
|
113
|
+
}).catch((err) => console.error('Failed to embed session summary:', err));
|
|
114
|
+
return JSON.stringify({
|
|
115
|
+
id: updated.id,
|
|
116
|
+
seq: updated.seq,
|
|
117
|
+
result: updated.result,
|
|
118
|
+
message: `Session #${updated.seq} completed: ${args.result}`,
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
// === session_list ===
|
|
123
|
+
server.addTool({
|
|
124
|
+
name: 'session_list',
|
|
125
|
+
description: 'List recent dev sessions for the current project.',
|
|
126
|
+
parameters: z.object({
|
|
127
|
+
limit: z.number().default(20).describe('Max results'),
|
|
128
|
+
offset: z.number().default(0).describe('Skip N results'),
|
|
129
|
+
status: z.enum(['active', 'completed', 'abandoned']).optional().describe('Filter by status'),
|
|
130
|
+
}),
|
|
131
|
+
execute: async (args) => {
|
|
132
|
+
const sessions = await listSessions(db, config.teamId, config.projectId, args);
|
|
133
|
+
return JSON.stringify(sessions.map((s) => ({
|
|
134
|
+
id: s.id,
|
|
135
|
+
seq: s.seq,
|
|
136
|
+
type: s.type,
|
|
137
|
+
short_desc: s.short_desc,
|
|
138
|
+
agent: s.agent,
|
|
139
|
+
status: s.status,
|
|
140
|
+
result: s.result,
|
|
141
|
+
started_at: s.started_at,
|
|
142
|
+
})));
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
// === session_read ===
|
|
146
|
+
server.addTool({
|
|
147
|
+
name: 'session_read',
|
|
148
|
+
description: 'Read full details of a dev session by ID or seq number.',
|
|
149
|
+
parameters: z.object({
|
|
150
|
+
session_id: z.string().optional().describe('Session UUID'),
|
|
151
|
+
seq: z.number().optional().describe('Session sequence number (#NNN)'),
|
|
152
|
+
}),
|
|
153
|
+
execute: async (args) => {
|
|
154
|
+
if (!args.session_id && args.seq === undefined) {
|
|
155
|
+
return JSON.stringify({ error: 'Provide session_id or seq' });
|
|
156
|
+
}
|
|
157
|
+
const session = await getSession(db, config.teamId, config.projectId, args.seq !== undefined ? args.seq : args.session_id);
|
|
158
|
+
if (!session)
|
|
159
|
+
return JSON.stringify({ error: 'Session not found' });
|
|
160
|
+
return JSON.stringify(session);
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
// === session_search ===
|
|
164
|
+
server.addTool({
|
|
165
|
+
name: 'session_search',
|
|
166
|
+
description: 'Semantic + full-text hybrid search across dev sessions. Uses vector similarity + RRF fusion.',
|
|
167
|
+
parameters: z.object({
|
|
168
|
+
query: z.string().describe('Search query (natural language)'),
|
|
169
|
+
limit: z.number().default(10).describe('Max results'),
|
|
170
|
+
}),
|
|
171
|
+
execute: async (args) => {
|
|
172
|
+
const queryEmbedding = await embed(args.query);
|
|
173
|
+
const results = await hybridSearchSessions(db, args.query, queryEmbedding, config.teamId, config.projectId, args.limit);
|
|
174
|
+
return JSON.stringify(results.map((r) => ({
|
|
175
|
+
id: r.id,
|
|
176
|
+
seq: r.seq,
|
|
177
|
+
type: r.type,
|
|
178
|
+
short_desc: r.short_desc,
|
|
179
|
+
result: r.result,
|
|
180
|
+
rrf_score: r.rrf_score,
|
|
181
|
+
request: r.request?.slice(0, 200),
|
|
182
|
+
result_note: r.result_note?.slice(0, 200),
|
|
183
|
+
})));
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Helper: embed text and store as memory chunks
|
|
188
|
+
async function embedAndStore(db, config, sourceId, category, text, metadata) {
|
|
189
|
+
const chunks = await embedWithChunking(text);
|
|
190
|
+
await upsertChunks(db, chunks.map((c) => ({
|
|
191
|
+
team_id: config.teamId,
|
|
192
|
+
project_id: config.projectId,
|
|
193
|
+
category,
|
|
194
|
+
source_id: sourceId,
|
|
195
|
+
content: c.content,
|
|
196
|
+
embedding: c.embedding,
|
|
197
|
+
chunk_index: c.chunkIndex,
|
|
198
|
+
metadata,
|
|
199
|
+
})));
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export interface DevSession {
|
|
2
|
+
id: string;
|
|
3
|
+
team_id: string;
|
|
4
|
+
project_id: string;
|
|
5
|
+
seq: number;
|
|
6
|
+
type: SessionType;
|
|
7
|
+
short_desc: string;
|
|
8
|
+
agent: AgentType;
|
|
9
|
+
status: SessionStatus;
|
|
10
|
+
result: SessionResult | null;
|
|
11
|
+
request: string | null;
|
|
12
|
+
steps: string | null;
|
|
13
|
+
files_changed: string[];
|
|
14
|
+
result_note: string | null;
|
|
15
|
+
started_at: string;
|
|
16
|
+
ended_at: string | null;
|
|
17
|
+
}
|
|
18
|
+
export type SessionType = 'fix' | 'feat' | 'refactor' | 'style' | 'config' | 'docs' | 'perf';
|
|
19
|
+
export type AgentType = 'claude' | 'codex' | 'gemini' | 'cursor' | 'other';
|
|
20
|
+
export type SessionStatus = 'active' | 'completed' | 'abandoned';
|
|
21
|
+
export type SessionResult = 'success' | 'warning' | 'failure';
|
|
22
|
+
export interface DevPlan {
|
|
23
|
+
id: string;
|
|
24
|
+
team_id: string;
|
|
25
|
+
project_id: string;
|
|
26
|
+
slug: string;
|
|
27
|
+
status: PlanStatus;
|
|
28
|
+
plan_md: string;
|
|
29
|
+
context_md: string;
|
|
30
|
+
checklist_md: string;
|
|
31
|
+
total_items: number;
|
|
32
|
+
done_items: number;
|
|
33
|
+
version: number;
|
|
34
|
+
created_at: string;
|
|
35
|
+
updated_at: string;
|
|
36
|
+
}
|
|
37
|
+
export type PlanStatus = 'active' | 'completed' | 'archived';
|
|
38
|
+
export type PlanDoc = 'plan' | 'context' | 'checklist';
|
|
39
|
+
export interface MemoryChunk {
|
|
40
|
+
id: string;
|
|
41
|
+
team_id: string;
|
|
42
|
+
project_id: string;
|
|
43
|
+
category: ChunkCategory;
|
|
44
|
+
source_id: string | null;
|
|
45
|
+
content: string;
|
|
46
|
+
embedding: number[];
|
|
47
|
+
chunk_index: number;
|
|
48
|
+
metadata: Record<string, unknown>;
|
|
49
|
+
created_at: string;
|
|
50
|
+
}
|
|
51
|
+
export type ChunkCategory = 'session' | 'plan' | 'context';
|
|
52
|
+
export interface SearchResult {
|
|
53
|
+
id: string;
|
|
54
|
+
content: string;
|
|
55
|
+
category: ChunkCategory;
|
|
56
|
+
source_id: string | null;
|
|
57
|
+
metadata: Record<string, unknown>;
|
|
58
|
+
similarity: number;
|
|
59
|
+
}
|
|
60
|
+
export interface HybridSearchResult extends DevSession {
|
|
61
|
+
rrf_score: number;
|
|
62
|
+
}
|
|
63
|
+
export interface ServerConfig {
|
|
64
|
+
supabaseUrl: string;
|
|
65
|
+
supabaseServiceKey: string;
|
|
66
|
+
openaiApiKey: string;
|
|
67
|
+
teamId: string;
|
|
68
|
+
projectId: string;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hive-mcp-server",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Hive MCP server — AI dev session logs, plans, and semantic search via Supabase pgvector",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"hive-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"inspect": "npx fastmcp dev src/index.ts",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"mcp",
|
|
23
|
+
"model-context-protocol",
|
|
24
|
+
"claude",
|
|
25
|
+
"supabase",
|
|
26
|
+
"pgvector",
|
|
27
|
+
"session-logs",
|
|
28
|
+
"semantic-search",
|
|
29
|
+
"ai-agent"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/StudioRaming/hive",
|
|
34
|
+
"directory": "mcp-server"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"fastmcp": "^3.33.0",
|
|
39
|
+
"@supabase/supabase-js": "^2.97.0",
|
|
40
|
+
"zod": "^3.24.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.9.3",
|
|
44
|
+
"tsx": "^4.19.0",
|
|
45
|
+
"@types/node": "^22.0.0"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
}
|
|
50
|
+
}
|