Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,36 @@ home-manager build --flake .
home-manager generations
```

## Codex と Claude Code から Grafana MCP を使う

`mcp-grafana` は Nix パッケージとしてインストールされ、Codex と Claude Code が同じ
起動設定を使います。起動時に Doppler から必要な環境変数を受け取り、読み取り専用
モードで Grafana に接続します。あらかじめ Doppler CLI へログインしてください。

1. Grafana に最小限の RBAC 権限を持つ Service Account を作成し、トークンを発行します。
2. Doppler の project `mcp`、config `prd` に `GRAFANA_URL` と `GRAFANA_SERVICE_ACCOUNT_TOKEN` の 2 変数だけを登録します。
3. Home Manager の設定を反映して、各クライアントから MCP サーバーを確認します。

トークンの値を dotfiles に保存したり、Codex の親プロセスに設定したりしません。

```bash
home-manager switch --flake .
codex mcp list
claude mcp list
```

Codex と Claude Code を再起動した後、それぞれの `/mcp` でも接続状態を確認できます。

Grafana Cloud ではスタックの URL を `GRAFANA_URL` に設定します。ホスト上の Grafana
へ接続する場合は、`http://localhost:3000` のような URL を指定できます。

`--disable-write` は誤操作を防ぐための補助策であり、Grafana 側の RBAC に代わるものでは
ありません。MCP サーバーは必須扱いにしていないため、Doppler や Grafana への接続に
失敗しても Codex や Claude Code 全体の起動は止まりません。

`mcp-grafana` を更新するときは、`modules/grafana-mcp.nix` のバージョンと
hash を同時に更新してください。

## 開発環境テンプレート

プロジェクトごとに独立した Nix 開発環境を提供するテンプレートを管理しています(`templates/` 参照)。
Expand Down
4 changes: 4 additions & 0 deletions config/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
- **汎用スクリプト実行**: 任意コードの実行につながる恐れがあるインタープリタ。
- 例: `python`, `python3`

Nix で宣言した固定の MCP 起動設定が子プロセスとして Doppler を起動する経路は、
AI Agent がツール経由で任意の Doppler コマンドを実行する経路とは別に扱います。
この区別は、AI Agent に Doppler の実行権限を与えるものではありません。

## 5. permission 設定の扱い

- AI Agent のコマンド許可判断の原則はこの `config/AGENTS.md` に記述する
Expand Down
1 change: 1 addition & 0 deletions home.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
imports = [
./modules/packages.nix
./modules/llm-agents.nix
./modules/grafana-mcp.nix
./modules/git.nix
./modules/gpg.nix
./modules/ssh.nix
Expand Down
31 changes: 29 additions & 2 deletions modules/claude.nix
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
{ ... }:
{
pkgs,
grafanaMcp,
...
}:
let
jsonFormat = pkgs.formats.json { };
pluginManifest = jsonFormat.generate "claude-grafana-mcp-plugin.json" {
name = "grafana-mcp";
};
mcpConfig = jsonFormat.generate "claude-grafana-mcp.json" {
mcpServers.grafana = {
inherit (grafanaMcp) command args;
type = "stdio";
};
};
grafanaMcpPlugin = pkgs.runCommand "claude-grafana-mcp-plugin" { } ''
install -Dm644 ${pluginManifest} "$out/grafana-mcp/.claude-plugin/plugin.json"
install -Dm644 ${mcpConfig} "$out/grafana-mcp/.mcp.json"
'';
claudeSkills = pkgs.symlinkJoin {
name = "claude-skills";
paths = [
../config/agents/skills
grafanaMcpPlugin
];
};
in
{
home.file.".claude/CLAUDE.md".source = ../config/claude/CLAUDE.md;

home.file.".claude/settings.json".source = ../config/claude/settings.json;

home.file.".claude/skills" = {
source = ../config/agents/skills;
source = claudeSkills;
};

home.file.".claude/hooks/notify.sh" = {
Expand Down
6 changes: 6 additions & 0 deletions modules/codex.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pkgs,
lib,
homeDirectory,
grafanaMcp,
...
}:
let
Expand Down Expand Up @@ -96,6 +97,11 @@ let
plugins."google-calendar@openai-curated".enabled = true;
plugins."github@openai-curated".enabled = true;

mcp_servers.grafana = {
inherit (grafanaMcp) command args;
startup_timeout_sec = 120;
};

features.codex_git_commit = true;
};
codexConfigFile = tomlFormat.generate "codex-config.toml" codexConfig;
Expand Down
53 changes: 53 additions & 0 deletions modules/grafana-mcp.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{ pkgs, ... }:
let
# renovate: datasource=github-releases depName=grafana/mcp-grafana
version = "0.14.0";
package = pkgs.stdenvNoCC.mkDerivation {
pname = "mcp-grafana";
inherit version;

src = pkgs.fetchurl {
url = "https://github.com/grafana/mcp-grafana/releases/download/v${version}/mcp-grafana_Linux_x86_64.tar.gz";
hash = "sha256-gcWrHESi580nBCCywjWHvrYqtZgvLd6LgAQFqp7G6Cw=";
};

sourceRoot = ".";
dontBuild = true;

installPhase = ''
runHook preInstall

install -Dm755 mcp-grafana "$out/bin/mcp-grafana"

runHook postInstall
'';

meta = {
description = "MCP server for Grafana";
homepage = "https://github.com/grafana/mcp-grafana";
license = pkgs.lib.licenses.asl20;
mainProgram = "mcp-grafana";
platforms = [ "x86_64-linux" ];
sourceProvenance = [ pkgs.lib.sourceTypes.binaryNativeCode ];
};
};
in
{
_module.args.grafanaMcp = {
command = "${pkgs.doppler}/bin/doppler";
args = [
"run"
"--project"
"mcp"
"--config"
"prd"
"--"
"${package}/bin/mcp-grafana"
"-t"
"stdio"
"--disable-write"
];
};

home.packages = [ package ];
}