Installing MCP servers
Step-by-step guide to wiring up a Model Context Protocol (MCP) server in Kenaz — the official ones, community ones, and your own.
For an overview of what MCP is and how Kenaz uses it, see Tools.
Where to find servers
- Official catalog — github.com/modelcontextprotocol/servers. Maintained by the MCP project; covers filesystem, GitHub, Slack, Google Drive, Postgres, SQLite, Memory, Brave Search, Sequential Thinking, etc.
- Community list — github.com/punkpeye/awesome-mcp-servers. Long tail; quality varies.
- Vendor-built — many SaaS vendors now ship their own (Notion, Linear, Stripe, Sentry, …). Check the vendor's docs.
- Your team's internal servers — anything you've written that speaks the MCP spec.
Prerequisites
The runtime depends on the server's language:
| Server uses | You'll need |
|---|---|
npx invocations | Node.js 20+ |
uvx invocations | uv |
| Standalone binary | Just the binary in your PATH |
Python python -m | Python 3.10+ and the package installed (pip install …) |
| Docker | Docker Desktop / Engine running |
Most official servers use npx or uvx so you don't have to manually install anything beyond the runtime.
Adding a server in Kenaz
Tools view → Add MCP server. The modal has three tabs:
Registry tab
Browse the curated catalog of shipped recipes (Brave Search, filesystem, GitHub, Postgres, Slack, memory, and more). Click a recipe to install it — Kenaz prompts for any required API keys and stores them in the OS keychain.
Paste config tab
Paste a mcpServers JSON block (Claude Desktop / Cursor format). Kenaz translates each entry into a recipe. Supported fields: command, args, env. HTTP/SSE entries are flagged as unsupported. Review the translation report and choose which entries to import.
Custom recipe tab
Form-based recipe author for servers not in the catalog. Fields:
- ID — stable identifier used in audit log entries.
- Display name — what shows in the Tools view.
- Transport —
stdio,http, orsse. - For stdio: Command and Args (space-separated), which become the spawn argv.
- For http / sse: URL and optional Headers (JSON object) and SSE Post URL.
After filling the form, click Save. Kenaz registers the recipe. Spawn and the MCP initialize handshake happen when the recipe is enabled. If the server fails to start, check Tools → server → Logs for the full subprocess stderr.
Concrete examples
The examples below show the Custom recipe tab fields. Filesystem, GitHub, Postgres, Slack, and Memory are available directly from the Registry tab — install from there and skip the manual entry.
A Docker-based server (Custom recipe tab)
Transport: stdio
Command: docker
Args: run --rm -i ghcr.io/your-org/your-mcp-server:latest
-i keeps stdin open — without it the MCP handshake fails immediately. --rm cleans up the container when Kenaz exits.
A custom Python server (Custom recipe tab)
Transport: stdio
Command: uvx
Args: --from ./path/to/your-server your-server-cli
Or, if installed system-wide:
Transport: stdio
Command: /usr/local/bin/your-mcp-server
Args: --config /etc/your-mcp/config.toml
Importing a JSON config
Many MCP server READMEs publish a JSON snippet shaped for Claude Desktop / Cursor:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_…"
}
}
}
}
In Kenaz, use the Paste config tab in the Add MCP Server modal. Each entry under mcpServers is translated to a Kenaz recipe. Review the translation report and confirm which entries to import.
This is the fastest way to follow a vendor's "add to your AI client" instructions when they only ship the JSON.
Per-project MCP servers
Per-project MCP server configuration via a project-local file is not yet supported in the current release. All MCP recipes are configured globally through the Tools view. Watch the release notes for project-scoped recipe support.
Building your own
The MCP project ships SDKs in TypeScript, Python, Go, Rust, and Java. The server quickstart walks through writing one in any of them.
The minimal shape: declare a list of tools (name, description, JSON schema for arguments) and implement a handler for each. The SDK takes care of the JSON-RPC framing and the initialize handshake.
A trivial Python example:
# pip install mcp
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-server")
@mcp.tool()
def greet(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
Save as hello.py. In Kenaz:
Transport: stdio
Command: python
Arguments:
/full/path/to/hello.py
After save, you'll see one tool — greet — in the server's tool list.
Troubleshooting
- "Server failed to start" — Kenaz couldn't spawn the command. Most often the runtime isn't on PATH (Node, Python, uv, Docker). The error message in the dialog has the full subprocess stderr.
- "Initialize timeout" — the server started but didn't send the
initializeresponse in 10 seconds. Either the server is slow on first run (npm caching, Docker pull), or it crashed before responding. Check Tools → server → Logs for the captured stderr. - "Tool list empty" — the server initialized but advertised zero tools. Some servers gate tools on environment (e.g. you didn't set
GITHUB_TOKEN, so the GitHub server registered no tools to avoid 401s on every call). - "Permission denied" inside the model's tool call — the MCP server itself returned an auth error. Check the env vars you set; rotate the API key if needed.
- Server crashes mid-session — Kenaz auto-restarts up to 3 times in a 60-second window before giving up. If a server keeps crashing, run the same command in a terminal manually to see the unfiltered output.
- Audit log noise — every MCP call writes a
tool.invoked+tool.completedpair. If a server polls aggressively (rare, but possible), this can balloon the log. Either fix the server or setaudit.suppress_kinds: ['tool.invoked', 'tool.completed']for that specific server in Settings → Audit.
Where logs live
MCP server stderr and connection logs are captured under the harness log directory:
~/.kenaz/harness/<env>/logs/
Check Tools → server → Logs in the UI to view the captured output without navigating to the filesystem.