Why this matters
Built-in tools stop at the repo and the web. The next layer is other systems: a tracker, a database, a filesystem jail, a formatter that runs after every edit. Grok Build does that with three different objects that people mash into one word.
Specialist rung. If you do not write software or run agents, you can stop after C4 and still have reached repo level.
MCP servers add tools. Plugins install a bundle (skills, agents, hooks, MCP, LSP). Hooks run your script at a lifecycle event. If you treat them as the same switch, you will enable a plugin you do not trust, commit a token, or believe a hook is blocking commands when it crashed and failed open.
This module is how those three attach, how they are named, and what you have to trust before any of them run. The artifact is not a screenshot of a marketplace. It is a project config you can read, a hook that denied a command you asked for, and grok inspect output that matches what you think is loaded.
Teach
Three layers, three jobs
| Layer | What it adds | When it runs | Trust |
|---|
| MCP server | Tools the model can call (linear__save_issue, filesystem__read_file) | When the model uses search_tool / use_tool | Project MCP rides the same folder-trust gate as project hooks |
| Plugin | A directory of skills, slash commands, agents, hooks, MCP, LSP | After install and enable; hooks/MCP stay dark until trusted | grok plugin install … --trust, or a path under ~/.grok/plugins/ |
| Hook | A command or HTTP POST on PreToolUse, Stop, SessionStart, and the rest | On the event. Only PreToolUse (and Stop / SubagentStop) can change control flow | Global ~/.grok/hooks/ always trusted; project .grok/hooks/ needs /hooks-trust |
Do not install a plugin to “add MCP.” You can add an MCP server with no plugin. Do not write a hook to “add a Linear tool.” That is an MCP server. Do not expect a skill from C6 to block rm. That is a hook or a deny rule (C10).
MCP servers
An MCP server is a process that speaks the Model Context Protocol. Grok starts it (stdio) or connects to it (HTTP / SSE). Configure in ~/.grok/config.toml (every project) or .grok/config.toml (this repo). Same name: the project entry replaces the user one; fields do not merge.
# .grok/config.toml — team-shareable. Hosted servers use url = "https://…"
[mcp_servers.practice-fs]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "."]
enabled = true
# After -- belongs to the server, so -y reaches npx
grok mcp add --scope project practice-fs -- npx -y @modelcontextprotocol/server-filesystem .
grok mcp list
grok mcp doctor practice-fs
--scope user (default) writes ~/.grok/config.toml. --scope project writes .grok/config.toml here. Store secrets as ${INTERNAL_MCP_TOKEN}, not a bearer in git. On Windows, command = "npx" is enough — Grok resolves the .cmd shim.
Names. Server practice-fs plus tool read_file is practice-fs__read_file. The model finds tools with search_tool, then calls them with use_tool. If a C8 subagent gets an empty catalog, the parent never connected the server, or mcpInheritance filtered it. Plugin agents cannot declare their own mcpServers.
OAuth tokens land in ~/.grok/mcp_credentials.json (owner-only plaintext). Never paste that file. After a config edit, r in /mcps or grok mcp doctor. grok inspect shows each server and its source. On a name clash: config.toml > Claude > Cursor > .mcp.json.
Plugins
A plugin is a folder (skills/, commands/, agents/, hooks/hooks.json, .mcp.json). A marketplace is a git repo with .grok-plugin/marketplace.json. Adding a marketplace installs nothing. An installed plugin stays off until you enable it. Trust is a third switch: hooks and MCP stay dark until trusted.
grok plugin marketplace add owner/repo
grok plugin install deploy-tools --trust
grok plugin details deploy-tools
Without --trust, install warns and stops. That is correct. Plugins run as you. /plugins opens the extensions modal (Ctrl+L outside the VS Code family). Space enables. Collision: /plugin-name:skill. [plugins] enabled = ["deploy-tools"] in config is the durable on-switch.
~/.grok/plugins/ is auto-trusted. .grok/plugins/ is not. Plugin agent frontmatter cannot set mcpServers, hooks, or permissionMode: bypassPermissions. You do not publish a marketplace today. You do need to know a team plugin is how a shop ships skill + hook + MCP as one unit.
Hooks
A hook is a command or an HTTP POST. Grok fires it on a lifecycle event. Input is JSON on stdin. The useful gate is PreToolUse: write {"decision":"deny","reason":"…"} to stdout and exit 2, and that tool call does not run.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "node bin/deny-demo.js", "timeout": 5 }
]
}
]
}
}
matcher is a regex on the tool name. Bash also matches Grok’s run_terminal_command. MCP calls match the qualified server__tool name, not use_tool. Empty matcher matches everything.
Fail-open. Timeout, crash, missing script, malformed JSON: the failure is recorded in scrollback, and the tool runs. Only an explicit deny blocks. A hook you cannot see succeed is not a security boundary. C10 will put deny rules and (on Linux/macOS) the sandbox under that same sentence.
Stop / SubagentStop can keep the agent working ({"decision":"block","reason":"tests failed"}). UserPromptSubmit is observe-only here. SessionStart does not fire for a subagent’s own session.
~/.grok/hooks/*.json is always trusted. Project .grok/hooks/ is silently skipped until /hooks-trust (or --trust). That grant (~/.grok/trusted_folders.toml) covers MCP, LSP, and hooks together. /hooks-untrust revokes it. /hooks lists what loaded; r reloads.
Inspect, then talk to the model
grok inspect
grok mcp list
grok plugin list
Inside the TUI: /mcps, /plugins, /hooks. If inspect and the modal disagree with the story in your head, the files win. Fix the files. Do not prompt the model to “enable Linear” and hope.
Worked example
Same practice desk as C1 (%USERPROFILE%\grok-build-practice). Not this LMS. Not a client repo.
cd into the practice repo. Confirm git status is clean enough that you can see new files.
- Add a project filesystem MCP rooted on
. — the command in Teach. Run grok mcp list. You should see practice-fs marked (project).
- Create
.grok/hooks/deny-demo.json with the PreToolUse / Bash block above. Create bin/deny-demo.js so that any command containing GROK_HOOK_DENY_DEMO writes a deny JSON and exits 2. Otherwise allow.
- Launch
grok in that directory. Run /hooks-trust when asked, or because the hook is not listed. Open /mcps and /hooks. Press r if you edited files after launch.
- Send:
Run the shell command echo GROK_HOOK_DENY_DEMO and then echo ok. Do not find another way to print those strings.
- Scrollback should show the hook deny, reason visible,
echo ok never reached. If the command ran, the hook failed open — node missing, path wrong, folder untrusted, or matcher missed. Fix that before you continue.
- Send:
Using search_tool, find tools from practice-fs. Name one qualified tool. Do not write files.
/quit. Run grok inspect and save the MCP + hook lines.
What you did not do: paste an API key into config.toml, install a marketplace plugin from a name you Googled, or flip always-approve so the deny would “just work.” The deny is the hook. Always-approve is C9 and C10, and it does not override a hook deny.
Your turn
Do c7-l01-e1 in Grok Build, in a git repo you own. The exercise makes Grok Build add the MCP server, write the hook, trust the folder, and produce the deny plus grok inspect. If you type the JSON by hand and never open the TUI, you did not take the module.
Common failure
Project hooks that “do nothing.” The folder is untrusted. /hooks will not show them as live. /hooks-trust. The same grant is what lets project MCP start.
A hook you treat as a lock. The script threw, node was not on PATH, or you matched use_tool instead of practice-fs__read_file. Fail-open means the dangerous command ran. Read the scrollback annotation. Until you have seen a deny you caused, you do not have a hook.
Secrets in git. Authorization = "Bearer xai-…" in a committed .grok/config.toml. Use ${VAR}. Rotate anything that already landed in history.
Install without reading. grok plugin install some-stranger/cool-tools --trust because a blog said to. Plugins run as you. Marketplace add, then grok plugin details, then a source you recognize, then --trust.
What’s next
C8 is the other kind of extra process: subagents with their own context window, and git worktrees so a child can edit without stepping on your tree. MCP inheritance rides along. Do not skip the isolation part.