MCP ServerInstall

Install

Connect any MCP client — Claude, Cursor, VS Code, OpenAI Codex, Gemini, Mistral — to the Certivant MCP server using your existing Certivant API key as a bearer token.

The Certivant MCP server speaks Streamable HTTP on a single endpoint, POST /mcp, and authenticates with a Certivant API key sent as a bearer token. There is no separate MCP credential to provision.

Before you start

Get an API key. Mint one in the dashboard at KYC → Developer (Owner or Admin only). It starts with kyk_ and is shown once — see Authentication.

Give it the right scopes. kyc:read is enough for triage, explanation, and reporting. Add kyc:write to send forms, start verifications, remind, renew, and submit KYB details. kyc:submit for releasing a request to processing. The MCP server forwards your key verbatim — a tool you lack the scope for returns the REST API's own 403.

Know your server URL. If Certivant is running the MCP server for you, use the host you were given. If you run it yourself, it listens on MCP_PORT (default 3007) and talks to the app at CERTIVANT_API_BASE_URL (default http://localhost:3005).

Treat the API key in these config files exactly like a password. Anyone holding it can act on your organization with its scopes — including sending real email to your customers.

Run the server

If you are self-hosting alongside the rest of the platform:

# from the repo root
MCP_PORT=3007 \
CERTIVANT_API_BASE_URL=https://app.certivant.com \
pnpm --filter @repo/mcp start

Confirm it is up — this endpoint is unauthenticated on purpose and reports only that the process is listening, never that the REST API is healthy:

curl http://localhost:3007/health
# → {"status":"ok","service":"certivant","transport":"streamable-http",…}

Works with any MCP client

The Certivant MCP server follows the open Model Context Protocol, so it is not tied to Claude or any single vendor. Any assistant, editor, CLI, or platform that speaks MCP over Streamable HTTP can use it — Claude Desktop and Claude Code, Cursor, VS Code, OpenAI Codex, Google Gemini, Mistral, and new clients arriving all the time.

Whichever one you use, the shape is the same: point the client at POST https://your-mcp-host/mcp and send your Certivant API key as Authorization: Bearer kyk_…. The rest is that client's own config format. The common ones are below — if yours is not listed, use the same URL and header in its MCP settings and it will work.

Configure an MCP-native host

These hosts read a config file (or a settings UI) and connect to the server for you. Paste the endpoint and your key, and the tools appear in the assistant.

Add it from the CLI:

claude mcp add --transport http certivant https://your-mcp-host/mcp \
  --header "Authorization: Bearer kyk_live_…"

Then check it connected:

claude mcp list

Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json in the project:

{
  "mcpServers": {
    "certivant": {
      "url": "https://your-mcp-host/mcp",
      "headers": {
        "Authorization": "Bearer kyk_live_…"
      }
    }
  }
}

Create .mcp.json in the workspace (or add to your user mcp.json). Prompt for the key rather than committing it:

{
  "inputs": [
    {
      "id": "certivant-key",
      "type": "promptString",
      "description": "Certivant API key (kyk_…)",
      "password": true
    }
  ],
  "servers": {
    "certivant": {
      "type": "http",
      "url": "https://your-mcp-host/mcp",
      "headers": {
        "Authorization": "Bearer ${input:certivant-key}"
      }
    }
  }
}

Claude Desktop's claude_desktop_config.json launches local servers, so a remote HTTP endpoint is bridged with mcp-remote:

{
  "mcpServers": {
    "certivant": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://your-mcp-host/mcp",
        "--header",
        "Authorization: Bearer kyk_live_…"
      ]
    }
  }
}

Restart Claude Desktop after editing the file.

Codex reads ~/.codex/config.toml (or a project .codex/config.toml in a trusted folder). Add a Streamable HTTP server and source the key from an environment variable so it is not stored in plain text:

[mcp_servers.certivant]
url = "https://your-mcp-host/mcp"
bearer_token_env_var = "CERTIVANT_API_KEY"

Or add it from the CLI:

export CERTIVANT_API_KEY=kyk_live_…
codex mcp add certivant \
  --url https://your-mcp-host/mcp \
  --bearer-token-env-var CERTIVANT_API_KEY

Codex sends the value as Authorization: Bearer <token>. For a header other than Authorization, use http_headers instead of bearer_token_env_var.

Add the server to ~/.gemini/settings.json (or a project .gemini/settings.json). The httpUrl key selects the Streamable HTTP transport:

{
  "mcpServers": {
    "certivant": {
      "httpUrl": "https://your-mcp-host/mcp",
      "headers": {
        "Authorization": "Bearer kyk_live_…"
      }
    }
  }
}

Build your own agent (APIs & frameworks)

The section above covers the ready-made clients you just point at the server — Claude, Cursor, VS Code, OpenAI Codex, Gemini CLI. This section is for building your own agent in code. Every model-provider API that supports remote MCP works — OpenAI's Responses API, Anthropic's Messages API, Google Gemini, Mistral — as do the model-agnostic agent frameworks, the Vercel AI SDK and LangChain, which expose the Certivant tools to whatever model you drive. All of them speak the same Streamable HTTP transport, so the same tools are available everywhere.

Who makes the connection matters.

  • Provider-hosted connectors — OpenAI's Responses API, Anthropic's Messages API, Gemini, and Mistral's connector call your MCP server from their cloud. So the endpoint must be internet-reachable (a http://localhost:3007 dev server will not work — use your deployed HTTPS host), and your API key travels to that provider.
  • Framework clients — the Vercel AI SDK and LangChain connect from your own code, so the key stays in your process and a local endpoint is fine.

