> Source: https://wexa.ai/docs/get-started/quickstart/mcp-server

# Quickstart — Wexa MCP server

The Wexa MCP server is the surface where the caller is a product someone else wrote — an editor,
a desktop assistant, anything that speaks the protocol. You configure the client once and every
Wexa tool becomes a tool that client can reach.

It is also the best surface to learn on, because you can watch a tool run, be refused, or wait on an
approval without writing a line of code. Everything you learn here is true of the other three.

## Before you start

You need a Wexa project and an administrator role on it, so that you can mint a credential.

## Step 1 — Find your endpoint

The gateway publishes its own connection details, and this endpoint needs no credential — which
makes it a useful first check that you have the right host.

```bash
curl -sS https://fabric.wexa.ai/v1/connection-info
```

```json
{
  "mcp": {
    "url_template": "https://fabric.wexa.ai/mcp/{projectId}",
    "auth": "OAuth 2.1 (PKCE) or Bearer API key (fab_sk_…)"
  },
  "api": { "base_url": "https://fabric.wexa.ai/v1" },
  "workspace_header": "X-Wexa-Workspace",
  "issuer": "https://fabric.wexa.ai",
  "tools": [
    "query-context", "create-ontology", "save-context", "docs", "search-code", "fetch-code",
    "run-agent", "knowledge-base-retrieve", "knowledge-base-add", "list-skills",
    "provision-connector", "list-models", "set-model", "create-process-flow",
    "update-process-flow", "get-process-flow", "get-execution", "run-process-flow"
  ]
}
```

Two things to take from this. The endpoint carries your project in the path, so a connection is to
one project and not to the platform at large. And `tools` is the list *this deployment* advertises —
all sixty-two tools, on every deployment, of which the example above shows only some. A tool whose
backing service the deployment has not configured is still listed, and a call to it fails with an
error saying it is not configured.

## Step 2 — Get a credential

An MCP client authenticates either through OAuth 2.1 with PKCE, if it supports that, or with an API
key as a bearer token. The key is the quicker path and the one this page uses.

`$FABRIC_USER_TOKEN` below is your own Wexa sign-in token, the session token the console holds
once you have signed in. The console mints keys from this same endpoint under
**Simple mode → Generate API key** if you would rather not handle it yourself.

```bash
curl -sS -X POST https://fabric.wexa.ai/v1/apikeys \
  -H "Authorization: Bearer $FABRIC_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"org_id":"org_...","dept_id":"dept_...","project_id":"proj_...","name":"quickstart"}'
```

```json
{
  "id": "key_...",
  "name": "quickstart",
  "note": "store this secret now; it is not retrievable again",
  "secret": "fab_sk_..."
}
```

The secret is returned once and stored only as a hash, so a key you lose is a key you replace.
Minting one requires an owner, organization-administrator or project-administrator role; any other
role is refused with `API key creation requires an admin role on this project`.

## Step 3 — Configure your client

Most MCP clients take a server name, a URL and a header block. The shape below is the one a desktop
assistant or an editor expects; consult your client for exactly where the file lives.

```json
{
  "mcpServers": {
    "fabric": {
      "url": "https://fabric.wexa.ai/mcp/proj_...",
      "headers": {
        "Authorization": "Bearer fab_sk_..."
      }
    }
  }
}
```

Restart the client and Wexa's tools appear in its tool list. At that point you are done, and you
can ask the assistant to query your project in plain language.

## Step 4 — Or do the handshake yourself

If you are building the client, or you want to see what the assistant is doing, the protocol is two
requests. The first one initializes a session. The `Accept` header decides how the reply is framed,
not whether you get one: offer both and the reply comes back as a server-sent event stream, offer
`application/json` alone and the same reply comes back as a plain JSON body. Neither is refused.

```bash
curl -sS -D - -X POST https://fabric.wexa.ai/mcp/proj_... \
  -H "Authorization: Bearer $WEXA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "quickstart", "version": "1" }
    }
  }'
```

```text
HTTP/1.1 200 OK
Content-Type: text/event-stream
Mcp-Protocol-Version: 2025-06-18
Mcp-Session-Id: sess_...

event: message
data: {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"tools":{"listChanged":false}},"protocolVersion":"2025-06-18","serverInfo":{"name":"wexa-fabric","version":"0.1.0"}}}
```

## Step 5 — List the tools, then call one

With the session id in hand, ask what this deployment has:

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/proj_... \
  -H "Authorization: Bearer $WEXA_API_KEY" \
  -H "Mcp-Session-Id: sess_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'
```

Then call one. The documentation tool is the best first call: it is registered in every deployment,
needs no data in your project, and reports your own scope and limits back to you.

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/proj_... \
  -H "Authorization: Bearer $WEXA_API_KEY" \
  -H "Mcp-Session-Id: sess_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": { "name": "docs", "arguments": { "topic": "governance" } }
  }'
```

```text
event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"text":"{\"lifecycle_id\":\"qlc_...\",\"result\":{\"mode\":\"auto\",\"quota\":{\"org_window_max\":600,\"project_window_max\":120},...}}","type":"text"}],"isError":false}}
```

That is a successful call. The tool's real answer is JSON inside the `text` of the first content
block — the protocol carries text, so the envelope every Wexa tool returns is serialized into it.
Unwrap it and you have the same `lifecycle_id` and `result` the REST API would have handed you.

## Step 6 — See a refusal

A credential that is wrong, or has been revoked, fails at the connection rather than at the tool,
and says which of the two it is:

```json
{ "error": "invalid_token", "error_description": "api key invalid or revoked" }
```

A tool that refuses its arguments answers inside the protocol instead, with the same error body the
REST API returns — so the two surfaces are not only at parity in what they allow, but in how they
explain a refusal.

## Where to go next

**Reference — All tools**
Every tool the Wexa MCP server can advertise, and whether your deployment has it.

**Before you start — Scope and server-bound arguments**
Why a connection is to one project, and what happens if a client sends another.

**Quickstart — Move into code**
The same tools, called from TypeScript, Python or plain HTTP.

**Concepts — Policy decisions and approvals**
What happens when a call is held until a person answers for it.
