Skip to main content

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 cataloggithub.com/modelcontextprotocol/servers. Maintained by the MCP project; covers filesystem, GitHub, Slack, Google Drive, Postgres, SQLite, Memory, Brave Search, Sequential Thinking, etc.
  • Community listgithub.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 usesYou'll need
npx invocationsNode.js 20+
uvx invocationsuv
Standalone binaryJust the binary in your PATH
Python python -mPython 3.10+ and the package installed (pip install …)
DockerDocker 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 dialog has four sections:

1. Identity

  • Name — what shows in the Tools view. Free text.
  • ID — auto-generated; rename if you want a stable identifier (used in audit log entries).

2. Transport

TransportWhen to use
stdioDefault. Kenaz spawns the server as a child process and talks over stdin/stdout. Fits anything you can run with npx, uvx, a shell script, or a binary.
HTTPThe server runs as a long-lived HTTP service (e.g. inside Docker, on a remote box).
SSESome hosted MCP services use server-sent events. Check the server's docs.

3. Command (stdio) or URL (HTTP/SSE)

For stdio, fill in:

  • Command — the executable. npx, uvx, python, /usr/local/bin/my-mcp-server, etc.
  • Arguments — the flags + args, one per line. The same tokens you'd pass on the command line.
  • Working directory — optional. Defaults to your home directory.

For HTTP/SSE:

  • URL — base URL of the server (e.g. https://mcp.your-corp.example).
  • Bearer token — optional auth header.

4. Environment

Two reasons to set env vars on a server:

  • API keys for the underlying service (GITHUB_TOKEN, SLACK_BOT_TOKEN, …).
  • Configuration the server reads from env (MCP_LOG_LEVEL, WORKSPACE_ROOT, …).

Format: one KEY=value per line. Values typed here go to the OS keychain on save and are re-injected when Kenaz spawns the server. Plaintext only ever exists in memory while the child process is alive.

You can also reference an existing keychain entry via KEY=keychain:<entry-name> — useful when multiple servers share the same key (e.g. you have a single GITHUB_PAT you reuse across the GitHub MCP and a custom one).

5. Save and verify

Click Save. Kenaz spawns the server, runs the MCP initialize handshake, pulls the tool list, and shows the tools in the right panel of the dialog. If the server fails to start, you'll see the error message inline; common causes are at the bottom of this page.

Concrete examples

Filesystem (sandboxed)

Transport: stdio
Command: npx
Arguments:
-y
@modelcontextprotocol/server-filesystem
/Users/you/code

The path argument scopes the server to that root — file operations are confined there.

GitHub

Transport: stdio
Command: npx
Arguments:
-y
@modelcontextprotocol/server-github
Environment:
GITHUB_TOKEN=ghp_…

Generate a fine-grained PAT at github.com/settings/tokens?type=beta. Scope to the minimum (read-only contents + issues/PRs is plenty for chat use).

Postgres (read-only)

Transport: stdio
Command: npx
Arguments:
-y
@modelcontextprotocol/server-postgres
postgres://readonly_user@localhost:5432/yourdb

Use a read-only DB role for safety. The MCP server doesn't enforce read-only on its own.

Slack

Transport: stdio
Command: npx
Arguments:
-y
@modelcontextprotocol/server-slack
Environment:
SLACK_BOT_TOKEN=xoxb-…
SLACK_TEAM_ID=T01234567

Bot token — create a Slack app, install to your workspace, copy the Bot User OAuth Token.

Memory (persistent across sessions)

Transport: stdio
Command: npx
Arguments:
-y
@modelcontextprotocol/server-memory

Stores facts in a local JSON file the server manages. No external service.

A Docker-based server

Transport: stdio
Command: docker
Arguments:
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

Transport: stdio
Command: uvx
Arguments:
--from
./path/to/your-server
your-server-cli

Or, if it's installed system-wide:

Transport: stdio
Command: /usr/local/bin/your-mcp-server
Arguments:
--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, Tools view → ⋯ → Import from JSON accepts that exact format. Each entry under mcpServers becomes a Kenaz MCP server configured for stdio with the command, args, and env you'd otherwise type by hand.

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

A .kenaz/mcp.json file in your project root, in the same shape as the import format above, registers MCPs that activate only for sessions inside that project:

{
"mcpServers": {
"project-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres",
"postgres://localhost:5432/projectdb"]
}
}
}

Useful for committing a curated MCP set alongside a repo so your team gets the same tools without manual setup.

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 initialize response 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.completed pair. If a server polls aggressively (rare, but possible), this can balloon the log. Either fix the server or set audit.suppress_kinds: ['tool.invoked', 'tool.completed'] for that specific server in Settings → Audit.

Where logs live

macOS: ~/Library/Logs/Kenaz/mcp/<server-id>.log
Windows: %APPDATA%\Kenaz\Logs\mcp\<server-id>.log
Linux: $XDG_DATA_HOME/kaneaz-harness/logs/mcp/<server-id>.log

Captures stderr from the spawned process plus Kenaz's MCP-framing log. Rotated daily; last 7 days kept.