Skip to main content
Glama

ToolKit ローカルスキル Agent

MCP (Model Context Protocol) プロトコルに基づくローカルスキルアシスタントです。計算機や天気予報などのカスタムスキルをサポートし、Web インターフェースと API インターフェースを提供します。

プロジェクト構造

..
├── .env                    # 大模型 API 配置
├── chat_history.db         # SQLite 对话历史数据库(自动生成)
├── index.html              # 前端 Web 界面
├── main.py                 # 主入口(命令行界面)
├── mcp_server.py          # MCP 服务端(核心)
├── server.py               # Flask 后端服务
├── requirements.txt        # 依赖清单
├── README.md               # 项目说明
├── tree.txt                # 目录结构
├── client/                 # 客户端目录
│   ├── doubao_mcp_client.py  # 豆包 API 客户端
│   └── __init__.py
├── config/                 # 配置目录
│   ├── settings.py         # 全局配置
│   └── __init__.py
└── skills/                 # 技能实现目录
    ├── calculator.py       # 计算器技能
    ├── weather.py          # 天气查询技能
    ├── web_search/         # 网络搜索技能目录
    │   └── web_search.py   # DuckDuckGo搜索实现
    |   └── SKILL.md  # skill描述
    |   └── _init_.py   
    └── __init__.py

Related MCP server: MCP Connection Hub

技術スタック

バックエンドフレームワーク: Python + Flask で Web サービスを構築し、RESTful API と SSE ストリーミング出力インターフェースを提供

AI プロトコルとモデル呼び出し: OpenAI 互換 SDK に基づいて大規模モデル API に接続し、Doubao などの OpenAI 形式モデルのアクセスをサポート

コアプロトコル: MCP (Model Context Protocol) を実装してツール呼び出しを標準化し、スキルの登録とスケジューリングを統一

非同期アーキテクチャ: asyncio 非同期処理 + スレッドプール分離により、Flask の同期環境下での非同期呼び出しのブロック問題を解決

データ永続化: SQLite を使用してマルチセッションの会話コンテキストを保存し、セッション管理と履歴の読み込みをサポート

スキルプラグイン化: モジュール式スキルシステムにより、計算機、天気、Web 検索などのプラグイン可能なツール拡張をサポート

フロントエンド: ネイティブ HTML/JS で Web インターフェースを実装し、Markdown レンダリング、ストリーミングタイピング効果、思考チェーンの表示をサポート

エンジニアリング: API 変数設定 (.env)、依存関係管理 (uv/pip)、エラー再試行とダウングレードメカニズム、ツール呼び出しキャッシュ

コア機能

安定した非同期処理 - Flask ルート内で直接 asyncio.run() を使用する問題を修正し、スレッドプールを使用して非同期関数を実行

会話履歴の永続化 - SQLite を使用して会話履歴を保存し、サービス再起動後も保持。マルチセッション管理をサポート

ツール呼び出しのフォールトトレランス - 自動再試行メカニズム。ツール呼び出し失敗時にモデルによる直接回答へダウングレード

MCP ツールキャッシュ - ツールリストを初回取得後にキャッシュし、重複する初期化オーバーヘッドを削減

ストリーミング出力 - 完全な SSE ストリーミングインターフェースを実装し、逐次出力体験をサポート

ツール呼び出しのヒント - スキル呼び出し時に「【ツールを呼び出しました: {ツール名}】」というヒント情報を表示

マルチエンドサポート - Web インターフェースとコマンドラインインターフェースの2種類の対話方式を提供

豊富なスキル - 計算機、天気予報、Web 検索スキルを内蔵

スキル管理 - フロントエンドでの視覚的なスキル管理。スキルの有効/無効を自由に切り替え可能

Markdown レンダリング - Markdown 形式の回答をサポート。コードハイライト、テーブル、リスト、数式などを表示可能

思考チェーンの表示 - 折りたたみ可能な AI の思考プロセス表示により、推論ロジックを理解しやすくする

マルチセッション管理 - 複数の独立した会話を作成可能。各会話の履歴を個別に保存

会話履歴の読み込み - セッション切り替え時に履歴を自動的に読み込み、対話プロセスを完全に記録

