smart-thinking-mcp
Version:
Un serveur MCP avancé pour le raisonnement multi-dimensionnel, adaptatif et collaboratif
286 lines (282 loc) • 13.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FetchSchema = exports.SearchSchema = exports.SmartThinkingParamsSchema = void 0;
exports.createSmartThinkingServer = createSmartThinkingServer;
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const zod_1 = require("zod");
const environment_1 = require("./environment");
const ThoughtTypeEnum = zod_1.z.enum(['regular', 'revision', 'meta', 'hypothesis', 'conclusion']);
const ConnectionTypeEnum = zod_1.z.enum([
'supports', 'contradicts', 'refines', 'branches', 'derives', 'associates',
'exemplifies', 'generalizes', 'compares', 'contrasts', 'questions',
'extends', 'analyzes', 'synthesizes', 'applies', 'evaluates', 'cites',
'extended-by', 'analyzed-by', 'component-of', 'applied-by', 'evaluated-by', 'cited-by'
]);
const TemporalityEnum = zod_1.z.enum(['before', 'after', 'during', 'concurrent']);
const CertaintyEnum = zod_1.z.enum(['definite', 'high', 'moderate', 'low', 'speculative']);
const DirectionalityEnum = zod_1.z.enum(['unidirectional', 'bidirectional', 'multidirectional']);
const ScopeEnum = zod_1.z.enum(['broad', 'specific', 'partial', 'complete']);
const NatureEnum = zod_1.z.enum(['causal', 'correlational', 'sequential', 'hierarchical', 'associative']);
const VisualizationTypeEnum = zod_1.z.enum(['graph', 'chronological', 'thematic', 'hierarchical', 'force', 'radial']);
const ClusterByEnum = zod_1.z.enum(['type', 'theme', 'metric', 'connectivity']);
const DirectionEnum = zod_1.z.enum(['LR', 'RL', 'TB', 'BT']);
const ConnectionAttributesSchema = zod_1.z.object({
temporality: TemporalityEnum.optional(),
certainty: CertaintyEnum.optional(),
directionality: DirectionalityEnum.optional(),
scope: ScopeEnum.optional(),
nature: NatureEnum.optional(),
customAttributes: zod_1.z.record(zod_1.z.string()).optional()
});
const ConnectionSchema = zod_1.z.object({
targetId: zod_1.z.string().describe('ID de la pensée cible'),
type: ConnectionTypeEnum.describe('Type de connexion'),
strength: zod_1.z.number().min(0).max(1).describe('Force de la connexion (0 à 1)'),
description: zod_1.z.string().optional().describe('Description optionnelle de la connexion'),
attributes: ConnectionAttributesSchema.optional(),
inferred: zod_1.z.boolean().optional().describe('Si la connexion a été inférée automatiquement'),
inferenceConfidence: zod_1.z.number().min(0).max(1).optional().describe('Confiance dans l\'inférence (0 à 1)'),
bidirectional: zod_1.z.boolean().optional().describe('Si la relation est intrinsèquement bidirectionnelle')
});
const MetricThresholdsSchema = zod_1.z.object({
confidence: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional(),
relevance: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional(),
quality: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional()
});
const FilterOptionsSchema = zod_1.z.object({
nodeTypes: zod_1.z.array(ThoughtTypeEnum).optional(),
connectionTypes: zod_1.z.array(ConnectionTypeEnum).optional(),
metricThresholds: MetricThresholdsSchema.optional(),
textSearch: zod_1.z.string().optional(),
dateRange: zod_1.z.tuple([zod_1.z.date(), zod_1.z.date()]).optional(),
customFilters: zod_1.z.record(zod_1.z.unknown()).optional()
}).optional();
const InteractivityOptionsSchema = zod_1.z.object({
zoomable: zod_1.z.boolean().optional(),
draggable: zod_1.z.boolean().optional(),
selectable: zod_1.z.boolean().optional(),
tooltips: zod_1.z.boolean().optional(),
expandableNodes: zod_1.z.boolean().optional(),
initialZoom: zod_1.z.number().optional(),
zoomRange: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional(),
highlightOnHover: zod_1.z.boolean().optional()
}).optional();
const VisualizationOptionsSchema = zod_1.z.object({
clusterBy: ClusterByEnum.optional().describe('Critère de regroupement des nœuds en clusters'),
direction: DirectionEnum.optional().default('TB').describe('Direction de la disposition hiérarchique'),
centerNode: zod_1.z.string().optional().describe('ID du nœud central pour les visualisations radiales ou hiérarchiques'),
maxDepth: zod_1.z.number().optional().describe('Profondeur maximale pour les visualisations hiérarchiques ou radiales'),
filters: FilterOptionsSchema.describe('Options de filtrage des nœuds et des liens'),
interactivity: InteractivityOptionsSchema.describe('Options d\'interactivité pour la visualisation')
}).optional();
exports.SmartThinkingParamsSchema = zod_1.z.object({
thought: zod_1.z.string().describe('Le contenu de la pensée à analyser - PARAMÈTRE OBLIGATOIRE'),
thoughtType: ThoughtTypeEnum.default('regular').describe('Type de pensée dans le graphe de raisonnement'),
connections: zod_1.z.array(ConnectionSchema).default([]).describe('Connexions à d\'autres pensées'),
requestSuggestions: zod_1.z.boolean().default(false).describe('Demander des suggestions d\'amélioration du raisonnement'),
generateVisualization: zod_1.z.boolean().default(false).describe('Générer une visualisation du graphe de pensée'),
visualizationType: VisualizationTypeEnum.default('graph').describe('Type de visualisation à générer'),
suggestTools: zod_1.z.boolean().default(true).describe('Suggérer des outils MCP pertinents pour cette étape du raisonnement'),
sessionId: zod_1.z.string().optional().describe('Identifiant de session pour maintenir l\'état'),
userId: zod_1.z.string().optional().describe('Identifiant de l\'utilisateur pour la personnalisation'),
help: zod_1.z.boolean().default(true).describe('Afficher le guide d\'utilisation complet'),
requestVerification: zod_1.z.boolean().default(false).describe('Demander explicitement une vérification des informations'),
containsCalculations: zod_1.z.boolean().default(false).describe('Indique si la pensée contient des calculs à vérifier'),
visualizationOptions: VisualizationOptionsSchema.describe('Options avancées pour la visualisation')
});
const SearchParamsSchema = zod_1.z.object({
query: zod_1.z.string().min(1, 'La requête de recherche est obligatoire'),
limit: zod_1.z.number().int().min(1).max(20).optional().default(5),
sessionId: zod_1.z.string().optional()
});
const FetchParamsSchema = zod_1.z.object({
id: zod_1.z.string().min(1, 'Identifiant requis'),
sessionId: zod_1.z.string().optional()
});
function formatMemoryTitle(memory) {
if (memory.metadata?.title) {
return memory.metadata.title;
}
if (memory.tags.length > 0) {
return memory.tags.join(' · ');
}
return `Mémoire ${memory.id.slice(0, 8)}`;
}
function createSmartThinkingTool(server, env) {
server.tool('smartthinking', exports.SmartThinkingParamsSchema.shape, async (params) => {
if (params.help && !params.thought) {
return {
content: [
{
type: 'text',
text: `# Smart-Thinking - Guide d'utilisation
Smart-Thinking est un outil de raisonnement multi-dimensionnel qui organise les pensées en graphe plutôt qu'en séquence linéaire, permettant une analyse plus riche et interconnectée des problèmes complexes.
## Paramètres principaux
- thought (obligatoire) : pensée à analyser
- thoughtType : regular | revision | meta | hypothesis | conclusion
- connections : [{ targetId, type, strength }]
- requestSuggestions : activer les recommandations
- generateVisualization : produire un graphe
- requestVerification : lancer une vérification explicite
- containsCalculations : vérifier les calculs mathématiques
## Types de visualisation
- graph, chronological, thematic, hierarchical, force, radial
## Exemple d'utilisation
thought: "L'intelligence artificielle transformera le marché du travail"
thoughtType: "hypothesis"
generateVisualization: true`
}
]
};
}
if (!params.thought) {
return {
isError: true,
content: [
{
type: 'text',
text: JSON.stringify({
error: "Le paramètre 'thought' est obligatoire.",
message: "Vous devez fournir une pensée à analyser."
}, null, 2)
}
]
};
}
const { response, sessionId } = await env.orchestrator.run(params);
const payload = {
...response,
sessionId
};
return {
content: [
{
type: 'text',
text: JSON.stringify(payload, null, 2)
}
],
structuredContent: payload
};
});
}
function createSearchTool(server, env) {
server.tool('search', 'Recherche les pensées et mémoires Smart-Thinking pertinentes pour la requête', SearchParamsSchema.shape, async ({ query, limit = 5, sessionId }) => {
const matches = await env.memoryManager.getRelevantMemories(query, limit, sessionId);
const results = matches.map(memory => {
const snippet = memory.content.length > 240 ? `${memory.content.slice(0, 240)}...` : memory.content;
const metadata = {};
if (memory.relevanceScore !== undefined) {
metadata.score = memory.relevanceScore;
}
if (memory.tags.length > 0) {
metadata.tags = memory.tags;
}
const memorySessionId = memory.metadata?.sessionId ?? null;
if (memorySessionId) {
metadata.sessionId = memorySessionId;
}
const timestamp = memory.timestamp instanceof Date ? memory.timestamp.toISOString() : memory.timestamp;
if (timestamp) {
metadata.timestamp = timestamp;
}
const result = {
id: memory.id,
title: formatMemoryTitle(memory),
text: snippet,
};
const sourceUrl = memory.metadata?.source;
if (typeof sourceUrl === 'string' && sourceUrl.trim().length > 0) {
result.url = sourceUrl;
}
if (Object.keys(metadata).length > 0) {
result.metadata = metadata;
}
return result;
});
const payload = { results };
return {
content: [
{
type: 'text',
text: JSON.stringify(payload, null, 2)
}
],
structuredContent: payload
};
});
}
function createFetchTool(server, env) {
server.tool('fetch', 'Récupère le contenu complet d\'une mémoire Smart-Thinking par identifiant', FetchParamsSchema.shape, async ({ id }) => {
const memory = env.memoryManager.getMemory(id);
if (!memory) {
return {
isError: true,
content: [
{
type: 'text',
text: JSON.stringify({
error: 'Mémoire introuvable',
id
}, null, 2)
}
]
};
}
const timestamp = memory.timestamp instanceof Date ? memory.timestamp.toISOString() : memory.timestamp;
const metadata = {
tags: memory.tags,
};
if (memory.metadata?.sessionId) {
metadata.sessionId = memory.metadata.sessionId;
}
if (timestamp) {
metadata.timestamp = timestamp;
}
if (memory.relevanceScore !== undefined) {
metadata.score = memory.relevanceScore;
}
const additionalMetadata = { ...memory.metadata };
if (additionalMetadata) {
delete additionalMetadata.source;
}
if (additionalMetadata && Object.keys(additionalMetadata).length > 0) {
metadata.additional = additionalMetadata;
}
const payload = {
id: memory.id,
title: formatMemoryTitle(memory),
text: memory.content,
metadata
};
const sourceUrl = memory.metadata?.source;
if (typeof sourceUrl === 'string' && sourceUrl.trim().length > 0) {
payload.url = sourceUrl;
}
return {
content: [
{
type: 'text',
text: JSON.stringify(payload, null, 2)
}
],
structuredContent: payload
};
});
}
function createSmartThinkingServer(env, options) {
const environment = env ?? (0, environment_1.getSmartThinkingEnvironment)();
const server = new mcp_js_1.McpServer({
name: 'smart-thinking-mcp',
version: environment.version
}, { capabilities: {} });
const { includeSmartThinkingTool = true } = options ?? {};
if (includeSmartThinkingTool) {
createSmartThinkingTool(server, environment);
}
createSearchTool(server, environment);
createFetchTool(server, environment);
return { server, env: environment };
}
exports.SearchSchema = SearchParamsSchema;
exports.FetchSchema = FetchParamsSchema;
//# sourceMappingURL=smart-thinking-server.js.map