@jungjaehoon/mama-server 1.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/package.json +53 -0
- package/src/mama/config-loader.js +218 -0
- package/src/mama/db-adapter/README.md +105 -0
- package/src/mama/db-adapter/base-adapter.js +91 -0
- package/src/mama/db-adapter/index.js +31 -0
- package/src/mama/db-adapter/sqlite-adapter.js +342 -0
- package/src/mama/db-adapter/statement.js +127 -0
- package/src/mama/db-manager.js +584 -0
- package/src/mama/debug-logger.js +78 -0
- package/src/mama/decision-formatter.js +1180 -0
- package/src/mama/decision-tracker.js +565 -0
- package/src/mama/embedding-cache.js +221 -0
- package/src/mama/embeddings.js +265 -0
- package/src/mama/hook-metrics.js +403 -0
- package/src/mama/mama-api.js +913 -0
- package/src/mama/memory-inject.js +243 -0
- package/src/mama/memory-store.js +89 -0
- package/src/mama/ollama-client.js +387 -0
- package/src/mama/outcome-tracker.js +349 -0
- package/src/mama/query-intent.js +236 -0
- package/src/mama/relevance-scorer.js +283 -0
- package/src/mama/time-formatter.js +82 -0
- package/src/mama/transparency-banner.js +301 -0
- package/src/server.js +290 -0
- package/src/tools/checkpoint-tools.js +76 -0
- package/src/tools/index.js +54 -0
- package/src/tools/list-decisions.js +76 -0
- package/src/tools/recall-decision.js +75 -0
- package/src/tools/save-decision.js +113 -0
- package/src/tools/suggest-decision.js +84 -0
- package/src/tools/update-outcome.js +128 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: suggest_decision
|
|
3
|
+
*
|
|
4
|
+
* Story M1.3: MCP Tool - suggest_decision (ported from mcp-server)
|
|
5
|
+
* Priority: P1 (Core Feature)
|
|
6
|
+
*
|
|
7
|
+
* Auto-suggests relevant past decisions based on semantic search.
|
|
8
|
+
*
|
|
9
|
+
* @module suggest-decision
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const mama = require('../mama/mama-api.js');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Suggest decision tool definition
|
|
16
|
+
*/
|
|
17
|
+
const suggestDecisionTool = {
|
|
18
|
+
name: 'suggest_decision',
|
|
19
|
+
description:
|
|
20
|
+
"Auto-suggest relevant past decisions based on user's question. Uses semantic search to find decisions related to the current context. Returns null if no relevant decisions found. Supports multilingual queries (English, Korean, etc.).",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
userQuestion: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description:
|
|
27
|
+
"User's question or intent (e.g., 'How should I handle authentication?', 'What about mesh count?'). The tool will perform semantic search to find relevant past decisions.",
|
|
28
|
+
},
|
|
29
|
+
recencyWeight: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description:
|
|
32
|
+
'Optional: How much to weight recency vs semantic similarity (0-1). Default: 0.3 (70% semantic, 30% recency).',
|
|
33
|
+
minimum: 0,
|
|
34
|
+
maximum: 1,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: ['userQuestion'],
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
async handler(params, context) {
|
|
41
|
+
const { userQuestion, recencyWeight, recencyScale, recencyDecay, disableRecency } = params || {};
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Validation
|
|
45
|
+
if (!userQuestion || typeof userQuestion !== 'string' || userQuestion.trim() === '') {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
message: '❌ Validation error: userQuestion must be a non-empty string',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Call MAMA API with markdown format
|
|
53
|
+
const suggestions = await mama.suggest(userQuestion, {
|
|
54
|
+
format: 'markdown',
|
|
55
|
+
recencyWeight,
|
|
56
|
+
recencyScale,
|
|
57
|
+
recencyDecay,
|
|
58
|
+
disableRecency,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (!suggestions) {
|
|
62
|
+
// No relevant decisions found (graceful)
|
|
63
|
+
return {
|
|
64
|
+
success: true,
|
|
65
|
+
message: '💡 No relevant past decisions found for this question.',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
success: true,
|
|
71
|
+
suggestions,
|
|
72
|
+
message: suggestions,
|
|
73
|
+
};
|
|
74
|
+
} catch (error) {
|
|
75
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
message: `❌ Failed to suggest decisions: ${errorMessage}`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
module.exports = { suggestDecisionTool };
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: update_outcome
|
|
3
|
+
*
|
|
4
|
+
* Story M1.5: MCP Tool - update_outcome (deferred from M1.3)
|
|
5
|
+
* Priority: P1 (Core Feature)
|
|
6
|
+
*
|
|
7
|
+
* Updates decision outcomes based on real-world results.
|
|
8
|
+
* Enables tracking success/failure of decisions over time.
|
|
9
|
+
*
|
|
10
|
+
* @module update-outcome
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const mama = require('../mama/mama-api.js');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Update outcome tool definition
|
|
17
|
+
*/
|
|
18
|
+
const updateOutcomeTool = {
|
|
19
|
+
name: 'update_outcome',
|
|
20
|
+
description:
|
|
21
|
+
"Update a decision's outcome based on real-world results. Use this to mark decisions as SUCCESS, FAILED, or PARTIAL after implementation/validation. This enables tracking decision success rates and surfacing failures for improvement.\n\n⚡ OUTCOME TYPES:\n• SUCCESS: Decision worked as expected\n• FAILED: Decision caused problems (provide failure_reason)\n• PARTIAL: Decision partially worked (provide limitation)\n\n⚡ USE CASES:\n• After testing: Mark experimental decisions as SUCCESS/FAILED\n• After deployment: Update outcomes based on production metrics\n• After user feedback: Capture failure reasons from complaints",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
decisionId: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description:
|
|
28
|
+
"Decision ID to update (e.g., 'decision_auth_strategy_123456_abc'). Get this from recall_decision or list_decisions responses.",
|
|
29
|
+
},
|
|
30
|
+
outcome: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
enum: ['SUCCESS', 'FAILED', 'PARTIAL'],
|
|
33
|
+
description:
|
|
34
|
+
"Outcome status:\n• 'SUCCESS': Decision worked well in practice\n• 'FAILED': Decision caused problems (explain in failure_reason)\n• 'PARTIAL': Decision partially worked (explain in limitation)",
|
|
35
|
+
},
|
|
36
|
+
failure_reason: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description:
|
|
39
|
+
"Why the decision failed (REQUIRED if outcome='FAILED'). Examples: 'Performance degraded under load', 'Security vulnerability found', 'User complaints about complexity'. Max 2000 characters.",
|
|
40
|
+
},
|
|
41
|
+
limitation: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description:
|
|
44
|
+
"What limitations were discovered (OPTIONAL for outcome='PARTIAL'). Examples: 'Works for most cases but fails with large datasets', 'Acceptable for MVP but needs optimization'. Max 2000 characters.",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
required: ['decisionId', 'outcome'],
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
async handler(params, context) {
|
|
51
|
+
const { decisionId, outcome, failure_reason, limitation } = params || {};
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Validation: Required fields
|
|
55
|
+
if (!decisionId || typeof decisionId !== 'string' || decisionId.trim() === '') {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
message: '❌ Validation error: decisionId must be a non-empty string',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!outcome || !['SUCCESS', 'FAILED', 'PARTIAL'].includes(outcome)) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
message: '❌ Validation error: outcome must be "SUCCESS", "FAILED", or "PARTIAL"',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Validation: failure_reason required for FAILED
|
|
70
|
+
if (outcome === 'FAILED' && (!failure_reason || failure_reason.trim() === '')) {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
message:
|
|
74
|
+
'❌ Validation error: failure_reason is required when outcome="FAILED" (explain what went wrong)',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Validation: Field lengths
|
|
79
|
+
if (failure_reason && failure_reason.length > 2000) {
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
message: `❌ Validation error: failure_reason must be ≤ 2000 characters (got ${failure_reason.length})`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (limitation && limitation.length > 2000) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
message: `❌ Validation error: limitation must be ≤ 2000 characters (got ${limitation.length})`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Call MAMA API
|
|
94
|
+
await mama.updateOutcome(decisionId, {
|
|
95
|
+
outcome,
|
|
96
|
+
failure_reason,
|
|
97
|
+
limitation,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Return success response
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
decision_id: decisionId,
|
|
104
|
+
outcome,
|
|
105
|
+
message: `✅ Decision outcome updated to ${outcome}${
|
|
106
|
+
failure_reason ? `\n Reason: ${failure_reason.substring(0, 100)}${failure_reason.length > 100 ? '...' : ''}` : ''
|
|
107
|
+
}${limitation ? `\n Limitation: ${limitation.substring(0, 100)}${limitation.length > 100 ? '...' : ''}` : ''}`,
|
|
108
|
+
};
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
111
|
+
|
|
112
|
+
// Check for common errors
|
|
113
|
+
if (errorMessage.includes('not found')) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
message: `❌ Decision not found: ${decisionId}\n\nUse recall_decision or list_decisions to find valid decision IDs.`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
message: `❌ Failed to update outcome: ${errorMessage}`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
module.exports = { updateOutcomeTool };
|