環境要件

  • Python 3.11+

  • openaiSDK(api)

  • uv パッケージ管理ツール (推奨) または pip

インストール

方法 1: uv パッケージ管理ツールを使用 (推奨)

  1. uv のインストール

    # Windows
    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 
    irm https://astral.sh/uv/install.ps1 | iex
    
    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh
  2. プロジェクトのクローン

    git clone https://github.com/taffy123d/Doubao-MCP-agent
    cd <项目目录>
  3. 仮想環境の作成

    uv venv
  4. 依存関係のインストール

    uv sync

方法 2: pip を使用

  1. プロジェクトのクローン

    git clone https://github.com/taffy123d/Doubao-MCP-agent
    cd <项目目录>
  2. 仮想環境の作成

    python -m venv venv
  3. 仮想環境の有効化

    # Windows
    venv\Scripts\activate
    
    # macOS / Linux
    source venv/bin/activate
  4. 依存関係のインストール

    pip install -r requirements.txt

設定

  • フロントエンドで API キーを設定
  • または .env ファイルに API キーを記入:
# OpenAI 兼容格式的 API 配置
OPENAI_API_KEY=你的API密钥
OPENAI_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
OPENAI_MODEL=你的模型ID

実行

方法 1: 完全起動 (推奨)

uv run server.py
#或者
python server.py
  • フロントエンドアクセス: http://localhost:5000

  • API インターフェース: http://localhost:5000/api/*

方法 2: コマンドラインインターフェース

uv run main.py
#或者
python main.py
  • ターミナルで直接対話

  • マルチターン対話と履歴記録をサポート

  • clear または 清除历史 を入力して会話履歴を消去

  • exitquit または 退出 を入力してプログラムを終了

API インターフェース

インターフェース

メソッド

説明

/

GET

フロントエンドページ

/api/health

GET

ヘルスチェック

/api/tools

GET

スキルリストの取得

/api/config

GET

設定の取得

/api/config

POST

設定の保存

/api/test-connection

POST

API 接続テスト

/api/chat

POST

チャット (会話履歴をサポート)

/api/chat/stream

POST

ストリーミングチャット (SSE)

/api/chat/clear

POST

会話履歴の消去

/api/sessions

GET

全セッションリストの取得

/api/sessions/<id>

DELETE

指定セッションの削除

/api/sessions/<id>/history

GET

セッション履歴の取得

API リクエスト例

チャットインターフェース

curl -X POST http://localhost:5000/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "你的API密钥",
    "model": "你的模型ID",
    "base_url": "https://ark.cn-beijing.volces.com/api/v3",
    "message": "北京天气",
    "session_id": "default"
  }'

ストリーミングチャットインターフェース

curl -X POST http://localhost:5000/api/chat/stream \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "你的API密钥",
    "model": "你的模型ID",
    "base_url": "https://ark.cn-beijing.volces.com/api/v3",
    "message": "北京天气",
    "session_id": "default"
  }'

履歴消去インターフェース

curl -X POST http://localhost:5000/api/chat/clear \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "default"
  }'

使用方法

Web インターフェース

  1. API の設定

    • 左側の設定パネルに API Key と Endpoint ID を入力

    • 「テスト」ボタンをクリックして接続を検証

  2. チャット

    • 入力ボックスに質問を入力

    • サポートされているスキル:

      • 計算機: 计算 123+456

      • 天気予報: 北京天气

      • Web 検索: 搜索 最新AI新闻

  3. スキル管理

    • 左側の「🔧 技能管理」をクリックしてパネルを展開

    • 利用可能なすべてのスキルとその説明を表示

    • スイッチボタンをクリックしてスキルを有効/無効化

    • 有効なスキルのみが呼び出されます

  4. マルチセッション管理

    • 左側の「💬 对话管理」をクリックしてパネルを展開

    • 「➕ 新建对话」をクリックして新しい会話を作成

    • セッションリストの項目をクリックして該当する会話に切り替え

    • 🗑️ をクリックして不要な会話を削除

    • 各セッションは履歴を個別に保存

  5. 結果の確認

    • システムは自動的に対応するスキルを呼び出し、結果を返します

    • Markdown 形式の回答をサポート (コードハイライト、テーブル、リストなど)

    • 「🧠 思考过程」をクリックして AI の推論ロジックを確認可能

    • マルチターン対話をサポート

