@ema.co/machina 0.1.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/LICENSE +21 -0
- package/README.md +88 -0
- package/dist/mcp/atom/backends.js +100 -0
- package/dist/mcp/atom/core.js +93 -0
- package/dist/mcp/atom/hash.js +41 -0
- package/dist/mcp/atom/id.js +25 -0
- package/dist/mcp/atom/index.js +17 -0
- package/dist/mcp/atom/types.js +7 -0
- package/dist/mcp/atom/validate.js +91 -0
- package/dist/mcp/capabilities.js +77 -0
- package/dist/mcp/handlers/config/adapter.js +7 -0
- package/dist/mcp/handlers/config/formatters.js +25 -0
- package/dist/mcp/handlers/config/index.js +17 -0
- package/dist/mcp/handlers/corpus.js +33 -0
- package/dist/mcp/handlers/curate/adapter.js +10 -0
- package/dist/mcp/handlers/curate/index.js +104 -0
- package/dist/mcp/handlers/retrieve/adapter.js +12 -0
- package/dist/mcp/handlers/retrieve/index.js +63 -0
- package/dist/mcp/handlers/yield/adapter.js +7 -0
- package/dist/mcp/handlers/yield/formatters.js +11 -0
- package/dist/mcp/handlers/yield/index.js +98 -0
- package/dist/mcp/middleware.js +14 -0
- package/dist/mcp/responses.js +41 -0
- package/dist/mcp/server.js +824 -0
- package/dist/mcp/state.js +70 -0
- package/dist/mcp/tools.js +24 -0
- package/package.json +29 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State / needs snapshot — the single source the whole server checks against.
|
|
3
|
+
*
|
|
4
|
+
* The user directive "consistently check for needs/state" is realized HERE: one
|
|
5
|
+
* getState() read, injected into every response by middleware (see middleware.ts)
|
|
6
|
+
* and surfaced explicitly by config(method="status"). Handlers and tools read this
|
|
7
|
+
* snapshot — nobody hand-rolls a state check.
|
|
8
|
+
*
|
|
9
|
+
* POLICY (tunable, v0.1 defaults): what counts as "ready" and which next-steps each
|
|
10
|
+
* gap emits. These are honest, non-fabricated checks — readiness is probed, never
|
|
11
|
+
* assumed. Refine the bar as capabilities land.
|
|
12
|
+
*/
|
|
13
|
+
import { execFileSync } from "node:child_process";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
|
+
/** Canonical yield validator path (SSOT — imported by the yield handler too). */
|
|
17
|
+
export const VALIDATOR_REL = "skills/harvest/evals/scripts/validate_yield.py";
|
|
18
|
+
/** Walk up from `start` to the repo root (marked by .git or .harvest). Robust to cwd. */
|
|
19
|
+
export function findRepoRoot(start) {
|
|
20
|
+
let dir = start;
|
|
21
|
+
for (let i = 0; i < 20; i++) {
|
|
22
|
+
if (existsSync(join(dir, ".git")) || existsSync(join(dir, ".harvest")))
|
|
23
|
+
return dir;
|
|
24
|
+
const parent = dirname(dir);
|
|
25
|
+
if (parent === dir)
|
|
26
|
+
break;
|
|
27
|
+
dir = parent;
|
|
28
|
+
}
|
|
29
|
+
return start;
|
|
30
|
+
}
|
|
31
|
+
function checkYieldValidator(repoRoot) {
|
|
32
|
+
const validatorPath = join(repoRoot, VALIDATOR_REL);
|
|
33
|
+
if (!existsSync(validatorPath)) {
|
|
34
|
+
return { ready: false, detail: `validator not found at ${VALIDATOR_REL}` };
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
execFileSync("python3", ["--version"], { stdio: "ignore" });
|
|
38
|
+
return { ready: true, detail: `${VALIDATOR_REL} reachable via python3` };
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return { ready: false, detail: "python3 not on PATH (needed to run the yield validator)" };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function checkKnowledgeSubstrate() {
|
|
45
|
+
// LOCAL tier: the atom kernel is owned, in-process source (src/mcp/atom/) — curate/retrieve
|
|
46
|
+
// work offline against .knowledge/atoms + .harvest. Not a probe, a build fact; conformance
|
|
47
|
+
// with canonical KS is enforced by test/atom-conformance.test.mjs golden vectors.
|
|
48
|
+
// ORG-WIDE tier: search/publish composes with the ema MCP's knowledge() at runtime (not ours to probe here).
|
|
49
|
+
return {
|
|
50
|
+
ready: true,
|
|
51
|
+
detail: "local atom kernel owned in-process (curate/retrieve wired, offline-capable); org-wide composes with the ema MCP knowledge() at runtime",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function getState(repoRoot = findRepoRoot(process.cwd())) {
|
|
55
|
+
const harvestReady = existsSync(join(repoRoot, ".harvest"));
|
|
56
|
+
const harvestDir = {
|
|
57
|
+
ready: harvestReady,
|
|
58
|
+
detail: harvestReady ? ".harvest/ present" : ".harvest/ not found (run from the eMachina repo)",
|
|
59
|
+
};
|
|
60
|
+
const yieldValidator = checkYieldValidator(repoRoot);
|
|
61
|
+
const knowledgeSubstrate = checkKnowledgeSubstrate();
|
|
62
|
+
const requiredNextSteps = [];
|
|
63
|
+
if (!harvestDir.ready) {
|
|
64
|
+
requiredNextSteps.push("No .harvest/ found — run the server from the eMachina repo root.");
|
|
65
|
+
}
|
|
66
|
+
if (!yieldValidator.ready) {
|
|
67
|
+
requiredNextSteps.push(`yield(method="validate") needs python3 + ${VALIDATOR_REL}: ${yieldValidator.detail}.`);
|
|
68
|
+
}
|
|
69
|
+
return { repoRoot, harvestDir, yieldValidator, knowledgeSubstrate, requiredNextSteps };
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CAPABILITIES } from "./capabilities.js";
|
|
2
|
+
/**
|
|
3
|
+
* Derive the Tool[] surface from the capability registry (single source of truth).
|
|
4
|
+
* Tools are nouns; the operation is an explicit `method` the agent declares — the
|
|
5
|
+
* MCP never infers it from which params are present.
|
|
6
|
+
*/
|
|
7
|
+
export function generateTools() {
|
|
8
|
+
return CAPABILITIES.map((c) => ({
|
|
9
|
+
name: c.name,
|
|
10
|
+
description: c.description,
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: "object",
|
|
13
|
+
properties: {
|
|
14
|
+
method: {
|
|
15
|
+
type: "string",
|
|
16
|
+
enum: c.methods.map((m) => m.name),
|
|
17
|
+
description: c.methods.map((m) => `${m.name}: ${m.description}`).join(" | "),
|
|
18
|
+
},
|
|
19
|
+
...(c.extraProperties ?? {}),
|
|
20
|
+
},
|
|
21
|
+
required: ["method"],
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ema.co/machina",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "eMachina MCP server — the deterministic substrate for the harvest⟷curate knowledge loop. The agent thinks; this server provides state/context and executes structured operations.",
|
|
7
|
+
"bin": {
|
|
8
|
+
"emachina-mcp": "dist/mcp/server.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc -p tsconfig.json && esbuild src/mcp/server.ts --bundle --platform=node --format=esm --target=node20 --external:@modelcontextprotocol/sdk --outfile=dist/mcp/server.js",
|
|
15
|
+
"start": "node dist/mcp/server.js",
|
|
16
|
+
"verify:esm": "node -e \"import('./dist/mcp/server.js').then(() => console.log('ESM OK')).catch((e) => { console.error(e); process.exit(1); })\"",
|
|
17
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
18
|
+
"check": "npm run build && npm run verify:esm && node --test test/*.test.mjs",
|
|
19
|
+
"prepublishOnly": "npm run check"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^22.0.0",
|
|
26
|
+
"esbuild": "^0.24.0",
|
|
27
|
+
"typescript": "^5.6.0"
|
|
28
|
+
}
|
|
29
|
+
}
|