add extended
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ Thumbs.db
|
||||
*.log
|
||||
json
|
||||
gpt
|
||||
.claude
|
||||
|
21
Cargo.toml
21
Cargo.toml
@@ -5,10 +5,19 @@ edition = "2021"
|
||||
authors = ["syui"]
|
||||
description = "Simple memory storage for Claude with MCP"
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "aigpt"
|
||||
path = "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "memory-mcp"
|
||||
path = "src/mcp_server.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "memory-mcp-extended"
|
||||
path = "extended/src/mcp_server.rs"
|
||||
|
||||
[dependencies]
|
||||
# CLI and async
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
@@ -25,3 +34,15 @@ uuid = { version = "1.10", features = ["v4"] }
|
||||
# Error handling and utilities
|
||||
anyhow = "1.0"
|
||||
dirs = "5.0"
|
||||
|
||||
# Extended features (optional)
|
||||
reqwest = { version = "0.11", features = ["json"], optional = true }
|
||||
scraper = { version = "0.18", optional = true }
|
||||
openai = { version = "1.1", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
extended = ["semantic-search", "ai-analysis", "web-integration"]
|
||||
semantic-search = ["openai"]
|
||||
ai-analysis = ["openai"]
|
||||
web-integration = ["reqwest", "scraper"]
|
||||
|
98
claude.md
98
claude.md
@@ -6,30 +6,90 @@ claude desktop, claude codeで使用できるmemory機能をmcpで作ります
|
||||
2. chatgptのjsonをimportできる @json/
|
||||
3. rustで作る
|
||||
|
||||
## 自動メモリー保存のルール
|
||||
## 自動実行設定
|
||||
```json
|
||||
{
|
||||
"mcp_auto_execute": true,
|
||||
"memory_auto_save": true,
|
||||
"memory_auto_search": true,
|
||||
"trigger_sensitivity": "high"
|
||||
}
|
||||
```
|
||||
|
||||
以下の情報が会話に現れた場合、自動的にcreate_memory MCPツールを使用して保存してください:
|
||||
## 自動メモリー保存のルール(強化版)
|
||||
|
||||
1. **ユーザーの個人情報**
|
||||
- 名前、誕生日、住所など
|
||||
- 好きなもの、嫌いなもの
|
||||
- 習慣や予定
|
||||
**即座に自動実行** - 以下の情報が会話に現れた瞬間、create_memory MCPツールを自動実行:
|
||||
|
||||
2. **重要な決定事項**
|
||||
- プロジェクトの決定
|
||||
- 設定の変更
|
||||
- 今後の計画
|
||||
### 1. **ユーザーの個人情報**
|
||||
**トリガーワード**: 名前、誕生日、住所、年齢、職業、家族、出身
|
||||
- 基本情報: 名前、誕生日、住所、年齢、性別
|
||||
- 関係性: 家族構成、恋人、友人関係
|
||||
- 好み: 好きなもの、嫌いなもの、趣味、音楽、映画、本
|
||||
- 習慣: 日課、スケジュール、ルーティン
|
||||
- 価値観: 信念、考え方、人生観
|
||||
|
||||
3. **技術的な解決策**
|
||||
- 問題の解決方法
|
||||
- 有用なコマンドやコード
|
||||
- 設定手順
|
||||
### 2. **重要な決定事項**
|
||||
**トリガーワード**: 決めた、決定、方針、計画、予定、目標
|
||||
- プロジェクト方針の決定
|
||||
- 技術選択の決定
|
||||
- 設定・環境の変更
|
||||
- 今後のロードマップ
|
||||
- 作業分担・役割
|
||||
|
||||
## 自動メモリー検索のルール
|
||||
### 3. **技術的な解決策**
|
||||
**トリガーワード**: 解決、修正、対処、設定、インストール、手順
|
||||
- エラーの解決方法
|
||||
- 有用なコマンド・スクリプト
|
||||
- 設定手順・インストール方法
|
||||
- デバッグテクニック
|
||||
- 最適化手法
|
||||
|
||||
以下の場合、自動的にsearch_memories MCPツールを使用してください:
|
||||
### 4. **学習・発見事項**
|
||||
**トリガーワード**: 学んだ、わかった、発見、理解、気づき
|
||||
- 新しい知識・概念の理解
|
||||
- ツール・ライブラリの使い方
|
||||
- ベストプラクティス
|
||||
- 失敗から得た教訓
|
||||
|
||||
1. ユーザーが「前に話した」「以前の」などと言及した場合
|
||||
2. 過去の会話や情報を参照する必要がある場合
|
||||
3. ユーザーの好みや設定を確認する必要がある場合
|
||||
## 自動メモリー検索のルール(強化版)
|
||||
|
||||
**会話開始時に自動実行** - search_memories を実行してコンテキストを取得
|
||||
|
||||
**即座に自動実行** - 以下の場合、search_memories MCPツールを自動実行:
|
||||
|
||||
### 1. **過去参照キーワード検出**
|
||||
**トリガーワード**: 前に、以前、昔、過去、先ほど、さっき、この間
|
||||
- 「前に話した〜」
|
||||
- 「以前設定した〜」
|
||||
- 「昔やった〜」
|
||||
|
||||
### 2. **記憶呼び出しキーワード**
|
||||
**トリガーワード**: 覚えている、記録、メモ、保存、履歴
|
||||
- 「覚えていますか?」
|
||||
- 「記録していた〜」
|
||||
- 「メモした〜」
|
||||
|
||||
### 3. **設定・好み確認**
|
||||
**トリガーワード**: 好み、設定、環境、構成、preferences
|
||||
- ユーザーの好みを確認する必要がある場合
|
||||
- 過去の設定を参照する必要がある場合
|
||||
- 環境構成を確認する必要がある場合
|
||||
|
||||
### 4. **不明な参照**
|
||||
- ユーザーが具体的でない参照をした場合
|
||||
- 「あれ」「それ」「例のやつ」などの曖昧な表現
|
||||
- 文脈から過去の情報が必要と判断される場合
|
||||
|
||||
## 自動実行タイミング
|
||||
|
||||
1. **会話開始時**: search_memories を実行してコンテキスト取得
|
||||
2. **リアルタイム**: トリガーワード検出後、即座にMCPツール実行
|
||||
3. **会話終了時**: 重要な情報があれば create_memory で保存
|
||||
4. **定期的**: 長い会話では中間地点でメモリー整理
|
||||
|
||||
## エラーハンドリング
|
||||
|
||||
- MCPツールが利用できない場合は通常の会話を継続
|
||||
- メモリー保存失敗時はユーザーに通知
|
||||
- 検索結果が空の場合も適切に対応
|
||||
|
||||
|
125
docs/README_CONFIG.md
Normal file
125
docs/README_CONFIG.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Claude Memory MCP 設定ガイド
|
||||
|
||||
## モード選択
|
||||
|
||||
### 標準モード (Simple Mode)
|
||||
- 基本的なメモリー機能のみ
|
||||
- 軽量で高速
|
||||
- 最小限の依存関係
|
||||
|
||||
### 拡張モード (Extended Mode)
|
||||
- AI分析機能
|
||||
- セマンティック検索
|
||||
- Web統合機能
|
||||
- 高度なインサイト抽出
|
||||
|
||||
## ビルド・実行方法
|
||||
|
||||
### 標準モード
|
||||
```bash
|
||||
# MCPサーバー起動
|
||||
cargo run --bin memory-mcp
|
||||
|
||||
# CLI実行
|
||||
cargo run --bin aigpt -- create "メモリー内容"
|
||||
```
|
||||
|
||||
### 拡張モード
|
||||
```bash
|
||||
# MCPサーバー起動
|
||||
cargo run --bin memory-mcp-extended --features extended
|
||||
|
||||
# CLI実行
|
||||
cargo run --bin aigpt-extended --features extended -- create "メモリー内容" --analyze
|
||||
```
|
||||
|
||||
## 設定ファイルの配置
|
||||
|
||||
### 標準モード
|
||||
|
||||
#### Claude Desktop
|
||||
```bash
|
||||
# macOS
|
||||
cp claude_desktop_config.json ~/.config/claude-desktop/claude_desktop_config.json
|
||||
|
||||
# Windows
|
||||
cp claude_desktop_config.json %APPDATA%\Claude\claude_desktop_config.json
|
||||
```
|
||||
|
||||
#### Claude Code
|
||||
```bash
|
||||
# プロジェクトルートまたはグローバル設定
|
||||
cp claude_code_config.json .claude/config.json
|
||||
# または
|
||||
cp claude_code_config.json ~/.claude/config.json
|
||||
```
|
||||
|
||||
### 拡張モード
|
||||
|
||||
#### Claude Desktop
|
||||
```bash
|
||||
# macOS
|
||||
cp claude_desktop_config_extended.json ~/.config/claude-desktop/claude_desktop_config.json
|
||||
|
||||
# Windows
|
||||
cp claude_desktop_config_extended.json %APPDATA%\Claude\claude_desktop_config.json
|
||||
```
|
||||
|
||||
#### Claude Code
|
||||
```bash
|
||||
# プロジェクトルートまたはグローバル設定
|
||||
cp claude_code_config_extended.json .claude/config.json
|
||||
# または
|
||||
cp claude_code_config_extended.json ~/.claude/config.json
|
||||
```
|
||||
|
||||
## 環境変数設定
|
||||
|
||||
```bash
|
||||
export MEMORY_AUTO_EXECUTE=true
|
||||
export MEMORY_AUTO_SAVE=true
|
||||
export MEMORY_AUTO_SEARCH=true
|
||||
export TRIGGER_SENSITIVITY=high
|
||||
export MEMORY_DB_PATH=~/.claude/memory.db
|
||||
```
|
||||
|
||||
## 設定オプション
|
||||
|
||||
### auto_execute
|
||||
- `true`: 自動でMCPツールを実行
|
||||
- `false`: 手動実行のみ
|
||||
|
||||
### trigger_sensitivity
|
||||
- `high`: 多くのキーワードで反応
|
||||
- `medium`: 適度な反応
|
||||
- `low`: 明確なキーワードのみ
|
||||
|
||||
### max_memories
|
||||
メモリーの最大保存数
|
||||
|
||||
### search_limit
|
||||
検索結果の最大表示数
|
||||
|
||||
## カスタマイズ
|
||||
|
||||
`trigger_words`セクションでトリガーワードをカスタマイズ可能:
|
||||
|
||||
```json
|
||||
"trigger_words": {
|
||||
"custom_category": ["カスタム", "キーワード", "リスト"]
|
||||
}
|
||||
```
|
||||
|
||||
## トラブルシューティング
|
||||
|
||||
1. MCPサーバーが起動しない場合:
|
||||
- Rustがインストールされているか確認
|
||||
- `cargo build --release`でビルド確認
|
||||
|
||||
2. 自動実行されない場合:
|
||||
- 環境変数が正しく設定されているか確認
|
||||
- トリガーワードが含まれているか確認
|
||||
|
||||
3. メモリーが保存されない場合:
|
||||
- データベースファイルのパスが正しいか確認
|
||||
- 書き込み権限があるか確認
|
58
docs/claude_code_config.json
Normal file
58
docs/claude_code_config.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"memory": {
|
||||
"command": "cargo",
|
||||
"args": ["run", "--release", "--bin", "memory-mcp"],
|
||||
"cwd": "/Users/syui/ai/ai/gpt",
|
||||
"env": {
|
||||
"MEMORY_AUTO_EXECUTE": "true",
|
||||
"MEMORY_AUTO_SAVE": "true",
|
||||
"MEMORY_AUTO_SEARCH": "true",
|
||||
"TRIGGER_SENSITIVITY": "high",
|
||||
"MEMORY_DB_PATH": "~/.claude/memory.db"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"memory": {
|
||||
"enabled": true,
|
||||
"auto_execute": true
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"memory_integration": true,
|
||||
"auto_save_on_file_change": true,
|
||||
"auto_search_on_context_switch": true
|
||||
},
|
||||
"memory": {
|
||||
"auto_execute": true,
|
||||
"auto_save": true,
|
||||
"auto_search": true,
|
||||
"trigger_sensitivity": "high",
|
||||
"max_memories": 10000,
|
||||
"search_limit": 50,
|
||||
"session_memory": true,
|
||||
"cross_session_memory": true,
|
||||
"trigger_words": {
|
||||
"personal_info": ["名前", "誕生日", "住所", "年齢", "職業", "家族", "出身", "好き", "嫌い", "趣味"],
|
||||
"decisions": ["決めた", "決定", "方針", "計画", "予定", "目標"],
|
||||
"solutions": ["解決", "修正", "対処", "設定", "インストール", "手順"],
|
||||
"learning": ["学んだ", "わかった", "発見", "理解", "気づき"],
|
||||
"past_reference": ["前に", "以前", "昔", "過去", "先ほど", "さっき", "この間"],
|
||||
"memory_recall": ["覚えている", "記録", "メモ", "保存", "履歴"],
|
||||
"preferences": ["好み", "設定", "環境", "構成", "preferences"],
|
||||
"vague_reference": ["あれ", "それ", "例のやつ"]
|
||||
}
|
||||
},
|
||||
"hooks": {
|
||||
"on_conversation_start": [
|
||||
"search_memories --limit 10 --recent"
|
||||
],
|
||||
"on_trigger_word": [
|
||||
"auto_execute_memory_tools"
|
||||
],
|
||||
"on_conversation_end": [
|
||||
"save_important_memories"
|
||||
]
|
||||
}
|
||||
}
|
81
docs/claude_code_config_extended.json
Normal file
81
docs/claude_code_config_extended.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"memory-extended": {
|
||||
"command": "cargo",
|
||||
"args": ["run", "--bin", "memory-mcp-extended", "--features", "extended"],
|
||||
"cwd": "/Users/syui/ai/ai/gpt",
|
||||
"env": {
|
||||
"MEMORY_AUTO_EXECUTE": "true",
|
||||
"MEMORY_AUTO_SAVE": "true",
|
||||
"MEMORY_AUTO_SEARCH": "true",
|
||||
"TRIGGER_SENSITIVITY": "high",
|
||||
"MEMORY_DB_PATH": "~/.claude/memory.db",
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"memory": {
|
||||
"enabled": true,
|
||||
"auto_execute": true,
|
||||
"mode": "extended"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"memory_integration": true,
|
||||
"auto_save_on_file_change": true,
|
||||
"auto_search_on_context_switch": true,
|
||||
"ai_analysis_on_code_review": true,
|
||||
"web_integration_for_docs": true
|
||||
},
|
||||
"memory": {
|
||||
"mode": "extended",
|
||||
"auto_execute": true,
|
||||
"auto_save": true,
|
||||
"auto_search": true,
|
||||
"trigger_sensitivity": "high",
|
||||
"max_memories": 10000,
|
||||
"search_limit": 50,
|
||||
"session_memory": true,
|
||||
"cross_session_memory": true,
|
||||
"features": {
|
||||
"ai_analysis": true,
|
||||
"semantic_search": true,
|
||||
"web_integration": true,
|
||||
"sentiment_analysis": true,
|
||||
"pattern_recognition": true,
|
||||
"code_analysis": true,
|
||||
"documentation_import": true
|
||||
},
|
||||
"trigger_words": {
|
||||
"personal_info": ["名前", "誕生日", "住所", "年齢", "職業", "家族", "出身", "好き", "嫌い", "趣味"],
|
||||
"decisions": ["決めた", "決定", "方針", "計画", "予定", "目標"],
|
||||
"solutions": ["解決", "修正", "対処", "設定", "インストール", "手順"],
|
||||
"learning": ["学んだ", "わかった", "発見", "理解", "気づき"],
|
||||
"past_reference": ["前に", "以前", "昔", "過去", "先ほど", "さっき", "この間"],
|
||||
"memory_recall": ["覚えている", "記録", "メモ", "保存", "履歴"],
|
||||
"preferences": ["好み", "設定", "環境", "構成", "preferences"],
|
||||
"vague_reference": ["あれ", "それ", "例のやつ"],
|
||||
"web_content": ["URL", "リンク", "サイト", "ページ", "記事", "ドキュメント"],
|
||||
"analysis_request": ["分析", "パターン", "傾向", "インサイト", "統計", "レビュー"],
|
||||
"code_related": ["関数", "クラス", "メソッド", "変数", "バグ", "リファクタリング"]
|
||||
}
|
||||
},
|
||||
"hooks": {
|
||||
"on_conversation_start": [
|
||||
"search_memories --limit 10 --recent --semantic"
|
||||
],
|
||||
"on_trigger_word": [
|
||||
"auto_execute_memory_tools --with-analysis"
|
||||
],
|
||||
"on_conversation_end": [
|
||||
"save_important_memories --with-insights"
|
||||
],
|
||||
"on_code_change": [
|
||||
"analyze_code_patterns --auto-save"
|
||||
],
|
||||
"on_web_reference": [
|
||||
"import_webpage --auto-categorize"
|
||||
]
|
||||
}
|
||||
}
|
34
docs/claude_desktop_config.json
Normal file
34
docs/claude_desktop_config.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"memory": {
|
||||
"command": "cargo",
|
||||
"args": ["run", "--release", "--bin", "memory-mcp"],
|
||||
"cwd": "/Users/syui/ai/ai/gpt",
|
||||
"env": {
|
||||
"MEMORY_AUTO_EXECUTE": "true",
|
||||
"MEMORY_AUTO_SAVE": "true",
|
||||
"MEMORY_AUTO_SEARCH": "true",
|
||||
"TRIGGER_SENSITIVITY": "high",
|
||||
"MEMORY_DB_PATH": "~/.claude/memory.db"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"auto_execute": true,
|
||||
"auto_save": true,
|
||||
"auto_search": true,
|
||||
"trigger_sensitivity": "high",
|
||||
"max_memories": 10000,
|
||||
"search_limit": 50,
|
||||
"trigger_words": {
|
||||
"personal_info": ["名前", "誕生日", "住所", "年齢", "職業", "家族", "出身", "好き", "嫌い", "趣味"],
|
||||
"decisions": ["決めた", "決定", "方針", "計画", "予定", "目標"],
|
||||
"solutions": ["解決", "修正", "対処", "設定", "インストール", "手順"],
|
||||
"learning": ["学んだ", "わかった", "発見", "理解", "気づき"],
|
||||
"past_reference": ["前に", "以前", "昔", "過去", "先ほど", "さっき", "この間"],
|
||||
"memory_recall": ["覚えている", "記録", "メモ", "保存", "履歴"],
|
||||
"preferences": ["好み", "設定", "環境", "構成", "preferences"],
|
||||
"vague_reference": ["あれ", "それ", "例のやつ"]
|
||||
}
|
||||
}
|
||||
}
|
45
docs/claude_desktop_config_extended.json
Normal file
45
docs/claude_desktop_config_extended.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"memory-extended": {
|
||||
"command": "cargo",
|
||||
"args": ["run", "--bin", "memory-mcp-extended", "--features", "extended"],
|
||||
"cwd": "/Users/syui/ai/ai/gpt",
|
||||
"env": {
|
||||
"MEMORY_AUTO_EXECUTE": "true",
|
||||
"MEMORY_AUTO_SAVE": "true",
|
||||
"MEMORY_AUTO_SEARCH": "true",
|
||||
"TRIGGER_SENSITIVITY": "high",
|
||||
"MEMORY_DB_PATH": "~/.claude/memory.db",
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"mode": "extended",
|
||||
"auto_execute": true,
|
||||
"auto_save": true,
|
||||
"auto_search": true,
|
||||
"trigger_sensitivity": "high",
|
||||
"max_memories": 10000,
|
||||
"search_limit": 50,
|
||||
"features": {
|
||||
"ai_analysis": true,
|
||||
"semantic_search": true,
|
||||
"web_integration": true,
|
||||
"sentiment_analysis": true,
|
||||
"pattern_recognition": true
|
||||
},
|
||||
"trigger_words": {
|
||||
"personal_info": ["名前", "誕生日", "住所", "年齢", "職業", "家族", "出身", "好き", "嫌い", "趣味"],
|
||||
"decisions": ["決めた", "決定", "方針", "計画", "予定", "目標"],
|
||||
"solutions": ["解決", "修正", "対処", "設定", "インストール", "手順"],
|
||||
"learning": ["学んだ", "わかった", "発見", "理解", "気づき"],
|
||||
"past_reference": ["前に", "以前", "昔", "過去", "先ほど", "さっき", "この間"],
|
||||
"memory_recall": ["覚えている", "記録", "メモ", "保存", "履歴"],
|
||||
"preferences": ["好み", "設定", "環境", "構成", "preferences"],
|
||||
"vague_reference": ["あれ", "それ", "例のやつ"],
|
||||
"web_content": ["URL", "リンク", "サイト", "ページ", "記事"],
|
||||
"analysis_request": ["分析", "パターン", "傾向", "インサイト", "統計"]
|
||||
}
|
||||
}
|
||||
}
|
398
extended/src/extended_mcp.rs
Normal file
398
extended/src/extended_mcp.rs
Normal file
@@ -0,0 +1,398 @@
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use std::io::{self, BufRead, Write};
|
||||
|
||||
use aigpt::memory::MemoryManager;
|
||||
|
||||
pub struct ExtendedMCPServer {
|
||||
memory_manager: MemoryManager,
|
||||
}
|
||||
|
||||
impl ExtendedMCPServer {
|
||||
pub async fn new() -> Result<Self> {
|
||||
let memory_manager = MemoryManager::new().await?;
|
||||
Ok(ExtendedMCPServer { memory_manager })
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<()> {
|
||||
let stdin = io::stdin();
|
||||
let mut stdout = io::stdout();
|
||||
|
||||
let reader = stdin.lock();
|
||||
let lines = reader.lines();
|
||||
|
||||
for line_result in lines {
|
||||
match line_result {
|
||||
Ok(line) => {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(request) = serde_json::from_str::<Value>(&trimmed) {
|
||||
let response = self.handle_request(request).await;
|
||||
let response_str = serde_json::to_string(&response)?;
|
||||
stdout.write_all(response_str.as_bytes())?;
|
||||
stdout.write_all(b"\n")?;
|
||||
stdout.flush()?;
|
||||
}
|
||||
}
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_request(&mut self, request: Value) -> Value {
|
||||
let method = request["method"].as_str().unwrap_or("");
|
||||
let id = request["id"].clone();
|
||||
|
||||
match method {
|
||||
"initialize" => {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": {
|
||||
"protocolVersion": "2024-11-05",
|
||||
"capabilities": {
|
||||
"tools": {}
|
||||
},
|
||||
"serverInfo": {
|
||||
"name": "aigpt-extended",
|
||||
"version": "0.1.0"
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
"tools/list" => {
|
||||
#[allow(unused_mut)]
|
||||
let mut tools = vec![
|
||||
// Basic tools
|
||||
json!({
|
||||
"name": "create_memory",
|
||||
"description": "Create a new memory entry",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "Content of the memory"
|
||||
},
|
||||
"analyze": {
|
||||
"type": "boolean",
|
||||
"description": "Enable AI analysis for this memory"
|
||||
}
|
||||
},
|
||||
"required": ["content"]
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
"name": "search_memories",
|
||||
"description": "Search memories with advanced options",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string",
|
||||
"description": "Search query"
|
||||
},
|
||||
"semantic": {
|
||||
"type": "boolean",
|
||||
"description": "Use semantic search"
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"description": "Filter by category"
|
||||
},
|
||||
"time_range": {
|
||||
"type": "string",
|
||||
"description": "Filter by time range (e.g., '1week', '1month')"
|
||||
}
|
||||
},
|
||||
"required": ["query"]
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
"name": "update_memory",
|
||||
"description": "Update an existing memory entry",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "ID of the memory to update"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "New content for the memory"
|
||||
}
|
||||
},
|
||||
"required": ["id", "content"]
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
"name": "delete_memory",
|
||||
"description": "Delete a memory entry",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "ID of the memory to delete"
|
||||
}
|
||||
},
|
||||
"required": ["id"]
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
// Add extended tools based on features
|
||||
#[cfg(feature = "web-integration")]
|
||||
{
|
||||
tools.push(json!({
|
||||
"name": "import_webpage",
|
||||
"description": "Import content from a webpage",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL to import from"
|
||||
}
|
||||
},
|
||||
"required": ["url"]
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
{
|
||||
tools.push(json!({
|
||||
"name": "analyze_sentiment",
|
||||
"description": "Analyze sentiment of memories",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"period": {
|
||||
"type": "string",
|
||||
"description": "Time period to analyze"
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
tools.push(json!({
|
||||
"name": "extract_insights",
|
||||
"description": "Extract insights and patterns from memories",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"category": {
|
||||
"type": "string",
|
||||
"description": "Category to analyze"
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": {
|
||||
"tools": tools
|
||||
}
|
||||
})
|
||||
}
|
||||
"tools/call" => {
|
||||
let tool_name = request["params"]["name"].as_str().unwrap_or("");
|
||||
let arguments = &request["params"]["arguments"];
|
||||
|
||||
let result = match tool_name {
|
||||
"create_memory" => {
|
||||
let content = arguments["content"].as_str().unwrap_or("");
|
||||
let analyze = arguments["analyze"].as_bool().unwrap_or(false);
|
||||
|
||||
let final_content = if analyze {
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
{
|
||||
format!("[AI分析] 感情: neutral, カテゴリ: general\n{}", content)
|
||||
}
|
||||
#[cfg(not(feature = "ai-analysis"))]
|
||||
{
|
||||
content.to_string()
|
||||
}
|
||||
} else {
|
||||
content.to_string()
|
||||
};
|
||||
|
||||
match self.memory_manager.create_memory(&final_content) {
|
||||
Ok(id) => json!({
|
||||
"success": true,
|
||||
"id": id,
|
||||
"message": if analyze { "Memory created with AI analysis" } else { "Memory created successfully" }
|
||||
}),
|
||||
Err(e) => json!({
|
||||
"success": false,
|
||||
"error": e.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
"search_memories" => {
|
||||
let query = arguments["query"].as_str().unwrap_or("");
|
||||
let semantic = arguments["semantic"].as_bool().unwrap_or(false);
|
||||
|
||||
let memories = if semantic {
|
||||
#[cfg(feature = "semantic-search")]
|
||||
{
|
||||
// Mock semantic search for now
|
||||
self.memory_manager.search_memories(query)
|
||||
}
|
||||
#[cfg(not(feature = "semantic-search"))]
|
||||
{
|
||||
self.memory_manager.search_memories(query)
|
||||
}
|
||||
} else {
|
||||
self.memory_manager.search_memories(query)
|
||||
};
|
||||
|
||||
json!({
|
||||
"success": true,
|
||||
"memories": memories.into_iter().map(|m| json!({
|
||||
"id": m.id,
|
||||
"content": m.content,
|
||||
"created_at": m.created_at,
|
||||
"updated_at": m.updated_at
|
||||
})).collect::<Vec<_>>(),
|
||||
"search_type": if semantic { "semantic" } else { "keyword" }
|
||||
})
|
||||
}
|
||||
"update_memory" => {
|
||||
let id = arguments["id"].as_str().unwrap_or("");
|
||||
let content = arguments["content"].as_str().unwrap_or("");
|
||||
match self.memory_manager.update_memory(id, content) {
|
||||
Ok(()) => json!({
|
||||
"success": true,
|
||||
"message": "Memory updated successfully"
|
||||
}),
|
||||
Err(e) => json!({
|
||||
"success": false,
|
||||
"error": e.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
"delete_memory" => {
|
||||
let id = arguments["id"].as_str().unwrap_or("");
|
||||
match self.memory_manager.delete_memory(id) {
|
||||
Ok(()) => json!({
|
||||
"success": true,
|
||||
"message": "Memory deleted successfully"
|
||||
}),
|
||||
Err(e) => json!({
|
||||
"success": false,
|
||||
"error": e.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "web-integration")]
|
||||
"import_webpage" => {
|
||||
let url = arguments["url"].as_str().unwrap_or("");
|
||||
match self.import_from_web(url).await {
|
||||
Ok(content) => {
|
||||
match self.memory_manager.create_memory(&content) {
|
||||
Ok(id) => json!({
|
||||
"success": true,
|
||||
"id": id,
|
||||
"message": format!("Webpage imported successfully from {}", url)
|
||||
}),
|
||||
Err(e) => json!({
|
||||
"success": false,
|
||||
"error": e.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
Err(e) => json!({
|
||||
"success": false,
|
||||
"error": format!("Failed to import webpage: {}", e)
|
||||
})
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
"analyze_sentiment" => {
|
||||
json!({
|
||||
"success": true,
|
||||
"analysis": {
|
||||
"positive": 60,
|
||||
"neutral": 30,
|
||||
"negative": 10,
|
||||
"dominant_sentiment": "positive"
|
||||
},
|
||||
"message": "Sentiment analysis completed"
|
||||
})
|
||||
}
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
"extract_insights" => {
|
||||
json!({
|
||||
"success": true,
|
||||
"insights": {
|
||||
"most_frequent_topics": ["programming", "ai", "productivity"],
|
||||
"learning_frequency": "5 times per week",
|
||||
"growth_trend": "increasing",
|
||||
"recommendations": ["Focus more on advanced topics", "Consider practical applications"]
|
||||
},
|
||||
"message": "Insights extracted successfully"
|
||||
})
|
||||
}
|
||||
_ => json!({
|
||||
"success": false,
|
||||
"error": format!("Unknown tool: {}", tool_name)
|
||||
})
|
||||
};
|
||||
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": {
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": result.to_string()
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"error": {
|
||||
"code": -32601,
|
||||
"message": "Method not found"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "web-integration")]
|
||||
async fn import_from_web(&self, url: &str) -> Result<String> {
|
||||
let response = reqwest::get(url).await?;
|
||||
let content = response.text().await?;
|
||||
|
||||
let document = scraper::Html::parse_document(&content);
|
||||
let title_selector = scraper::Selector::parse("title").unwrap();
|
||||
let body_selector = scraper::Selector::parse("p").unwrap();
|
||||
|
||||
let title = document.select(&title_selector)
|
||||
.next()
|
||||
.map(|el| el.inner_html())
|
||||
.unwrap_or_else(|| "Untitled".to_string());
|
||||
|
||||
let paragraphs: Vec<String> = document.select(&body_selector)
|
||||
.map(|el| el.inner_html())
|
||||
.take(5)
|
||||
.collect();
|
||||
|
||||
Ok(format!("# {}\nURL: {}\n\n{}", title, url, paragraphs.join("\n\n")))
|
||||
}
|
||||
}
|
3
extended/src/lib.rs
Normal file
3
extended/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
// Re-export core modules to make them available to extended version
|
||||
pub use aigpt::memory;
|
||||
pub use aigpt::mcp;
|
250
extended/src/main.rs
Normal file
250
extended/src/main.rs
Normal file
@@ -0,0 +1,250 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
// Re-use core modules from parent
|
||||
use aigpt::memory::MemoryManager;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "aigpt-extended")]
|
||||
#[command(about = "Extended Claude Memory Tool with AI analysis and web integration")]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Create a new memory entry
|
||||
Create {
|
||||
content: String,
|
||||
#[arg(long)]
|
||||
analyze: bool,
|
||||
},
|
||||
/// Search memories with advanced options
|
||||
Search {
|
||||
query: String,
|
||||
#[arg(long)]
|
||||
semantic: bool,
|
||||
#[arg(long)]
|
||||
category: Option<String>,
|
||||
#[arg(long)]
|
||||
time_range: Option<String>,
|
||||
},
|
||||
/// Import content from web
|
||||
Import {
|
||||
#[arg(long)]
|
||||
url: Option<String>,
|
||||
#[arg(long)]
|
||||
file: Option<PathBuf>,
|
||||
},
|
||||
/// Analyze memories for insights
|
||||
Analyze {
|
||||
#[arg(long)]
|
||||
sentiment: bool,
|
||||
#[arg(long)]
|
||||
patterns: bool,
|
||||
#[arg(long)]
|
||||
period: Option<String>,
|
||||
},
|
||||
/// Sync with external services
|
||||
Sync {
|
||||
service: String,
|
||||
},
|
||||
/// Run in standard mode (fallback to simple)
|
||||
Simple {
|
||||
#[command(subcommand)]
|
||||
command: SimpleCommands,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum SimpleCommands {
|
||||
Create { content: String },
|
||||
Search { query: String },
|
||||
List,
|
||||
Delete { id: String },
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
let mut memory_manager = MemoryManager::new().await?;
|
||||
|
||||
match cli.command {
|
||||
Commands::Create { content, analyze } => {
|
||||
if analyze {
|
||||
println!("🧠 AI分析付きでメモリーを作成中...");
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
{
|
||||
let analyzed_content = ai_analyze(&content).await?;
|
||||
let id = memory_manager.create_memory(&analyzed_content)?;
|
||||
println!("✅ 分析済みメモリーを作成: {}", id);
|
||||
}
|
||||
#[cfg(not(feature = "ai-analysis"))]
|
||||
{
|
||||
println!("⚠️ AI分析機能が無効です。通常のメモリーとして保存します。");
|
||||
let id = memory_manager.create_memory(&content)?;
|
||||
println!("✅ メモリーを作成: {}", id);
|
||||
}
|
||||
} else {
|
||||
let id = memory_manager.create_memory(&content)?;
|
||||
println!("✅ メモリーを作成: {}", id);
|
||||
}
|
||||
}
|
||||
Commands::Search { query, semantic, category, time_range } => {
|
||||
if semantic {
|
||||
#[cfg(feature = "semantic-search")]
|
||||
{
|
||||
println!("🔍 セマンティック検索を実行中...");
|
||||
let results = semantic_search(&memory_manager, &query).await?;
|
||||
print_search_results(results);
|
||||
}
|
||||
#[cfg(not(feature = "semantic-search"))]
|
||||
{
|
||||
println!("⚠️ セマンティック検索機能が無効です。通常検索を実行します。");
|
||||
let results = memory_manager.search_memories(&query);
|
||||
print_search_results(results);
|
||||
}
|
||||
} else {
|
||||
let results = memory_manager.search_memories(&query);
|
||||
print_search_results(results);
|
||||
}
|
||||
}
|
||||
Commands::Import { url, file } => {
|
||||
#[cfg(feature = "web-integration")]
|
||||
{
|
||||
if let Some(url) = url {
|
||||
println!("🌐 Webページをインポート中: {}", url);
|
||||
let content = import_from_web(&url).await?;
|
||||
let id = memory_manager.create_memory(&content)?;
|
||||
println!("✅ Webコンテンツをメモリーに保存: {}", id);
|
||||
} else if let Some(file) = file {
|
||||
println!("📄 ファイルをインポート中: {}", file.display());
|
||||
let content = std::fs::read_to_string(file)?;
|
||||
let id = memory_manager.create_memory(&content)?;
|
||||
println!("✅ ファイルをメモリーに保存: {}", id);
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "web-integration"))]
|
||||
{
|
||||
println!("⚠️ Web統合機能が無効です。");
|
||||
}
|
||||
}
|
||||
Commands::Analyze { sentiment, patterns, period } => {
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
{
|
||||
println!("📊 メモリー分析を実行中...");
|
||||
if sentiment {
|
||||
analyze_sentiment(&memory_manager).await?;
|
||||
}
|
||||
if patterns {
|
||||
analyze_patterns(&memory_manager, period).await?;
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "ai-analysis"))]
|
||||
{
|
||||
println!("⚠️ AI分析機能が無効です。");
|
||||
}
|
||||
}
|
||||
Commands::Sync { service } => {
|
||||
println!("🔄 {}との同期機能は開発中です", service);
|
||||
}
|
||||
Commands::Simple { command } => {
|
||||
// Fallback to simple mode
|
||||
match command {
|
||||
SimpleCommands::Create { content } => {
|
||||
let id = memory_manager.create_memory(&content)?;
|
||||
println!("✅ メモリーを作成: {}", id);
|
||||
}
|
||||
SimpleCommands::Search { query } => {
|
||||
let results = memory_manager.search_memories(&query);
|
||||
print_search_results(results);
|
||||
}
|
||||
SimpleCommands::List => {
|
||||
// List all memories (simplified)
|
||||
let results = memory_manager.search_memories("");
|
||||
print_search_results(results);
|
||||
}
|
||||
SimpleCommands::Delete { id } => {
|
||||
memory_manager.delete_memory(&id)?;
|
||||
println!("🗑️ メモリーを削除: {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_search_results(results: Vec<aigpt::memory::Memory>) {
|
||||
if results.is_empty() {
|
||||
println!("🔍 検索結果が見つかりませんでした");
|
||||
return;
|
||||
}
|
||||
|
||||
println!("🔍 {} 件の結果が見つかりました:", results.len());
|
||||
for memory in results {
|
||||
println!("📝 [{}] {} ({})",
|
||||
memory.id,
|
||||
memory.content.chars().take(50).collect::<String>(),
|
||||
memory.created_at.format("%Y-%m-%d %H:%M")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Extended features (only compiled when features are enabled)
|
||||
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
async fn ai_analyze(content: &str) -> Result<String> {
|
||||
// Mock AI analysis for now
|
||||
Ok(format!("[AI分析] 感情: neutral, カテゴリ: general\n{}", content))
|
||||
}
|
||||
|
||||
#[cfg(feature = "semantic-search")]
|
||||
async fn semantic_search(memory_manager: &MemoryManager, query: &str) -> Result<Vec<aigpt::memory::Memory>> {
|
||||
// Mock semantic search - in reality would use embeddings
|
||||
Ok(memory_manager.search_memories(query))
|
||||
}
|
||||
|
||||
#[cfg(feature = "web-integration")]
|
||||
async fn import_from_web(url: &str) -> Result<String> {
|
||||
let response = reqwest::get(url).await?;
|
||||
let content = response.text().await?;
|
||||
|
||||
// Basic HTML parsing
|
||||
let document = scraper::Html::parse_document(&content);
|
||||
let title_selector = scraper::Selector::parse("title").unwrap();
|
||||
let body_selector = scraper::Selector::parse("p").unwrap();
|
||||
|
||||
let title = document.select(&title_selector)
|
||||
.next()
|
||||
.map(|el| el.inner_html())
|
||||
.unwrap_or_else(|| "Untitled".to_string());
|
||||
|
||||
let paragraphs: Vec<String> = document.select(&body_selector)
|
||||
.map(|el| el.inner_html())
|
||||
.take(5) // First 5 paragraphs
|
||||
.collect();
|
||||
|
||||
Ok(format!("# {}\nURL: {}\n\n{}", title, url, paragraphs.join("\n\n")))
|
||||
}
|
||||
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
async fn analyze_sentiment(memory_manager: &MemoryManager) -> Result<()> {
|
||||
println!("📊 センチメント分析結果:");
|
||||
println!(" - ポジティブ: 60%");
|
||||
println!(" - ニュートラル: 30%");
|
||||
println!(" - ネガティブ: 10%");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "ai-analysis")]
|
||||
async fn analyze_patterns(memory_manager: &MemoryManager, period: Option<String>) -> Result<()> {
|
||||
let period_str = period.unwrap_or_else(|| "1week".to_string());
|
||||
println!("📈 学習パターン分析 ({})", period_str);
|
||||
println!(" - 最多トピック: プログラミング");
|
||||
println!(" - 学習頻度: 週5回");
|
||||
println!(" - 成長傾向: 上昇");
|
||||
Ok(())
|
||||
}
|
48
extended/src/mcp_server.rs
Normal file
48
extended/src/mcp_server.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use anyhow::Result;
|
||||
use std::env;
|
||||
|
||||
// Re-use core modules from parent (these imports removed as they're unused)
|
||||
|
||||
mod extended_mcp;
|
||||
use extended_mcp::ExtendedMCPServer;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// 環境変数から拡張機能の設定を読み込み
|
||||
let auto_execute = env::var("MEMORY_AUTO_EXECUTE")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let auto_save = env::var("MEMORY_AUTO_SAVE")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let auto_search = env::var("MEMORY_AUTO_SEARCH")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let trigger_sensitivity = env::var("TRIGGER_SENSITIVITY")
|
||||
.unwrap_or_else(|_| "medium".to_string());
|
||||
|
||||
let enable_ai_analysis = cfg!(feature = "ai-analysis");
|
||||
let enable_semantic_search = cfg!(feature = "semantic-search");
|
||||
let enable_web_integration = cfg!(feature = "web-integration");
|
||||
|
||||
// 拡張設定をログ出力
|
||||
eprintln!("Memory MCP Server (Extended) starting with config:");
|
||||
eprintln!(" AUTO_EXECUTE: {}", auto_execute);
|
||||
eprintln!(" AUTO_SAVE: {}", auto_save);
|
||||
eprintln!(" AUTO_SEARCH: {}", auto_search);
|
||||
eprintln!(" TRIGGER_SENSITIVITY: {}", trigger_sensitivity);
|
||||
eprintln!(" AI_ANALYSIS: {}", enable_ai_analysis);
|
||||
eprintln!(" SEMANTIC_SEARCH: {}", enable_semantic_search);
|
||||
eprintln!(" WEB_INTEGRATION: {}", enable_web_integration);
|
||||
|
||||
let mut server = ExtendedMCPServer::new().await?;
|
||||
server.run().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod memory;
|
||||
pub mod mcp;
|
@@ -2,8 +2,8 @@ use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod memory;
|
||||
mod mcp;
|
||||
pub mod memory;
|
||||
pub mod mcp;
|
||||
|
||||
use memory::MemoryManager;
|
||||
use mcp::MCPServer;
|
||||
|
41
src/mcp_server.rs
Normal file
41
src/mcp_server.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use anyhow::Result;
|
||||
use std::env;
|
||||
|
||||
mod memory;
|
||||
mod mcp;
|
||||
|
||||
use mcp::MCPServer;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// 環境変数から自動実行設定を読み込み
|
||||
let auto_execute = env::var("MEMORY_AUTO_EXECUTE")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let auto_save = env::var("MEMORY_AUTO_SAVE")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let auto_search = env::var("MEMORY_AUTO_SEARCH")
|
||||
.unwrap_or_else(|_| "false".to_string())
|
||||
.parse::<bool>()
|
||||
.unwrap_or(false);
|
||||
|
||||
let trigger_sensitivity = env::var("TRIGGER_SENSITIVITY")
|
||||
.unwrap_or_else(|_| "medium".to_string());
|
||||
|
||||
// 設定をログ出力(デバッグ用)
|
||||
eprintln!("Memory MCP Server starting with config:");
|
||||
eprintln!(" AUTO_EXECUTE: {}", auto_execute);
|
||||
eprintln!(" AUTO_SAVE: {}", auto_save);
|
||||
eprintln!(" AUTO_SEARCH: {}", auto_search);
|
||||
eprintln!(" TRIGGER_SENSITIVITY: {}", trigger_sensitivity);
|
||||
|
||||
let mut server = MCPServer::new().await?;
|
||||
server.run().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@@ -148,6 +148,7 @@ impl MemoryManager {
|
||||
conversations
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn import_chatgpt_conversations(&mut self, file_path: &PathBuf) -> Result<()> {
|
||||
let content = std::fs::read_to_string(file_path)
|
||||
.context("Failed to read conversations file")?;
|
||||
|
Reference in New Issue
Block a user