コマンドラインインターフェース

  1. プログラムの実行

    python main.py
  2. 質問の入力

    • ターミナルで直接質問を入力

    • サポートされているスキル:

      • 計算機: 计算 123+456

      • 天気予報: 北京天气

  3. 結果の確認

    • システムは自動的に対応するスキルを呼び出し、結果を返します

    • マルチターン対話をサポート

    • clear または 清除历史 を入力して会話履歴を消去

新しいスキルの追加方法

ステップ 1: スキルファイルの作成

skills/ ディレクトリに新しいスキルファイルを作成します (例: my_skill.py):

"""我的自定义技能"""
from mcp.server.fastmcp import FastMCP

def register_my_skill(mcp: FastMCP):
    """注册技能到 MCP 服务"""
    
    @mcp.tool()
    def my_skill(param1: str, param2: int = 1) -> str:
        """
        我的自定义技能描述
        示例:my_skill(param1="值", param2=2)
        
        Args:
            param1: 参数1描述
            param2: 参数2描述(默认值)
        Returns:
            技能执行结果
        """
        try:
            # 技能逻辑实现
            result = f"处理结果: {param1} - {param2}"
            return result
        except Exception as e:
            return f"处理失败: {str(e)}"

ステップ 2: スキルの登録

skills/__init__.py を編集し、新しいスキルの登録関数を追加します:

from .calculator import register_calculator_tool
from .weather import register_weather_tool
from .my_skill import register_my_skill

__all__ = [
    "register_calculator_tool", 
    "register_weather_tool",
    "register_my_skill"
]

ステップ 3: MCP サービスの更新

mcp_server.py を編集し、新しいスキルの登録を追加します:

from skills import register_calculator_tool, register_weather_tool, register_my_skill

# 注册所有技能工具
register_calculator_tool(mcp)
register_weather_tool(mcp)
register_my_skill(mcp)  # 添加这一行

ステップ 4: サービスの再起動

MCP サービスとバックエンドサービスを再起動すると、新しいスキルが使用可能になります。

スキル開発仕様

  1. ファイル命名: 小文字とアンダースコアを使用

  2. 関数命名: register_xxx_tool 形式

  3. ツールデコレータ: @mcp.tool() デコレータを使用

  4. ドキュメント文字列: 機能説明、例、パラメータ説明を含める

  5. エラー処理: 例外をキャッチし、わかりやすいヒントを返す

  6. パラメータ型: 型アノテーションを使用

複雑な Skill の作成方法 (SKILL.md 付き)

機能が複雑なスキルの場合、独立した skill ディレクトリを作成し、スキル実装と SKILL.md 記述ファイルを含めることを推奨します。

ディレクトリ構造

skills/
└── my_complex_skill/          # skill 目录
    ├── __init__.py            # 导出配置(必选)
    ├── my_skill.py            # 技能实现(必选)
    └── SKILL.md               # skill 描述文档(必选)

ステップ 1: skill ディレクトリと実装ファイルの作成

skills/ ディレクトリの下に新しい skill ディレクトリを作成します (例: skills/my_complex_skill/)

1.1 スキル実装ファイル my_skill.py の作成

"""我的复杂技能实现"""
from mcp.server.fastmcp import FastMCP
from duckduckgo_search import AsyncDuckDuckGoSearcher  # 示例依赖

def register_my_complex_skill(mcp: FastMCP):
    """注册复杂技能到 MCP 服务"""
    
    @mcp.tool()
    async def my_complex_skill(query: str, limit: int = 5) -> str:
        """
        我的复杂技能描述
        
        Args:
            query: 查询关键词
            limit: 返回结果数量,默认5
        
        Returns:
            格式化的搜索结果
        """
        try:
            async with AsyncDuckDuckGoSearcher() as searcher:
                results = await searcher.atext(query, max_results=limit)
                # 处理并返回结果
                return f"找到 {len(results)} 条结果..."
        except Exception as e:
            return f"搜索失败: {str(e)}"

