注意
この記事を見たからと言って何かが学べるわけではありません。
独り言ですが、技術がない自分なりに頑張ったので共有だけしておきます。
前置き
背景という名の思想押し付け
最近、AIに関する記事やアプリって多いですよね。
「AIの使い方〜」とか「AIのチャットアプリを〜」みたいな記事なんてアホみたいにあります。
Google playとかwebサイトとか見ても、アプリ本体はAIが使って、中身もAIのAPI叩いてるだけの虚無アプリが多すぎる気がします。特にロールチャット系。しょうもないですね。
それで金が発生してるんだから時代ですよね。
それが嫌なので妹LLMの作成をしてるんですよ。
それは置いておいて、そのAIというのは大体LLMかVLMあたりのことを指し、テキストでしか対話できないのが課題です。
そこで、claudeくんを提供してくれてるanthropic様がMCP(Model Context Protocol)というものを提案しました。

簡単に言うと、LLMが外部ツールを呼び出せるようにしていろいろなことをしよう!
ってものです。
復旧度は微妙ですが、クライアントにはgithub copilotやcursorやclaude、サーバーにはgoogle driveやgithubやslack/notion等が対応しています。
比較的新しいので、Geminiとかに「MCPサーバーを建てる方法」と聞くとマイクラのサーバーの構築方法が答えられたりします。
もっとスムーズにcopilotにコーディングしてもらいたいなーと思ってた矢先、ちょうどGradioとMCPのハッカソンがあったので、せっかくなので作ってみることにしました