Either way, scope the key to the minimum the workflow needs, and prefer a kyc:read-only key for autonomous or unattended runs — a kyc:write key lets a model send real email to your customers with no human in the loop unless you gate it.

The Responses API takes a remote MCP server directly in tools. It fetches the tool list from the server and lets the model call it.

from openai import OpenAI

client = OpenAI()

resp = client.responses.create(
    model="gpt-4.1",
    tools=[
        {
            "type": "mcp",
            "server_label": "certivant",
            "server_url": "https://your-mcp-host/mcp",
            "headers": {"Authorization": "Bearer kyk_live_…"},
            # Gate write tools rather than skipping every prompt — see below.
            "require_approval": "always",
        }
    ],
    input="What's in my verification queue today?",
)

print(resp.output_text)

require_approval: "never" skips the human confirmation on every tool, including the ones that email customers, start verifications, or send reminders. For unattended use, either keep "always", pass an object that only auto-approves the read tools, or use a kyc:read-only key so no write tool exists to call.

The same tools entry works from the Node SDK and from a raw POST https://api.openai.com/v1/responses call.

Claude's own Messages API attaches a remote MCP server directly — a useful reminder that Certivant is a standard server, not a Claude-specific one.

import anthropic

client = anthropic.Anthropic()

resp = client.beta.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "What's in my verification queue today?"}],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://your-mcp-host/mcp",
            "name": "certivant",
            "authorization_token": "kyk_live_…",  # sent as Authorization: Bearer
        }
    ],
    betas=["mcp-client-2025-04-04"],
)

Anthropic's MCP connector is beta and actively changing — the beta header version, and whether the server is passed in mcp_servers or inside the tools array, have both moved. Treat the snippet as illustrative and follow the current MCP connector docs for the exact shape.

Google's SDK connects through an MCP client session. Open a Streamable HTTP session against the server and hand it to generate_content as a tool.

import asyncio
from google import genai
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

client = genai.Client()

async def main():
    async with streamablehttp_client(
        "https://your-mcp-host/mcp",
        headers={"Authorization": "Bearer kyk_live_…"},
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            resp = await client.aio.models.generate_content(
                model="gemini-2.0-flash",
                contents="What's in my verification queue today?",
                config=genai.types.GenerateContentConfig(tools=[session]),
            )
            print(resp.text)

asyncio.run(main())

Gemini's MCP support is experimental and, at the time of writing, calls tools only — the server's resources and prompts are ignored. The tools are the load-bearing part, so this is rarely a problem in practice.

Mistral connects through a connector you add in Le Chat or in La Plateforme, rather than in code. Mistral requires the same Streamable HTTP transport and bearer auth the server already uses.

Open Connectors in Le Chat (or the Studio / Agents settings).
Add an MCP connector and paste your server URL, https://your-mcp-host/mcp.

Choose HTTP Bearer token as the auth method and paste your kyk_… key. Mistral also supports OAuth 2.1 for servers that offer it — see the note at the bottom of this page.

Save. Mistral runs the MCP initialize handshake and lists the tools.

Mistral's connector requires HTTPS with a valid TLS certificate and a server that returns 200 and answers the initialize call. The deployed Certivant host satisfies this; a plain-HTTP or self-signed dev server does not.

The AI SDK connects to the server and exposes its tools to any model you drive with generateText / streamText — one integration, every model.

import { experimental_createMCPClient as createMCPClient } from "ai";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const mcp = await createMCPClient({
  transport: new StreamableHTTPClientTransport(
    new URL("https://your-mcp-host/mcp"),
    { requestInit: { headers: { Authorization: "Bearer kyk_live_…" } } },
  ),
});

const tools = await mcp.tools();
// hand `tools` to generateText({ model, tools, prompt }) with any provider's model

createMCPClient is still flagged experimental_ in the AI SDK.

langchain-mcp-adapters turns the server's tools into LangChain tools for any LangChain or LangGraph agent, on any model.

from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient(
    {
        "certivant": {
            "transport": "streamable_http",
            "url": "https://your-mcp-host/mcp",
            "headers": {"Authorization": "Bearer kyk_live_…"},
        }
    }
)

tools = await client.get_tools()
# give `tools` to any LangGraph / LangChain agent

Verify the connection

Ask the assistant "what's in my verification queue today?". It should call get_todays_queue and come back with counts. If instead you see an authentication error, the server tells you which of the three failure modes you hit:

ResponseCause
Missing Authorization header…The host is not sending the header at all — check spelling and quoting in the config.
Malformed Authorization header…The value is not of the form Bearer <token>.
Bearer token does not look like a Certivant API key…The token is missing the kyk_ prefix.
A 401/403 from a tool callThe key itself is invalid, revoked, or lacks the scope. The MCP server does not validate keys — that verdict came from the REST API.

All four arrive as JSON-RPC errors with a WWW-Authenticate header.

About OAuth

An OAuth 2.1 + Dynamic Client Registration flow is implemented so directory-listed connectors can install Certivant without pasting a key: the server answers an unauthenticated request with a WWW-Authenticate pointer to its protected-resource metadata, and the sign-in, organization choice and consent happen in Certivant. The tokens it issues behave like API keys. The guides above use the bearer API key, which works in every host.