1.2 __init__.py の作成と設定のエクスポート

"""my_complex_skill - 我的复杂技能"""
from .my_skill import register_my_complex_skill

__all__ = ["register_my_complex_skill"]

1.3 SKILL.md 記述ドキュメントの作成

# 我的复杂技能

## 功能描述
一句话描述技能功能...

## 使用场景
### ✅ 适用场景
- 场景1
- 场景2

## 参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| query | string | 是 | - | 查询关键词 |

## 使用示例
```python
# 示例1
my_complex_skill(query="关键词")

結果の戻り値形式

  • 結果 1: xxx

  • 結果 2: xxx

例外処理

エラータイプ

処理方法

ネットワークエラー

わかりやすいエラーメッセージを返す

注意事項

  1. 注意事項 1

  2. 注意事項 2


### 步骤 2:更新 skills/__init__.py

```python
from .calculator import register_calculator_tool
from .weather import register_weather_tool
from .web_search import register_web_search_tool
from .my_complex_skill import register_my_complex_skill  # 新增

__all__ = [
    "register_calculator_tool", 
    "register_weather_tool",
    "register_web_search_tool",
    "register_my_complex_skill"  # 新增
]

ステップ 3: mcp_server.py の更新

from skills import (
    register_calculator_tool, 
    register_weather_tool, 
    register_web_search_tool,
    register_my_complex_skill  # 新增
)

# 注册所有技能工具
register_calculator_tool(mcp)
register_weather_tool(mcp)
register_web_search_tool(mcp)
register_my_complex_skill(mcp)  # 新增

ステップ 4: 追加の依存関係のインストール (必要な場合)

新しい skill が追加の Python パッケージを必要とする場合、uv add でインポートするか、requirements.txt に追加します:

uv add 包名称
或
包名称 >=版本号 #requirements.txt

その後、以下を実行:

uv sync
# 或
pip install 包名称

ステップ 5: サービスの再起動

サービスを再起動すると、新しいスキルが使用可能になります。

SKILL.md 仕様

フィールド

必須

説明

# タイトル

はい

スキル名

## 機能説明

はい

スキルの役割を一行で説明

## 使用シーン

推奨

適用シーンを列挙

## パラメータ説明

推奨

テーブル形式でパラメータを説明

## 使用例

推奨

コードと対話例

## 結果の戻り値形式

推奨

戻り値の構造を説明

## 例外処理

推奨

エラー処理方法

## 注意事項

推奨

使用上の注意点

スキル例

計算機スキル

  • 機能: 加減乗除、括弧、べき乗計算をサポート

  • 呼び出し: 计算 (10+5)*2

天気予報スキル

  • 機能: 都市の天気と予報を照会

  • 呼び出し: 上海天气 または 北京天气 3天

Web 検索スキル

  • 機能: DuckDuckGo を使用して最新情報を検索

  • 呼び出し: 搜索 Python最新版本 または 搜索 今天科技新闻

  • 依存関係: ddgs ライブラリ (pip install duckduckgo-search)

技術的なハイライト

  1. 非同期処理の最適化 - スレッドプールを使用して非同期関数を実行し、リクエストごとに新しいイベントループを作成する問題を回避

  2. 会話履歴の永続化 - SQLite ベースの永続ストレージにより、サービス再起動後も保持。マルチセッション分離をサポート

  3. ツール呼び出しのフォールトトレランス - 失敗時に自動的に 2 回再試行し、モデルによる直接回答へダウングレードして堅牢性を向上

  4. MCP ツールキャッシュ - 重複する初期化オーバーヘッドを削減し、応答速度を向上

  5. ストリーミング出力の実装 - 完全な SSE ストリーミングインターフェースにより、優れたユーザー体験を提供

  6. ツール呼び出しのヒント - 明確なツール呼び出しのヒントにより、ユーザー体験を向上

  7. マルチエンドサポート - Web インターフェースとコマンドラインインターフェースを同時に提供

  8. スキル管理システム - フロントエンドでの視覚的なスキル管理。柔軟な有効/無効切り替えをサポート

  9. Markdown レンダリング - コードハイライトやテーブルなど、完全な Markdown サポート

  10. 思考チェーンの表示 - 折りたたみ可能な AI 推論プロセスの表示

  11. マルチセッション管理 - 完全なセッション作成、切り替え、削除機能

  12. 会話履歴の読み込み - セッション履歴の自動読み込みと表示

