M0: compilable skeleton — Kigi 0.1.0 fork surgery
Hard fork of xai-org/grok-build (Apache-2.0) re-targeted as Kigi, an
unofficial Kimi Code CLI community build.
Rename & identity
- 72 xai-*/xai-grok-* crates -> kigi-* (explicit: xai-grok-pager-bin ->
kigi-bin [binary `kigi`], xai-grok-pager -> kigi-tui; rest mechanical);
ptyctl, ptyctl-cli, third_party/ unchanged; proto package
xai.grok.tools.v1 -> kigi.tools.v1
- Config home ~/.kigi (KIGI_SHARE_DIR override), env prefix GROK_* ->
KIGI_*, `kigi --version` carries the unofficial-community-build notice
- clap identity, help text, startup banner, prompt templates rebranded
(templates re-encrypted)
Deletions (PRD removal list #5/#6/#7/#9/#10)
- voice input (xai-grok-voice) and all TUI wiring
- telemetry: Mixpanel client, external OTel stream, Sentry, OTLP layers,
trace/GCS/S3 upload queues (kigi-file-utils halved), workspace upload
module & dc_log, heap-profile uploader, auth-diagnostics uploader,
session-analytics halves of feedback; local zero-egress observability
preserved in new kigi-log crate (unified log, --debug firehose,
subsystem file logs, opt-in instrumentation)
- announcements (crate, remote-settings fields, TUI surfaces)
- plugin marketplace (crate, sources/browse/CTA/extensions-modal tab);
direct plugin install/uninstall/update via kigi-agent git_install kept
- relay/gateway/assets endpoints and features (agent relay, headless
relay transport, gateway bridge, LeaderEnvUrls); leader IPC socket now
~/.kigi/leader.sock + KIGI_LEADER_SOCKET, no ws-url derivation
- functional types rehomed instead of deleted: PermissionMode ->
kigi-config-types, McpInitStrategy -> kigi-mcp, PrCreationSource ->
session signals, TerminalDiagnostics -> kigi-pager-render, agent_id ->
shell util
Endpoints
- kigi-env rewritten: single production KigiEndpoints {coding_api_base_url
https://api.kimi.com/coding/v1 (KIGI_CODE_BASE_URL), oauth_host
https://auth.kimi.com (KIGI_OAUTH_HOST), update_base_url (GitHub
Releases API), upgrade_page_url}; GrokBuildEnvironment enum deleted
Toolchain & workspace hygiene
- Rust 1.97.0 pinned; edition 2024; full cargo update; git2 hoisted to
workspace at 0.21 (Option->Result API migration), quick-xml 0.41
- Root Cargo.toml hand-maintained (PRD §8.1): version 0.1.0 inherited by
all members, members sorted, unused deps pruned
- cargo-deny advisories gate (deny.toml with documented transitive
exceptions); CI workflow (check/clippy/fmt/deny/test, macOS+Linux)
- cross-crate test seams re-gated behind `test-support` cargo feature;
insta snapshot baselines renamed to the kigi_tui prefix
- clippy --workspace --all-targets: zero warnings; fmt clean
Fixes surfaced by the port
- updater probe/installer divergence (bin/kigi vs bin/grok symlink set)
- idle model-metadata refresh dead under KIGI_CODE_BASE_URL override
(new is_effective_coding_endpoint_url, loopback+override aware)
- macOS symlinked-TMPDIR fixture canonicalization (foreign_sessions,
fast-worktree); RSS measurement tests serialized via serial_test
Docs & legal (Apache §4)
- NOTICE added (upstream attribution + change statement); THIRD-PARTY
notices sustained; kigi-tools ported-code notices extended; README,
CONTRIBUTING, SECURITY, AGENTS.md rewritten
Out of scope for M0 (tracked): Kimi auth/inference (M1), search/fetch,
command parity, config import (M2), Computer Hub excision & final
brand-token sweep (M2), distribution & self-update rewrite (M3).
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
# MCP Servers
|
||||
|
||||
MCP (Model Context Protocol) servers extend Grok with external tool integrations. They let Grok interact with any service that implements the MCP standard.
|
||||
|
||||
---
|
||||
|
||||
## What Are MCP Servers?
|
||||
|
||||
An MCP server is a process that exposes tools to Grok over a standardized protocol. When you configure an MCP server, its tools become available to the model alongside Grok's built-in tools. The model can discover and call these tools during a session.
|
||||
|
||||
For example, a GitHub MCP server might expose tools like `create_issue`, `list_pull_requests`, and `search_code`. A database server might expose `query`, `list_tables`, and `describe_schema`.
|
||||
|
||||
See the [MCP specification](https://modelcontextprotocol.io) for protocol details.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
MCP servers are configured in `~/.kigi/config.toml` under `[mcp_servers.<name>]` sections.
|
||||
|
||||
### stdio Transport (Local Process)
|
||||
|
||||
Grok spawns a local process and communicates over stdin/stdout:
|
||||
|
||||
```toml
|
||||
[mcp_servers.my-server]
|
||||
command = "/path/to/server" # Server executable
|
||||
args = ["--flag", "value"] # Command arguments
|
||||
env = { API_KEY = "sk-..." } # Environment variables
|
||||
enabled = true # Enable or disable the server (default: true)
|
||||
startup_timeout_sec = 30 # Server startup timeout, seconds (default: 30)
|
||||
tool_timeout_sec = 6000 # Per-tool-call timeout fallback, seconds (default: 6000)
|
||||
tool_timeouts = { slow_op = 120 } # Per-tool timeout overrides, seconds
|
||||
```
|
||||
|
||||
> **Global startup-timeout override:** instead of setting `startup_timeout_sec`
|
||||
> per server, you can change the default for all servers via the `MCP_TIMEOUT`
|
||||
> environment variable (milliseconds, compatible with Claude Code) or
|
||||
> `KIGI_MCP_STARTUP_TIMEOUT_SECS` (seconds). A per-server `startup_timeout_sec`
|
||||
> still takes precedence over both. Cold-start `npx`/`uvx` servers that download
|
||||
> packages on first launch often need this; the default is 30s.
|
||||
>
|
||||
> **MCP tool-result size cap:** large MCP / `use_tool` results are truncated
|
||||
> inline (full payload spilled under the session `mcp/` folder). Default is
|
||||
> **20_000 bytes**. Override via:
|
||||
>
|
||||
> - env `KIGI_MAX_MCP_OUTPUT_BYTES` or `MAX_MCP_OUTPUT_BYTES` (bytes; Grok-native
|
||||
> wins if both set; Claude-style name, but we bound by **bytes** not tokens)
|
||||
> - `config.toml` — user-level (`~/.kigi/config.toml`) **or repo-level**
|
||||
> (`.kigi/config.toml` anywhere on the cwd → git-root chain; the deepest
|
||||
> file wins, and the repo value applies only once the folder is trusted):
|
||||
>
|
||||
> ```toml
|
||||
> [mcp]
|
||||
> max_output_bytes = 40000
|
||||
> ```
|
||||
>
|
||||
> Precedence: requirements.toml > env > repo `.kigi/config.toml` >
|
||||
> user/managed config > default. Repo edits apply to running sessions in that
|
||||
> directory via config hot-reload.
|
||||
|
||||
### HTTP/SSE Transport (Remote Server)
|
||||
|
||||
For remote MCP servers accessible over HTTP:
|
||||
|
||||
```toml
|
||||
[mcp_servers.remote-api]
|
||||
url = "https://mcp.example.com/api"
|
||||
headers = { "Authorization" = "Bearer token" }
|
||||
```
|
||||
|
||||
### Streamable HTTP with Session ID
|
||||
|
||||
```toml
|
||||
[mcp_servers.my-streamable-server]
|
||||
url = "https://mcp.example.com/api/mcp"
|
||||
headers = { "x-mcp-session-id" = "{{session_id}}" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CLI Management
|
||||
|
||||
Manage MCP servers from the command line without editing config files:
|
||||
|
||||
```bash
|
||||
# List configured MCP servers
|
||||
grok mcp list
|
||||
grok mcp list --json # Machine-readable output
|
||||
|
||||
# Add a stdio server. Everything after -- is the server command, so flags
|
||||
# like -y reach the server instead of being parsed by grok.
|
||||
grok mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/dir
|
||||
|
||||
# Add a stdio server with environment variables (-e is repeatable)
|
||||
grok mcp add postgres -e DATABASE_URL=postgres://localhost/mydb -- npx -y @modelcontextprotocol/server-postgres
|
||||
|
||||
# Add a remote HTTP server
|
||||
grok mcp add --transport http sentry https://mcp.sentry.dev/mcp
|
||||
|
||||
# Add a remote server with an authentication header (--header is repeatable)
|
||||
grok mcp add --transport http api https://mcp.example.com/mcp --header "Authorization: Bearer YOUR_TOKEN"
|
||||
|
||||
# Add a remote SSE server
|
||||
grok mcp add --transport sse linear https://mcp.linear.app/sse
|
||||
|
||||
# Remove a server
|
||||
grok mcp remove github
|
||||
|
||||
# Diagnose a server's configuration and connectivity
|
||||
grok mcp doctor # Check every configured server
|
||||
grok mcp doctor github # Check one server
|
||||
grok mcp doctor --json # Machine-readable output
|
||||
```
|
||||
|
||||
The transport defaults to `stdio`; pass `--transport http` or `--transport sse` for remote servers.
|
||||
|
||||
By default `grok mcp add` writes to `~/.kigi/config.toml` (`--scope user`). Use `--scope project` to write to `.kigi/config.toml` in the current directory instead, which can be committed and shared with your team (see [Project-Scoped MCP Servers](#project-scoped-mcp-servers)). Header and environment variable values are stored verbatim, so reference secrets as `${VAR}` instead of pasting them into a committed project config (see [Example Configurations](#example-configurations)). `grok mcp list` shows servers from both scopes, marking project-scoped ones with `(project)`.
|
||||
|
||||
`grok mcp remove` searches both scopes and exits 0 after removing the server. It exits 1 when the name is not found, or when the name is defined in both user and project scope — pass `--scope` to say which one to remove.
|
||||
|
||||
Breaking changes from earlier releases: `--env` now takes one `KEY=value` per flag (use `-e A=1 -e B=2`, not `--env A=1 B=2`), and server names may only contain letters, numbers, hyphens, and underscores.
|
||||
|
||||
---
|
||||
|
||||
## Project-Scoped MCP Servers
|
||||
|
||||
MCP servers can be configured per-project by placing a `.kigi/config.toml` in your repository:
|
||||
|
||||
```
|
||||
my-project/
|
||||
.kigi/
|
||||
config.toml
|
||||
src/
|
||||
...
|
||||
```
|
||||
|
||||
```toml
|
||||
# .kigi/config.toml
|
||||
[mcp_servers.linear]
|
||||
url = "https://mcp.linear.app/mcp"
|
||||
enabled = true
|
||||
```
|
||||
|
||||
When a server exposes a native HTTP/SSE endpoint, prefer the `url` form over wrapping it in a stdio proxy such as `npx mcp-remote <url>`. Grok handles HTTP/SSE and OAuth directly, so the native form avoids an extra subprocess per session. It also registers Grok's own OAuth client with the provider.
|
||||
|
||||
Grok walks from the current directory up to the git repo root, loading `.kigi/config.toml` at each level:
|
||||
|
||||
| Location | Scope | Priority |
|
||||
|----------|-------|----------|
|
||||
| `~/.kigi/config.toml` | All projects | Lowest |
|
||||
| `<repo-root>/.kigi/config.toml` | This repository | Medium |
|
||||
| `<cwd>/.kigi/config.toml` | Current directory | Highest |
|
||||
|
||||
If a project defines a server with the same name as a global one, the project version replaces it entirely (fields are not merged).
|
||||
|
||||
Project-scoped files contribute `[mcp_servers]`, `[plugins]`, and `[permission]` entries. Grok reads most other config sections only from `~/.kigi/config.toml`.
|
||||
|
||||
---
|
||||
|
||||
## Tool Naming
|
||||
|
||||
MCP tools are namespaced with the server name to avoid collisions:
|
||||
|
||||
- Server `filesystem` with tool `read_file` becomes `filesystem__read_file`
|
||||
- Server `github` with tool `create_issue` becomes `github__create_issue`
|
||||
|
||||
---
|
||||
|
||||
## Toggle Servers at Runtime
|
||||
|
||||
You can enable or disable MCP servers during a session without restarting Grok.
|
||||
|
||||
### The /mcps Modal
|
||||
|
||||
Open the MCP servers modal in the TUI:
|
||||
|
||||
- Run `/mcps` as a slash command
|
||||
- Or press `Ctrl+L` (non–VS Code family) and navigate to the MCP Servers tab; on VS Code family use `/plugins` or `/mcp` and open the MCP Servers tab
|
||||
|
||||
From the modal you can:
|
||||
|
||||
- See each server's source, enabled state, and tool count
|
||||
- Enable or disable a server with `Space`
|
||||
- Expand a server to view the tools it provides
|
||||
- Refresh the list with `r` after you edit `config.toml`
|
||||
- Authenticate an OAuth server with `i`
|
||||
- Add a server with `a`, or remove one with `x`
|
||||
|
||||
### Tool Discovery
|
||||
|
||||
The model has access to two built-in tools for working with MCP servers:
|
||||
|
||||
- `search_tool` — Discover available integration tools across all enabled MCP servers. Use this to find tools by name or description.
|
||||
- `use_tool` — Call an integration tool discovered via `search_tool`. Specify the fully-qualified tool name (e.g., `github__create_issue`).
|
||||
|
||||
---
|
||||
|
||||
## Compatibility
|
||||
|
||||
Grok loads MCP server configurations from multiple sources for compatibility:
|
||||
|
||||
| Source | Format | Location | Configurable |
|
||||
|--------|--------|----------|-------------|
|
||||
| `config.toml` | Native Grok config | `~/.kigi/config.toml`, `.kigi/config.toml` | Always on |
|
||||
| `.claude.json` | Claude Code format | `~/.claude.json` | `[compat.claude] mcps` |
|
||||
| `.cursor/mcp.json` | Cursor format | `~/.cursor/mcp.json`, `<project>/.cursor/mcp.json` | `[compat.cursor] mcps` |
|
||||
| `.mcp.json` | MCP standard format | Project root (cwd to git root) | Loaded unless you have imported or dismissed the Claude import prompt (the import marker is set) |
|
||||
|
||||
All sources are merged in priority order: config.toml > Claude > Cursor > `.mcp.json`. Servers from higher-priority sources take precedence when names conflict.
|
||||
|
||||
The Claude and Cursor MCP sources are scanned by default. To disable scanning for a specific vendor, set `[compat.<vendor>] mcps = false` in `~/.kigi/config.toml` or the corresponding environment variable (`KIGI_CURSOR_MCPS_ENABLED`, `KIGI_CLAUDE_MCPS_ENABLED`). See [Configuration](05-configuration.md#harness-compatibility) for details. Use `grok inspect` to see which MCP servers were loaded and their vendor origin (`[cursor]`, `[claude]`).
|
||||
|
||||
---
|
||||
|
||||
## MCP OAuth
|
||||
|
||||
For MCP servers that require OAuth authentication, Grok handles the credential flow automatically. When an MCP server requests OAuth credentials, Grok opens a browser-based authorization flow and stores the resulting tokens for future use.
|
||||
|
||||
---
|
||||
|
||||
## Example Configurations
|
||||
|
||||
Use the `url` form for hosted MCP servers and the `command` / `args` form for local stdio tools.
|
||||
|
||||
### Native HTTP (hosted services)
|
||||
|
||||
You must authenticate OAuth-based MCP servers before you can use them. Grok stores the resulting tokens under `~/.kigi/mcp_credentials.json`. After you edit `config.toml`, press `r` in the `/mcps` modal to refresh the server list.
|
||||
|
||||
```toml
|
||||
[mcp_servers.linear]
|
||||
url = "https://mcp.linear.app/mcp"
|
||||
enabled = true
|
||||
|
||||
[mcp_servers.sentry]
|
||||
url = "https://mcp.sentry.dev/mcp"
|
||||
enabled = true
|
||||
|
||||
[mcp_servers.mixpanel]
|
||||
url = "https://mcp.mixpanel.com/mcp"
|
||||
enabled = true
|
||||
```
|
||||
|
||||
For internal or self-hosted servers that authenticate with a static bearer token rather than OAuth, set the `Authorization` header explicitly:
|
||||
|
||||
```toml
|
||||
[mcp_servers.internal-tools]
|
||||
url = "https://mcp.internal.example.com/mcp"
|
||||
enabled = true
|
||||
|
||||
[mcp_servers.internal-tools.headers]
|
||||
Authorization = "Bearer <token>"
|
||||
```
|
||||
|
||||
To avoid putting secrets in the config file, reference an environment variable with `${VAR}` (or `${VAR:-default}`). Grok expands string fields in `[mcp_servers.*]` — `url`, `command`, `args`, and the values in `env` and `headers` — at load time:
|
||||
|
||||
```toml
|
||||
[mcp_servers.internal-tools]
|
||||
url = "https://mcp.internal.example.com/mcp"
|
||||
enabled = true
|
||||
headers = { "Authorization" = "Bearer ${INTERNAL_MCP_TOKEN}" }
|
||||
```
|
||||
|
||||
### Local stdio
|
||||
|
||||
Use stdio for tools that must run locally (filesystem access, local databases, in-house servers).
|
||||
|
||||
```toml
|
||||
# Filesystem access scoped to a directory
|
||||
[mcp_servers.filesystem]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"]
|
||||
|
||||
# Local Postgres
|
||||
[mcp_servers.postgres]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-postgres", "postgresql://user:pass@localhost/db"]
|
||||
|
||||
# Custom server with a longer startup timeout and tuned per-tool timeouts
|
||||
[mcp_servers.my-tools]
|
||||
command = "/usr/local/bin/my-mcp-server"
|
||||
args = ["--config", "/etc/my-mcp.json"]
|
||||
startup_timeout_sec = 30
|
||||
tool_timeout_sec = 120
|
||||
tool_timeouts = { slow_analysis = 300, quick_lookup = 10 }
|
||||
```
|
||||
|
||||
On Windows, npm installs launchers like `npx`, `npm`, `pnpm`, and `yarn` as `.cmd` batch shims (there is no `npx.exe`). Grok resolves a bare `command` such as `npx` to its real launcher path on `PATH` (honoring `PATHEXT`) before spawning, so these work without manually wrapping them in `cmd /c`. A `command` given as an absolute path or one containing a path separator is used as-is.
|
||||
|
||||
---
|
||||
|
||||
## Available MCP Servers
|
||||
|
||||
A partial list of MCP servers you can configure with the `url` or `command` forms shown above. Confirm the current endpoint or package name with each provider before use:
|
||||
|
||||
| Server | Transport | Endpoint / Package |
|
||||
|--------|-----------|--------------------|
|
||||
| Linear | HTTP (OAuth) | `https://mcp.linear.app/mcp` |
|
||||
| Sentry | HTTP (OAuth) | `https://mcp.sentry.dev/mcp` |
|
||||
| Mixpanel | HTTP (OAuth) | `https://mcp.mixpanel.com/mcp` |
|
||||
| Filesystem | stdio | `@modelcontextprotocol/server-filesystem` |
|
||||
| Git | stdio | `@modelcontextprotocol/server-git` |
|
||||
| GitHub | stdio | `@modelcontextprotocol/server-github` |
|
||||
| GitLab | stdio | `@modelcontextprotocol/server-gitlab` |
|
||||
| PostgreSQL | stdio | `@modelcontextprotocol/server-postgres` |
|
||||
| SQLite | stdio | `@modelcontextprotocol/server-sqlite` |
|
||||
| Puppeteer | stdio | `@modelcontextprotocol/server-puppeteer` |
|
||||
|
||||
See the [MCP Server Registry](https://github.com/modelcontextprotocol/servers) for the full list of community servers and the [MCP specification](https://modelcontextprotocol.io) for protocol details.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Server Not Starting
|
||||
|
||||
```bash
|
||||
# Test the server command manually
|
||||
npx -y @modelcontextprotocol/server-filesystem /path
|
||||
|
||||
# Increase startup timeout
|
||||
# In config.toml:
|
||||
[mcp_servers.filesystem]
|
||||
startup_timeout_sec = 30
|
||||
```
|
||||
|
||||
For stdio servers, Grok captures the process's standard error to `~/.kigi/logs/mcp/<server>.stderr.log`, truncated on each launch. Check this file when a server starts but fails to handshake:
|
||||
|
||||
```bash
|
||||
tail -f ~/.kigi/logs/mcp/filesystem.stderr.log
|
||||
```
|
||||
|
||||
### Viewing Server Status
|
||||
|
||||
Use `grok inspect` to see all loaded MCP servers and their sources:
|
||||
|
||||
```bash
|
||||
grok inspect # Human-readable
|
||||
grok inspect --json # Machine-readable
|
||||
```
|
||||
|
||||
### Debug Logging
|
||||
|
||||
```bash
|
||||
RUST_LOG=debug KIGI_LOG_FILE=/tmp/grok.log grok
|
||||
tail -f /tmp/grok.log
|
||||
```
|
||||
|
||||
Look for log entries containing `mcp` to trace server startup, tool discovery, and tool call execution.
|
||||
Reference in New Issue
Block a user