# MCP server

> Connect Claude, Cursor or any MCP client to netweft with an API key and let an agent read projects, audits, keywords, rankings and context.

Source: https://netweft.com/docs/mcp-server
Updated: 2026-10-24

**netweft runs a Model Context Protocol server at https://api.netweft.com/mcp. An agent with an API key gets 25 read-only tools over the workspace's stored data, and clients that only run local servers connect through netweft-mcp on npm.**

netweft speaks the Model Context Protocol, so an AI agent can read a workspace
the way the in-app [assistant](/docs/project-assistant) does. Every tool is
read-only over data netweft already stores: an agent can read a workspace but
cannot change it or spend its credits. Paid lookups stay in the dashboard.

## Connect a client

1. Issue an [API key](/docs/api-keys) under **Settings**, then **API keys**.
   The key is shown once, beside the snippets below filled in for your
   workspace.
2. Add netweft to your client, with the key in the `Authorization` header.

| Setting | Value |
| --- | --- |
| URL | `https://api.netweft.com/mcp` |
| Transport | Streamable HTTP (JSON-RPC 2.0 over `POST`) |
| Header | `Authorization: Bearer nw_<prefix>_<secret>`, or `x-api-key: nw_<prefix>_<secret>` |
| Protocol versions | `2026-07-28`, and the handshake revisions `2025-11-25`, `2025-06-18` and `2025-03-26` |

Clients that speak HTTP connect to that URL directly. Clients that only start
local servers, such as Claude Desktop and Windsurf, run
[`netweft-mcp`](https://www.npmjs.com/package/netweft-mcp) from npm, which
relays each message to the same URL with your key. It needs Node.js 20 or
later and nothing installed by hand: the client starts it with `npx`.

### Claude Code

```sh
claude mcp add --transport http netweft https://api.netweft.com/mcp \
  --header "Authorization: Bearer $NETWEFT_API_KEY"
```

To share the setup with a project without sharing the key, add it to
`.mcp.json` and keep the key in an environment variable:

```json
{
  "mcpServers": {
    "netweft": {
      "type": "http",
      "url": "https://api.netweft.com/mcp",
      "headers": {
        "Authorization": "Bearer ${NETWEFT_API_KEY}"
      }
    }
  }
}
```

### Claude Desktop

Open **Settings**, then **Developer**, then **Edit Config**, and add netweft
to `claude_desktop_config.json`. Restart Claude Desktop afterwards.

```json
{
  "mcpServers": {
    "netweft": {
      "command": "npx",
      "args": ["-y", "netweft-mcp"],
      "env": {
        "NETWEFT_API_KEY": "nw_..."
      }
    }
  }
}
```

Windsurf takes the same entry in `~/.codeium/windsurf/mcp_config.json`, and
so does any other client that starts a command.

### Cursor

In `~/.cursor/mcp.json`, or `.cursor/mcp.json` in a project:

```json
{
  "mcpServers": {
    "netweft": {
      "url": "https://api.netweft.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:NETWEFT_API_KEY}"
      }
    }
  }
}
```

### VS Code

In `.vscode/mcp.json`. VS Code asks for the key once and keeps it out of the
file:

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "netweft-key",
      "description": "netweft API key",
      "password": true
    }
  ],
  "servers": {
    "netweft": {
      "type": "http",
      "url": "https://api.netweft.com/mcp",
      "headers": {
        "Authorization": "Bearer ${input:netweft-key}"
      }
    }
  }
}
```

### Codex CLI

In `~/.codex/config.toml`:

```toml
[mcp_servers.netweft]
url = "https://api.netweft.com/mcp"
bearer_token_env_var = "NETWEFT_API_KEY"
```

### Gemini CLI

In `~/.gemini/settings.json`, through the npm bridge:

```json
{
  "mcpServers": {
    "netweft": {
      "command": "npx",
      "args": ["-y", "netweft-mcp"],
      "env": {
        "NETWEFT_API_KEY": "$NETWEFT_API_KEY"
      }
    }
  }
}
```

### Self-hosted

Point a client at your own API's URL followed by `/mcp`. For the npm bridge,
add `NETWEFT_API_URL` to its `env` with the API's URL; the bridge adds `/mcp`
itself.

## How the server answers

The server answers `server/discover`, `initialize`, `ping`, `tools/list` and
`tools/call`, and keeps no session. A client on `2026-07-28` sends the
version with every request and needs no handshake; an older client opens with
`initialize` and is answered in its own version. Both are told how the tools
fit together before the first call: start with `list_projects`.

Each tool has a title and is marked read-only, so a client that asks before
running a tool that writes can skip asking. A tool's answer comes back as
text, and as structured content when it is a single object.

The server answers with JSON, or with a single event when the client accepts
`text/event-stream`. A `GET` request answers `405`, because the server never
sends a message unprompted. A request that names a version the server does
not speak, or whose headers disagree with its body, answers `400`.

## Tools

`tools/list` returns only the tools the key's scopes allow.

| Scope | Tools |
| --- | --- |
| Projects | `whoami`, `list_projects`, `get_project`, `get_project_overview` |
| Keywords | `list_saved_keywords`, `list_keyword_tags` |
| Rank tracking | `list_rank_trackers`, `get_rank_tracker`, `list_tracked_keywords`, `get_latest_rank_results`, `get_rank_position_matrix`, `get_rank_trend`, `get_keyword_rank_history`, `estimate_rank_check_cost` |
| Site audit | `list_audits`, `get_audit`, `list_audit_issues`, `list_audit_pages` |
| Context | `get_project_context`, `list_competitors`, `list_key_pages`, `list_research_log`, `list_backlink_snapshots` |
| Billing | `get_credit_balance`, `get_subscription` |

Start an agent with `list_projects` to get project ids; most other tools take
one. `estimate_rank_check_cost` reports what a rank check would cost without
running it.

## Limits

One key can make 120 requests a minute. A key that is revoked
or past its expiry is refused at once.

## Example prompts

- "List my netweft projects, then summarise the critical issues from the
  latest audit of the first one."
- "Which tracked keywords fell out of the top 10 in the last check?"
- "Read the project context and list the competitors with their notes."
