{ inputs, lib, config, pkgs, myhostname, ... }: let inherit (lib) mkOption types; googleWorkspaceStateDir = "/home/fw/.local/share/google-workspace-mcp/${myhostname}"; in { options.opencode.mcpEnabled = mkOption { type = types.attrsOf types.bool; default = { az = false; k8s = true; github = true; jira = true; google = false; mssql = false; vault = false; }; description = "Per-host MCP enablement flags for OpenCode servers."; }; imports = [ ../moduler/tmux.nix ../moduler/fish.nix ../moduler/kitty.nix ../moduler/dunst.nix ../moduler/nixpkgs.nix # ../moduler/firefox.nix ../moduler/zathura.nix ../moduler/lazygit.nix ../moduler/ssh.nix ../moduler/oh-my-posh.nix ../moduler/gtk.nix # ../moduler/neovim.nix ../moduler/programs/k9s ]; config = { programs.home-manager.enable = true; programs.fish.enable = true; programs.opencode = { enable = true; enableMcpIntegration = false; settings = { "$schema" = "https://opencode.ai/config.json"; theme = lib.mkForce "catppuccin"; plugin = [ "@ex-machina/opencode-anthropic-auth" ]; provider = { ollama = { npm = "@ai-sdk/openai-compatible"; options = { baseURL = "http://localhost:11434/v1"; }; models = { # Only include models that support function calling (tools) "gemma2:latest" = {}; "llama3.1:8b" = {}; "qwen2.5-coder:14b" = {}; "qwen2.5-coder:32b" = {}; # Note: deepseek-coder models and codellama:13b don't support tools }; }; }; mcp = { az = { type = "local"; enabled = config.opencode.mcpEnabled.az or false; command = [ "docker" "run" "-i" "--rm" "--env-file" "/home/fw/.azure/credentials" "mcr.microsoft.com/azure-sdk/azure-mcp:latest" ]; }; k8s = { type = "local"; enabled = config.opencode.mcpEnabled.k8s or false; command = [ "docker" "run" "--rm" "-i" "--user" "1000:100" "-v" "/home/fw/.kube:/kube:ro" "ghcr.io/containers/kubernetes-mcp-server:latest" "--kubeconfig" "/kube/config" ]; }; github = { type = "local"; enabled = config.opencode.mcpEnabled.github or false; command = [ "docker" "run" "-i" "--rm" "-e" "GITHUB_PERSONAL_ACCESS_TOKEN" "ghcr.io/github/github-mcp-server" ]; }; jira = { type = "local"; enabled = config.opencode.mcpEnabled.jira or false; command = [ "docker" "run" "-i" "--rm" "--env-file" "/home/fw/.config/opencode/.env.local" "ghcr.io/sooperset/mcp-atlassian:latest" ]; }; google = { type = "local"; command = [ "docker" "run" "-i" "--rm" "--network" "host" "--user" "1000:100" "-v" "${googleWorkspaceStateDir}:/home/app/.google_workspace_mcp" "-e" "GOOGLE_OAUTH_CLIENT_ID" "-e" "GOOGLE_OAUTH_CLIENT_SECRET" "-e" "USER_GOOGLE_EMAIL" "-e" "OAUTHLIB_INSECURE_TRANSPORT=1" "--entrypoint" "/app/.venv/bin/python" "ghcr.io/taylorwilsdon/google_workspace_mcp:latest" "/app/main.py" "--single-user" ]; enabled = config.opencode.mcpEnabled.google or false; }; mssql = { type = "local"; command = [ "nix" "shell" "nixpkgs#uv" "nixpkgs#freetds" "-c" "uvx" "--from" "git+https://github.com/RichardHan/mssql_mcp_server.git@77b0c6a9771e3f83a54c03dad42f1a53e0a20d0e" "mssql_mcp_server" ]; enabled = config.opencode.mcpEnabled.mssql or false; }; vault = { type = "local"; command = [ "docker" "run" "-i" "--rm" "-e" "VAULT_ADDR" "-e" "VAULT_TOKEN" "-e" "VAULT_NAMESPACE" "hashicorp/vault-mcp-server" ]; enabled = config.opencode.mcpEnabled.vault or false; }; }; }; }; home.activation.opencodeAtlassianEnv = lib.hm.dag.entryAfter [ "writeBoundary" ] '' mkdir -p "$HOME/.config/opencode" if [ -r /run/secrets/opencode_atlassian_env ]; then ln -sf /run/secrets/opencode_atlassian_env "$HOME/.config/opencode/.env.local" fi ''; home.activation.googleWorkspaceMcpState = lib.hm.dag.entryAfter [ "writeBoundary" ] '' mkdir -p "${googleWorkspaceStateDir}" ''; home.file.".config/opencode/session-prompt.txt".text = '' Session instructions for this entire chat: 1) Tooling / binaries - Always use Nix for binaries and tool execution. - Prefer `nix shell nixpkgs# -c ` (or `nix develop -c ` if the repo already defines a dev shell). - Do not run tools directly from global/system installs unless I explicitly ask. 2) Daily note logging - Track general work notes in: /home/fw/knowledge/notes/daily - Use today's daily note file (create it if missing) and keep it updated as work progresses. - Add short, timestamped entries for meaningful actions/decisions. 3) Schedule updates - In today's daily note, maintain a "Schedule" section/tab and keep it current with what we are actively doing. - When tasks change, update Schedule first, then continue implementation. - Keep Schedule concise and action-oriented. 4) Working style - Don't ask for confirmation on normal steps; proceed with sensible defaults. - Only ask when blocked, destructive, or security-sensitive. ''; programs.alacritty = { enable = true; # theme = "catppuccin_${theme}"; theme = "catppuccin_mocha"; settings = { font = { normal = { family = lib.mkForce "FiraCode Nerd Font Mono"; }; size = lib.mkForce 16; }; }; }; home.username = "fw"; home.homeDirectory = "/home/fw"; home.stateVersion = "25.05"; systemd.user.startServices = "sd-switch"; }; }