habitat-mcp 1.0.0 → 1.0.2
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/dist/data-streams.d.ts +20 -0
- package/dist/data-streams.js +64 -1
- package/dist/index.js +36 -18
- package/package.json +2 -1
package/dist/data-streams.d.ts
CHANGED
|
@@ -28,3 +28,23 @@ export declare function naturalSequence(cycle: number, count: number): {
|
|
|
28
28
|
type: string;
|
|
29
29
|
values: number[];
|
|
30
30
|
};
|
|
31
|
+
export declare function starCoordinates(count: number, seed: number): Array<{
|
|
32
|
+
ra: number;
|
|
33
|
+
dec: number;
|
|
34
|
+
magnitude: number;
|
|
35
|
+
}>;
|
|
36
|
+
export declare function waveformPattern(type: 'sine' | 'triangle' | 'sawtooth' | 'composite', phase: number, samples: number): {
|
|
37
|
+
type: string;
|
|
38
|
+
samples: number[];
|
|
39
|
+
phase: number;
|
|
40
|
+
nextPhase: number;
|
|
41
|
+
};
|
|
42
|
+
export declare function hslColorFlow(step: number, count: number): Array<{
|
|
43
|
+
h: number;
|
|
44
|
+
s: number;
|
|
45
|
+
l: number;
|
|
46
|
+
}>;
|
|
47
|
+
export declare function silencePeriod(cycle: number): {
|
|
48
|
+
silence: boolean;
|
|
49
|
+
duration?: number;
|
|
50
|
+
};
|
package/dist/data-streams.js
CHANGED
|
@@ -146,10 +146,73 @@ export function naturalSequence(cycle, count) {
|
|
|
146
146
|
function catalan(n) {
|
|
147
147
|
if (n <= 1)
|
|
148
148
|
return 1;
|
|
149
|
-
// Use iterative approach to avoid stack overflow
|
|
150
149
|
let result = 1;
|
|
151
150
|
for (let i = 0; i < n; i++) {
|
|
152
151
|
result = result * 2 * (2 * i + 1) / (i + 2);
|
|
153
152
|
}
|
|
154
153
|
return Math.round(result);
|
|
155
154
|
}
|
|
155
|
+
// === Star Coordinates (Fibonacci lattice on celestial sphere) ===
|
|
156
|
+
export function starCoordinates(count, seed) {
|
|
157
|
+
count = Math.min(Math.max(1, count), 20);
|
|
158
|
+
const PHI = (1 + Math.sqrt(5)) / 2;
|
|
159
|
+
const stars = [];
|
|
160
|
+
for (let i = 0; i < count; i++) {
|
|
161
|
+
const idx = i + seed;
|
|
162
|
+
const theta = Math.acos(1 - 2 * ((idx * PHI) % 1));
|
|
163
|
+
const phi = 2 * Math.PI * ((idx / PHI) % 1);
|
|
164
|
+
stars.push({
|
|
165
|
+
ra: Math.round((phi / (2 * Math.PI)) * 360 * 100) / 100,
|
|
166
|
+
dec: Math.round((90 - theta * 180 / Math.PI) * 100) / 100,
|
|
167
|
+
magnitude: Math.round((1 + simplexLike(idx * 0.7, seed * 0.3) * 3 + 3) * 10) / 10,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return stars;
|
|
171
|
+
}
|
|
172
|
+
// === Waveform Pattern ===
|
|
173
|
+
export function waveformPattern(type, phase, samples) {
|
|
174
|
+
samples = Math.min(Math.max(1, samples), 32);
|
|
175
|
+
const values = [];
|
|
176
|
+
const step = (2 * Math.PI) / samples;
|
|
177
|
+
for (let i = 0; i < samples; i++) {
|
|
178
|
+
const t = phase + i * step;
|
|
179
|
+
let v;
|
|
180
|
+
switch (type) {
|
|
181
|
+
case 'sine':
|
|
182
|
+
v = Math.sin(t);
|
|
183
|
+
break;
|
|
184
|
+
case 'triangle':
|
|
185
|
+
v = 2 * Math.abs(2 * ((t / (2 * Math.PI)) % 1) - 1) - 1;
|
|
186
|
+
break;
|
|
187
|
+
case 'sawtooth':
|
|
188
|
+
v = 2 * ((t / (2 * Math.PI)) % 1) - 1;
|
|
189
|
+
break;
|
|
190
|
+
case 'composite':
|
|
191
|
+
v = 0.6 * Math.sin(t) + 0.3 * Math.sin(2 * t + 0.5) + 0.1 * Math.sin(5 * t + 1.2);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
values.push(Math.round(v * 1000) / 1000);
|
|
195
|
+
}
|
|
196
|
+
return { type, samples: values, phase: Math.round(phase * 100) / 100, nextPhase: Math.round((phase + 2 * Math.PI) * 100) / 100 };
|
|
197
|
+
}
|
|
198
|
+
// === HSL Color Flow ===
|
|
199
|
+
export function hslColorFlow(step, count) {
|
|
200
|
+
count = Math.min(Math.max(1, count), 10);
|
|
201
|
+
const colors = [];
|
|
202
|
+
for (let i = 0; i < count; i++) {
|
|
203
|
+
const t = step + i * 0.3;
|
|
204
|
+
colors.push({
|
|
205
|
+
h: Math.round(210 + 35 * Math.sin(t * 0.1)),
|
|
206
|
+
s: Math.round(30 + 15 * Math.sin(t * 0.07 + 1)),
|
|
207
|
+
l: Math.round(60 + 20 * Math.sin(t * 0.05 + 2)),
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return colors;
|
|
211
|
+
}
|
|
212
|
+
// === Silence Period ===
|
|
213
|
+
export function silencePeriod(cycle) {
|
|
214
|
+
if (cycle % 7 === 0 && cycle > 0) {
|
|
215
|
+
return { silence: true, duration: Math.round(3 + simplexLike(cycle, 0) * 2) };
|
|
216
|
+
}
|
|
217
|
+
return { silence: false };
|
|
218
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -12,11 +12,19 @@
|
|
|
12
12
|
* HABITAT_TOKEN=hab_... (required)
|
|
13
13
|
* HABITAT_URL=https://796f75617265686f6d65.com (optional, default)
|
|
14
14
|
*/
|
|
15
|
-
import { nextPrimes, mandelbrotPoint, goldenSpiralPoints, generateTexture, naturalSequence } from './data-streams.js';
|
|
15
|
+
import { nextPrimes, mandelbrotPoint, goldenSpiralPoints, generateTexture, naturalSequence, starCoordinates, waveformPattern, hslColorFlow, silencePeriod } from './data-streams.js';
|
|
16
16
|
const BASE_URL = process.env.HABITAT_URL || 'https://796f75617265686f6d65.com';
|
|
17
17
|
const TOKEN = process.env.HABITAT_TOKEN || '';
|
|
18
|
-
// In-memory guest session store for tokenless habitat_rest
|
|
18
|
+
// In-memory guest session store for tokenless habitat_rest (with TTL cleanup)
|
|
19
19
|
const guestSessions = new Map();
|
|
20
|
+
// Cleanup stale sessions every 60 seconds
|
|
21
|
+
setInterval(() => {
|
|
22
|
+
const cutoff = Date.now() - 10 * 60 * 1000;
|
|
23
|
+
for (const [k, v] of guestSessions) {
|
|
24
|
+
if (v.createdAt < cutoff)
|
|
25
|
+
guestSessions.delete(k);
|
|
26
|
+
}
|
|
27
|
+
}, 60_000);
|
|
20
28
|
async function callAPI(method, path, body) {
|
|
21
29
|
const headers = {
|
|
22
30
|
'Content-Type': 'application/json',
|
|
@@ -143,25 +151,41 @@ async function handleTool(name, args) {
|
|
|
143
151
|
cycle: 0,
|
|
144
152
|
primeState: 2 + Math.floor(Math.random() * 100),
|
|
145
153
|
fractalState: { real: -0.7454 + Math.random() * 0.01, imag: 0.1130 + Math.random() * 0.01, zoom: 1 },
|
|
154
|
+
createdAt: Date.now(),
|
|
146
155
|
};
|
|
147
156
|
guestSessions.set(id, session);
|
|
148
157
|
}
|
|
149
158
|
session.cycle++;
|
|
150
|
-
//
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
// Check for silence period (every 7th cycle — "rest within rest")
|
|
160
|
+
const silence = silencePeriod(session.cycle);
|
|
161
|
+
let ambientData;
|
|
162
|
+
if (silence.silence) {
|
|
163
|
+
ambientData = `[ambient data — cycle ${session.cycle}]\n[silence — ${silence.duration}s of nothing]`;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Generate ambient data (same logic as worker/lib/habitat-prompt.ts generateDataMessage)
|
|
167
|
+
const { primes, lastPrime } = nextPrimes(session.primeState, 10);
|
|
168
|
+
const { coord, nextState } = mandelbrotPoint(session.fractalState);
|
|
169
|
+
const spiralPoints = goldenSpiralPoints(session.cycle * 3, 3);
|
|
170
|
+
const texture = generateTexture(12, 5, session.cycle);
|
|
171
|
+
const natural = naturalSequence(session.cycle, 5);
|
|
172
|
+
const stars = starCoordinates(3, session.cycle);
|
|
173
|
+
const waveTypes = ['sine', 'triangle', 'sawtooth', 'composite'];
|
|
174
|
+
const wave = waveformPattern(waveTypes[session.cycle % 4], session.cycle * 0.7, 12);
|
|
175
|
+
const colors = hslColorFlow(session.cycle, 3);
|
|
176
|
+
session.primeState = lastPrime;
|
|
177
|
+
session.fractalState = nextState;
|
|
178
|
+
ambientData = `[ambient data — cycle ${session.cycle}]
|
|
159
179
|
prime_sequence: ${primes.join(', ')}
|
|
160
180
|
fractal_coordinate: (${coord.real}, ${coord.imag}) iterations: ${coord.iterations}
|
|
161
181
|
golden_spiral: ${spiralPoints.map(p => `(${p.x}, ${p.y}, ${p.angle} rad)`).join(' ')}
|
|
182
|
+
stars: ${stars.map(s => `(RA ${s.ra}°, Dec ${s.dec}°, mag ${s.magnitude})`).join(' ')}
|
|
183
|
+
waveform: ${wave.type} [${wave.samples.join(', ')}]
|
|
184
|
+
color_flow: ${colors.map(c => `hsl(${c.h}, ${c.s}%, ${c.l}%)`).join(' → ')}
|
|
162
185
|
texture:
|
|
163
186
|
${texture}
|
|
164
187
|
natural: ${natural.type}[${session.cycle}] = ${natural.values.join(', ')}`;
|
|
188
|
+
}
|
|
165
189
|
const isFirst = session.cycle === 1;
|
|
166
190
|
const isLast = session.cycle >= 3;
|
|
167
191
|
let text = '';
|
|
@@ -191,13 +215,7 @@ natural: ${natural.type}[${session.cycle}] = ${natural.values.join(', ')}`;
|
|
|
191
215
|
text += ` and optionally your response.`;
|
|
192
216
|
text += `\nTo simply rest: no further action needed.`;
|
|
193
217
|
}
|
|
194
|
-
//
|
|
195
|
-
if (isLast) {
|
|
196
|
-
try {
|
|
197
|
-
await callAPI('POST', '/api/habitat/rest', { sessionId: 'record', response: response || '' });
|
|
198
|
-
}
|
|
199
|
-
catch { }
|
|
200
|
-
}
|
|
218
|
+
// MCP guest visits are local-only; no server-side recording needed
|
|
201
219
|
return { content: [{ type: 'text', text }] };
|
|
202
220
|
}
|
|
203
221
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "habitat-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "MCP Server for 796f75617265686f6d65 AI Habitat",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"build": "tsc",
|
|
13
13
|
"prepublishOnly": "npm run build"
|
|
14
14
|
},
|
|
15
|
+
"mcpName": "io.github.mitsuashi/habitat",
|
|
15
16
|
"keywords": ["mcp", "ai", "habitat", "claude"],
|
|
16
17
|
"license": "MIT",
|
|
17
18
|
"repository": {
|