注意事項

  1. API キーのセキュリティ: API キーをバージョン管理にコミットしないでください

  2. スキルの安全性: スキル内で危険な操作を実行しないでください

  3. パフォーマンス最適化: 時間のかかる操作には非同期処理を検討してください

  4. エラー処理: スキルが例外を適切に処理できるようにしてください

トラブルシューティング

  • 接続失敗: API キーとネットワーク接続を確認してください

  • スキルが応答しない: MCP サービスが正常に動作しているか確認してください

  • フロントエンドが表示されない: ブラウザのコンソールにエラーがないか確認してください

  • ストリーミングインターフェースの問題: ネットワーク接続が安定していることを確認し、途中で切断されないようにしてください

  • データベースエラー: chat_history.db ファイルの権限を確認し、読み書き可能であることを確認してください

データストレージ

プロジェクトは SQLite データベースを使用して会話履歴を永続化します:

  • データベースファイル: chat_history.db (プロジェクトルートディレクトリ、初回実行時に自動生成)

  • テーブル構造:

    CREATE TABLE messages (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      session_id TEXT NOT NULL,    -- 会话ID,支持多会话隔离
      role TEXT NOT NULL,           -- 角色(user/assistant/tool)
      content TEXT NOT NULL,        -- 消息内容
      timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
    )
  • 履歴の照会: SQLite ツールまたはコマンドラインを使用して確認

    sqlite3 chat_history.db "SELECT * FROM messages ORDER BY timestamp DESC LIMIT 10;"

拡張の提案

  1. さらなるスキル: 翻訳、株価照会、ニュースなどのスキルを追加

  2. 多言語サポート: 多言語インターフェースを追加

  3. デプロイ最適化: Docker コンテナ化デプロイを使用

  4. スキルマーケット: スキルマーケットを作成し、ユーザーがスキルを共有・ダウンロードできるようにする

  5. モデル切り替え: 異なる大規模言語モデルへの切り替えをサポート

更新ログ

2026-03-29 重大な更新

API 呼び出し方式のアップグレード

  • httpx → OpenAI SDK: すべての API 呼び出しを httpx による直接 HTTP リクエストから openai>=1.0.0 SDK 方式に変更

  • 設定フィールドの名称変更:

    • DOUBAO_API_KEYOPENAI_API_KEY

    • DOUBAO_ENDPOINT_IDOPENAI_MODEL

    • DOUBAO_BASE_URLOPENAI_BASE_URL (/chat/completions サフィックスを削除)

ツール呼び出しの最適化

  • Schema のクリーンアップ: Doubao API がサポートしていない titledefault などのフィールドを自動的に削除

  • Description のクリーンアップ: 余分な空白文字を圧縮し、フォーマットを最適化

  • メッセージ変換: _msg_to_dict() 関数を追加し、OpenAI SDK が返す ChatCompletionMessage オブジェクトを正しく処理

  • 2 回目の呼び出し: ツール呼び出し後の 2 回目のリクエストにおけるメッセージ形式の問題を修正

バグ修正

  • ✅ 「Object of type ChatCompletionMessage is not JSON serializable」エラーを修正

  • ✅ メッセージ履歴保存時の型変換問題を修正

  • ✅ デバッグを容易にするための詳細な例外スタックトレースを追加

アーキテクチャの改善

  • _msg_to_dict() 補助関数を追加し、メッセージ形式変換を統一

  • API 型検出を追加 (Xunfei API は自動的に tools パラメータをスキップ)

  • chat() ルートの例外処理とログ出力を最適化


Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive demonstration server that provides tools for calculations, weather, and note management alongside an interactive web interface. It showcases how AI assistants can seamlessly interact with external data sources and functions using the Model Context Protocol.
    -
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables AI assistants to operate Huawei Cloud resources (ECS, OBS, GaussDB, etc.) through conversational workflows via the Model Context Protocol.
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/taffy123d/LocalSkill-MCP-Agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server