Grok Build CLI: Extending Grok with MCP, Skills, Plugins and Hooks
Grok ships with a strong default toolset, but its real power is how far you can extend it. Four mechanisms do the work: MCP servers add tools, skills add workflows, plugins package and share both, and hooks run your code at lifecycle moments. Here is how they fit together.
New to Grok? Start at Grok Build CLI: Zero to Hero (Start Here).
MCP servers add tools
The Model Context Protocol lets Grok talk to databases, issue trackers, APIs, anything that speaks MCP. Configure servers under [mcp_servers] in config.toml. Local tools use a stdio command, hosted services use a url (Grok speaks HTTP, SSE, and OAuth directly, so you rarely need a proxy wrapper).
You can also manage them without editing files. The CLI adds, lists, and removes servers, and project-scoped servers in .grok/config.toml override global ones by name.
Skills package a workflow
A skill is a directory with a SKILL.md file: YAML frontmatter plus Markdown instructions. The description field is critical, it is how Grok decides when to invoke the skill automatically. Skills also appear as slash commands, so a commit skill becomes /commit.
Run /skillify right after finishing a workflow and Grok will capture what you just did into a reusable skill, interviewing you to refine it.
Plugins distribute everything
A plugin bundles skills, agents, hooks, MCP servers, and LSP configs into one installable unit. Install from a GitHub shorthand, a URL, or a local path, and wire up a team marketplace so everyone gets the same tooling.
Plugins must be trusted before their hooks or MCP servers run, which stops an untrusted repo from executing code on your machine.
Hooks run your code at the right moment
Hooks fire on lifecycle events: SessionStart, PreToolUse, PostToolUse, and more. A PreToolUse hook can deny a dangerous command before it runs. Define them in JSON with an optional matcher on the tool name.
The hook receives the full event as JSON on stdin and, for blocking hooks, returns an allow or deny decision on stdout. Here is the classic "block destructive commands" guard.
Hooks fail open on any error, so to actually block something your script must run to completion and emit an explicit deny. That is a safety feature, not a bug.
Continue the series
The full series
- Grok Build CLI: Zero to Hero (Start Here)
- Grok Build CLI: Sessions, Rewind and Compaction
- Grok Build CLI: Slash Commands and Keyboard Mastery
- Grok Build CLI: Teaching Grok Your Project (AGENTS.md)
- Grok Build CLI: Models and Custom Endpoints
- Grok Build CLI: Extending Grok with MCP, Skills, Plugins and Hooks (you are here)
- Grok Build CLI: Cross-Session Memory
- Grok Build CLI: Subagents, Plan Mode and Background Work
- Grok Build CLI: Headless Mode and Automation
- Grok Build CLI: Sandbox and Permissions
- Grok Build CLI: IDE Integration with ACP
- Grok Build CLI: The Evolution (Power-User Version History)