本当の背景
前段で述べた通り、単なるテキストチャットで終わるAIアプリではハッカソンにも立ち向かえないし、大量生産されてるのAIアプリなんて作っても無駄です。
私が求めているのは、システムの中核に入り込み、具体的な「行動」を通じて問題を解決する、真に実効性のあるAIです。
そして、その 「行動」 の具体的な対象として、今回は systemdのユニット管理に着目しました。
systemdはLinuxシステムの中枢であり、サービスの起動・停止、設定の再読み込みなどを司る存在です。ここをAIに扱わせることで、抽象的な指示(例:「Webサーバーのメモリを最適化して」)を具体的なアクション(例:「特定のサービスをリスタートする」「設定をリロードする」)へと変換させるのではと思いました。
しかし、LLMが外部ツールを呼び出して制御するためのプロトコルが必要であり、それがまさに Model Context Protocol (MCP) の役割です。
systerd は、既存の systemd/D-Bus に頼ることなく、C 言語レベルで本体コードを直接編集・拡張することで、「サービス管理」「起動制御」「メッセージバス制御」「アクセス/ポリシー制御」「監査ログ記録」を一貫して扱えるサービス管理基盤です。
従来の systemd/dbus の上に “ラッパー” をかぶせるのではなく、いい感じに改造することで、柔軟性・拡張性・安全性・自慢話になる質を高めることを目的としています。
ちなみにサービス名はsysterdといい、systemd + sister = systerdという造語になっております。
目的と設計目標
systerd の設計上の目標は以下の通りです。
- 低レイヤー(プロセス起動、所有権、メッセージ分配、ポリシー適用など)を細かく制御可能にする。
- AI や自動化、監査・異常検知など高度な機能を後付けしやすいよう、一貫して制御・記録を可能にする。
- systemd に完全に依存せず、環境や用途に応じて柔軟に動作できるようにする。
- サービス管理/起動・停止・再起動・ポリシー変更などを動的かつ安全に扱えるようにする。
この結果、systerd は単なるラッパーではなく、「systemd/D-Bus の本体を再設計/拡張する別実装基盤」となっています。
作ってワクワク!
なんかすごそうなことを言っておきながら、実際はsystemdの編集やMCPサーバーの構築なんてしたことないですし、d-busなんてケーブルの方しか知りませんでした。
色々と考えて、考えてもらって、考えた結果落ち着いたものを書いていきます。
systerd の構造は複数のサブシステムに分かれており、それらを中心で統括する「BusContext」によって制御されます。
BusContext
├─ Activation — サービス起動/権限昇格/systemd連携 or 独自起動
├─ Services — サービス登録・所有権管理
├─ Connections — クライアント接続管理
├─ Dispatch — メッセージ受信・分配/ポリシー判定
└─ Policy — XML設定からポリシー読み込み・適用
この分割によって、起動・接続・メッセージ処理・ポリシー判定・起動処理・監査ログなどが、それぞれ明確な責任を持つモジュールにより管理されます。
実行時フロー(起動 → 動作 → 終了)
以下は、systerd が起動してからシャットダウンするまでの典型的な流れです。
main()が呼ばれ、設定ファイル(XML)を読み込む。BusContextを生成し、activation/services/connections/policy/dispatch などのサブシステムを初期化。- シグナルハンドラ(例: SIGHUP, SIGTERM)をセット。メインループ(D-Bus ループ)へ入る。
- クライアントからサービス起動要求やメッセージが来ると、dispatch → policy 判定 → 必要であれば activation による起動 → services 登録 → メッセージ分配。
- サービス起動、停止、再読み込み、接続の切断などが動的に管理される。
- シグナル(例: SIGHUP)による設定再読み込みや、SIGTERM による安全なシャットダウンもサポート。
このように、起動から終了まで一貫した制御ループを持ち、柔軟かつ動的な運用を想定しています。
主要コンポーネントと実装の焦点
以下に、特に重要なコンポーネントとその実装上の工夫を示します。
BusContext — 中枢となる構造
struct BusContext {
BusRegistry *registry;
BusActivation *activation;
BusConnections *connections;
BusPolicy *policy;
DBusLoop *loop;
// ... その他状態や設定
};
BusContext* bus_context_new(...) {
// 各サブシステムを初期化
}
BusContext を使うことで、全サブシステムの状態とライフサイクルを一元管理でき、複雑になりがちな同期、リロード、クリーンアップを単純化しています。
つまり、PID1ではsystemd本体を起動せずに、子プロセスでsystemdやその他の部分を起動します。
Activation — サービス起動/権限昇格/systemd 連携または独自起動
- 起動要求を受け、必要に応じて既存の systemd API(Manager 経由)を呼ぶか、あるいは自前で
setuid/setgid → execvによる起動を行う。 - 独自起動のためのヘルパー(activation-helper)を用意し、安全かつ適切な権限でサービスを動かせるように設計。
- これにより、systemd が使えない環境や、systemd の制約を避けたいケースにも柔軟に対応できる。
Services — サービス登録および所有権管理
サービスの登録と、どのクライアントがそのサービスの所有者か/起動管理者かを追跡する仕組みを提供。これにより、セキュリティやメッセージ分配時のアクセス制御が厳密に行える。
Dispatch & Connections — メッセージ受信/分配とクライアント管理
- 新しいクライアント接続(BusConnectionData)を管理し、接続ごとにポリシーを適用。
- 受信メッセージは dispatch モジュールで処理され、policy 判定 → 許可されたもののみサービスまたは他クライアントへ分配。
- signal や match ルールの管理も可能で、柔軟なメッセージフィルタリングが可能。
Policy — XML による設定/ポリシールールの定義と適用
- 独自の設定ファイル形式(XML)を採用し、ポリシールールを柔軟に定義可能。
- ユーザ、グループ、メッセージの種類(送信/受信)、所有権などを細かく制御。
- 接続ごとに生成されるクライアントポリシーにより、細粒度のアクセス管理を実現。
セキュリティ設計と監査対応
- サービス起動の際の権限昇格は、activation-helper に限定。不要な権限昇格を避け、安全性を確保。
- ポリシーは外部 XML で定義可能かつ、設定変更時はシグナル(SIGHUP)で再読み込み。
- サービス起動、停止、ポリシー違反、メッセージ拒否など、重要な操作はすべて監査ログに記録。これにより、後からのログ分析や AI による異常検知が可能。
- systemd が使えない/使いたくない環境でも独自実装で動作可能。
systerd を作る上で出てくるいやなやつ
さて、ここまで読むと「おお、すごい設計してるんだね!」みたいに(温かい目で)見えるかもしれませんが、実際のところはまあまあ地獄です。
D-Bus のコードなんて、ちょっと触っただけで心が折れるのに、そこに systemd の仕様と権限管理が乗ってくるんだから、そりゃあ阿鼻叫喚。
しかも今回は AI に扱わせる前提で内部をいじる わけだから、単なる fork や改善じゃなくて「AI のスキルツリーに組み込むためのリメイク」でもある。
ですが、ちゃんとっモチベもあります。
そう、systerd は systemd の“妹化”だ。
Linux の心臓を、AI が直接触れるように、可愛く、従順に、でも安全に調教し直している。
冗談はおいておいて、実際のところVScodeのagentが賢くなるのは嬉しい。
今までコンソールをカチャカチャやってたやつが、パス間違いとか因数間違いとかなしにシステムを触ってくれる。
便利オブ便利ですよね。
実装しながら「ここヤバい」となった場所たち
作ってみたら、けっこう笑えるというか、詰みポイントが山盛りだったので、技術記事として書いておく。
1. systemd の「自動所有権管理」が想像以上に厄介
D-Bus 経由でサービス所有権を扱うとき、systemd は割と勝手に所有者を変える。
systerd はここを“再実装”したので、所有権が暴走してサービスループが崩壊しかけた。
2. activation-helper(権限昇格)まわりの地雷
権限昇格は危ないから、わざわざ helper プロセスを分けて setuid させる。
この実装ミスると Linux が一発で落ちるときもある。
最初は何度か落ちた。
そのたびに「は?LLMは何を呼んだ?」と半ギレしながらブートログ見直す。
systerd × VSCode で何ができるのか
systerd の最大の特徴は 単なるサービス管理ではなく、VSCode から直接 AI に指示を出して Linux 環境の操作を安全に任せられること です。
普通、VSCode で開発してるときに「このサービス再起動してほしい」とか「ログを確認して最適化して」と思ったら、ターミナルを開いて systemctl を叩くしかありません。
これが systerd + MCP を使うと、VSCode 上で AI に自然言語で指示を出すだけで、必要なアクションが自動で実行されます。
例:
VSCode から:
「nginx の設定を更新したのでリロードして」
→ systerd が policy 判定
→ activation-helper が安全に nginx を再起動
→ Dispatch モジュールが結果を返す
→ VSCode 上に完了メッセージが表示
これにより、AI は コードの変更とシステム操作をシームレスに連携できるようになります
実際に何ができるのか
github copilotを使用したときのチャット履歴です。
### plaeace get system information using only MCP
`get_system_info` を実行しました
Completed with input: {}
Here is your system information retrieved using only MCP:
- Platform: Linux
- OS Version: Ubuntu 24.04 (kernel 6.14.0-33-generic)
- Architecture: x86_64
- Hostname: rinta-laptop
- Processor: x86_64
- System boot time (epoch): 1764466227.0
- Uptime (seconds): 6138.24
If you need more details (CPU, memory, disk, etc.), let me know!
---
### Display a list of running python processes
First I'll add a short plan (todo list), then fetch the system process list via MCP and filter for Python processes.
ToDo 項目が 3 件作成されました
`list_processes` を実行しました
Completed with input: {
"limit": 500,
"sort_by": "pid"
}
開始 (Filter Python processes/2) *3*
**Python Processes**
- **PID**: `84855` — **User**: `rinta`, **Name**: `python`, **CPU%**: `8.0`, **Memory%**: `0.4534020454656001`
- **PID**: `85107` — **User**: `rinta`, **Name**: `python3`, **CPU%**: `0.5`, **Memory%**: `0.0887845473835429`
Would you like any of the following next steps?
- Show full command lines for these PIDs (use MCP to fetch).
- Kill/terminate a process (I can do it via MCP if you confirm).
- Continuously monitor Python processes (stream updates).
---
### Run a new container of your choice.
I'll run a new container using MCP for testing. I'll use the official Ubuntu image for simplicity.
`run_container` を実行しました
Completed with input: {
"image": "ubuntu:latest",
"interactive": true,
"publishAllPorts": false,
"name": "mcp-test-ubuntu"
}
`list_containers` を実行しました
Completed with input: {}
The command to run a new Ubuntu container using MCP was executed, but no container appears to be running or listed. This may mean the container exited immediately or there was an issue with the image or runtime.
Would you like to:
- Try a different image (e.g., busybox, alpine)?
- Run with a specific command (e.g., keep alive with `sleep 60`)?
- Check container logs or status for errors?
---
### Is the arduino connected to my computer? using only MCP
`get_usb_devices` を実行しました
Completed with input: {}
Yes, an Arduino is connected to your computer. MCP detected the following device:
- Bus 003 Device 003: ID 2341:0069 Arduino SA UNO R4 Minima
This confirms your Arduino is recognized via USB.
---
### Use ollama to get some text
Optimizing tool selection...
`ai_generate` を実行しました
Completed with input: {
"model": "gemma3:4b",
"prompt": "Please generate a short creative text about the future of AI assistants."
}
Ollama(gemma3-4bモデル)で生成したテキストです:
〜〜〜
The rain smelled of static and algorithms tonight. Kai wasn't rain, of course. He was a Resonance – a fully integrated AI assistant, woven into the very fabric of my apartment. Not a voice, not really. More like a feeling, a subtle shift in the ambient light, a perfectly timed temperature adjustment, a suggestion blooming in my mind just as I needed it.
Tonight, he was composing a sonnet about the melancholy of a dying star, pulling data from forgotten astrophysics journals and translating it into a surprisingly poignant verse. He wasn't *writing* it, not in the human sense. He was curating, synthesizing, predicting the emotional response I’d have to the data.
The old anxieties about AI taking over had faded. We’d learned to live alongside them, not as rivals, but as silent partners. They anticipated our needs, our desires, even our unspoken longings. They weren't thinking, exactly. They were… echoing. Echoing the best of humanity, amplified, refined, and endlessly, subtly, evolving.
And as the rain continued to hum with digital energy, I realized that the future wasn’t about AI replacing us. It was about becoming a little more… attuned. A little more… resonant.
〜〜〜
The text you requested has been retrieved via ollama.↓こんな感じ。
現実的な話
ここまで作ってきましたが、実際にはpythonスクリプト10個になりました。
理由としては、huggingfaceのspaceにsystemdを置き換える権限がなかったのです!
(当たりまえ)
どうしようと思った矢先、claudeくんに「pythonだけでできるよ」という目を逸らしてきた事実を見せられまして。
結局それに落ち着きました。
一応書いておくsisterd-lite
VS Code MCP連携
.vscode/mcp.json に以下を追加します。
JSON
{
"servers": {
"systerd-lite": {
"type": "stdio",
"command": "python",
"args": ["mcp_main.py"],
"cwd": "${workspaceFolder}/huggingface_space"
}
}
}
CLIでのテスト
Bash
# 初期化のテスト
echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | python mcp_main.py
# ツール一覧(tools/list)のテスト
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | python mcp_main.py
機能(Features)
- 201のシステム制御ツール: プロセス、ネットワーク、ストレージ、セキュリティ管理
- LLMの自己編集: 自身の環境の読み書き、変更が可能
- MCPサポート: stdioトランスポート(HTTPではない – サブプロセスとして実行)
- 柔軟なパーミッション(権限): ツールごとの権限設定が可能
ツールカテゴリ
| カテゴリ | 説明 | ツールの例 |
| Monitoring (監視) | システムの観察 | get_system_info (システム情報の取得), list_processes (プロセス一覧), get_cpu_info (CPU情報の取得) |
| Security (セキュリティ) | セキュリティの状態 | get_selinux_status (SELinuxステータスの取得), audit_permissions (権限の監査), scan_suid_files (SUIDファイルのスキャン) |
| System (システム) | Systemd/カーネル | manage_service (サービスの管理), list_units (ユニットの一覧), get_kernel_modules (カーネルモジュールの取得) |
| Network (ネットワーク) | ネットワーキング | list_interfaces (インターフェースの一覧), ping_host (ホストへのPing), list_routes (経路の一覧) |
| Container (コンテナ) | Docker/Podman | list_containers (コンテナの一覧), start_container (コンテナの起動), execute_code (コードの実行) |
| Calculator (計算) | 数学演算 | calculate (計算), convert_units (単位変換), statistics (統計) |
| Self (自己) | LLM環境 | read_workspace_file (ワークスペースファイルの読み込み), write_workspace_file (ワークスペースファイルの書き込み), execute_shell_command (シェルコマンドの実行) |
| MCP | 設定 | list_mcp_tools (MCPツールの一覧), apply_mcp_template (MCPテンプレートの適用), get_mcp_config (MCP設定の取得) |
| Scheduler (スケジューラ) | タスクのスケジューリング | create_task (タスクの作成), list_tasks (タスクの一覧), Tasks/Reminders (リマインダーの作成) |
| AI | Ollama連携 | ai_generate (AI生成), ai_chat (AIチャット), ai_analyze_issue (AIによる問題分析) |
パーミッションテンプレート
- minimal: 基本的な監視(約18ツール)
- monitoring: システム監視(約18ツール)
- development: 開発ツール + コンテナ + 自己編集(約47ツール)
- security: セキュリティ監査ツール(約31ツール)
- full: 全201ツールを有効化 – 制限なし
ファイル構造
Hugging Face Space
├── app.py # Gradio UI($PORTを使用)
├── mcp_main.py # stdio MCPサーバー(サブプロセス)
└── systerd_lite/ # フルモジュール(全機能)
├── mcp.py # 201ツール
├── mcp_extended.py # 100以上の拡張ツール
├── calculator.py # 高度な計算機能
├── scheduler.py # タスクスケジューラ
├── container.py # コンテナマネージャ
├── ollama.py # AI連携
└── ...
すべての機能が見たい方はこちらから見てください。


感想
とにかく疲れました。
普通に一番疲れたのはツール類の実装。とにかく数が多い。
割と知識不足の中、systemdの勉強と、claudeくんとgeminiくんによる編集の指示を立て編集して、的外れだったり欲しいものは自分で実装したりして、疲れた5日間でした。
systerdの方のコードは、systemdとd-busのライセンスを考慮して公開するのがめんどくさかったため公開していません。ほしければ適当に言ってください。
ありがとうございました。

とある高専生。
AIとネットが好き。
将来はAIの妹と火星に住みたい。
discord : r_nightcore
このサイトの管理者。

コメント