2026-03-13
By Orbiq Team

How to Build an MCP Server for Compliance Automation

Step-by-step tutorial for building a Model Context Protocol (MCP) server that wraps the Orbiq API — let AI agents access trust center data natively

Developers
Agentic AI
MCP Server
Model Context Protocol
Compliance Automation
API
AI Agents

How to Build an MCP Server for Compliance Automation

A Model Context Protocol (MCP) server is a standardized interface that lets AI agents — such as Claude, ChatGPT, or custom LLM applications — access external tools and data sources through a consistent protocol, and building one that wraps a compliance API like Orbiq's means your AI agents can query certifications, retrieve compliance documents, and answer security questions using live trust center data.

MCP is quickly becoming the standard way AI agents interact with external systems. By exposing your compliance operations as MCP tools, you enable any MCP-compatible AI assistant to check your SOC 2 status, retrieve your security policies, or answer vendor security questionnaires — all grounded in your actual compliance data rather than the model's general training knowledge.


What Is MCP (Model Context Protocol)?

The Model Context Protocol is an open standard created by Anthropic that defines how AI applications communicate with external tools and data sources. Think of it as a USB-C port for AI agents: a single, standardized interface that lets any compliant client connect to any compliant server.

An MCP server exposes tools (functions the AI can call) and resources (data the AI can read). An MCP client — like Claude Desktop, Cursor, Windsurf, or any custom agent — discovers available tools, decides when to use them, and calls them through the protocol.

Why MCP Matters for Compliance

Compliance data lives in specialized systems — trust centers, GRC platforms, document management tools. Without MCP, building an AI agent that can access this data requires custom integration code for each AI platform. With MCP, you write one server and every MCP-compatible client can use it.

Integration ApproachDevelopment EffortClient CompatibilityMaintenance
Custom API integration per AI platformHigh — separate code for eachOne client onlyMaintain N integrations
LLM function calling (raw)Medium — schema per modelModel-specificUpdate per model version
MCP serverMedium — one implementationAny MCP clientSingle codebase

For compliance teams, this means an AI assistant in Claude Desktop can answer "Are we SOC 2 compliant?" by checking your actual trust center data through the MCP server — not by guessing from its training data.


What You Will Build

In this tutorial, you will build an MCP server in TypeScript that wraps Orbiq's REST API and exposes five compliance tools:

  1. get_certifications — Lists all compliance certifications with their status and expiry dates
  2. get_documents — Retrieves compliance documents available in the trust center
  3. answer_question — Calls the Orbiq Ask API to answer compliance questions from the knowledge base
  4. check_nda_status — Checks NDA acceptance status for a specific visitor
  5. get_access_requests — Lists pending access requests for compliance documents

When complete, an AI agent connected to your MCP server can answer questions like "What certifications does our company have?" or "Has this vendor signed our NDA?" using live data from your Orbiq trust center.


Prerequisites

Before you begin, you will need:

  • Node.js 18+ installed
  • An Orbiq account with an API key (sign up at orbiqhq.com)
  • Basic familiarity with TypeScript and REST APIs
  • An MCP client for testing (Claude Desktop, Cursor, or the MCP Inspector)

Set up your environment:

mkdir orbiq-mcp-server && cd orbiq-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
npx tsc --init

Set your API key:

export ORBIQ_API_KEY="your_api_key_here"

Step 1: Set Up the MCP Server Scaffold

Create the main server file at src/index.ts:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const ORBIQ_API_KEY = process.env.ORBIQ_API_KEY;
const BASE_URL = "https://app.orbiqhq.com/api/v1";

if (!ORBIQ_API_KEY) {
  throw new Error("ORBIQ_API_KEY environment variable is required");
}

const server = new McpServer({
  name: "orbiq-compliance",
  version: "1.0.0",
});

async function orbiqFetch(endpoint: string, options: RequestInit = {}) {
  const response = await fetch(`${BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${ORBIQ_API_KEY}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  if (!response.ok) {
    throw new Error(`Orbiq API error: ${response.status} ${response.statusText}`);
  }

  return response.json();
}

// Tools will be registered here (Steps 2-6)

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Orbiq MCP server running on stdio");
}

main().catch(console.error);

This sets up the MCP server with stdio transport (the standard for local MCP servers) and a helper function for authenticated Orbiq API calls.


Step 2: Expose Certifications as an MCP Tool

Add the get_certifications tool that lets AI agents check your company's compliance certifications:

server.tool(
  "get_certifications",
  "List all compliance certifications with their status and expiry dates",
  {},
  async () => {
    const data = await orbiqFetch("/certifications");
    const certifications = data.data ?? [];

    const summary = certifications.map((cert: any) => ({
      title: cert.title,
      state: cert.state,
      issue_date: cert.issue_date,
      expiry_date: cert.expiry_date,
      featured: cert.featured,
    }));

    return {
      content: [
        {
          type: "text" as const,
          text: JSON.stringify(summary, null, 2),
        },
      ],
    };
  }
);

When an AI agent calls this tool, it gets a structured list of all certifications — SOC 2, ISO 27001, GDPR, etc. — with their current validity status.


Step 3: Expose Documents as an MCP Tool

Add the get_documents tool so agents can discover available compliance documents:

server.tool(
  "get_documents",
  "List compliance documents available in the trust center",
  {
    access_level: z
      .enum(["public", "restricted", "requires_nda", "internal"])
      .optional()
      .describe("Filter by access level"),
  },
  async ({ access_level }) => {
    const data = await orbiqFetch("/documents");
    let documents = data.data ?? [];

    if (access_level) {
      documents = documents.filter(
        (doc: any) => doc.access_level === access_level
      );
    }

    const summary = documents.map((doc: any) => ({
      title: doc.title,
      description: doc.description,
      access_level: doc.access_level,
      expiry_date: doc.expiry_date,
      created_at: doc.created_at,
    }));

    return {
      content: [
        {
          type: "text" as const,
          text: JSON.stringify(summary, null, 2),
        },
      ],
    };
  }
);

Step 4: Expose the Ask API as an MCP Tool

This is the most powerful tool — it lets AI agents answer compliance questions using your knowledge base:

server.tool(
  "answer_question",
  "Answer a compliance or security question using the Orbiq knowledge base",
  {
    question: z.string().describe("The compliance question to answer"),
  },
  async ({ question }) => {
    const data = await orbiqFetch("/ask", {
      method: "POST",
      body: JSON.stringify({
        question,
        question_type: "text",
      }),
    });

    // Handle async responses (202 Accepted)
    if (data.status === "in_progress" && data.id) {
      let attempts = 0;
      let result = data;

      while (result.status === "in_progress" && attempts < 15) {
        await new Promise((resolve) => setTimeout(resolve, 2000));
        result = await orbiqFetch(`/ask/${data.id}`);
        attempts++;
      }

      if (result.status === "completed") {
        const answer = extractAnswer(result);
        return {
          content: [{ type: "text" as const, text: answer || "No answer found in knowledge base." }],
        };
      }

      return {
        content: [
          {
            type: "text" as const,
            text: `Ask API returned status: ${result.status}. The question may need human review.`,
          },
        ],
      };
    }

    // Handle sync responses (200 OK)
    const answer = extractAnswer(data);
    return {
      content: [{ type: "text" as const, text: answer || "No answer found in knowledge base." }],
    };
  }
);

function extractAnswer(data: any): string {
  for (const item of data.output ?? []) {
    for (const content of item.content ?? []) {
      if (content.text) return content.text.trim();
    }
  }
  return "";
}

The Ask API uses a hybrid sync/async model. If the answer is ready immediately, you get a 200 OK with the completed response. Otherwise, you get a 202 Accepted and poll GET /ask/{id} until the response reaches a terminal state (completed, failed, or incomplete).


Step 5: Add NDA and Access Request Tools

Add tools for checking NDA status and listing access requests:

server.tool(
  "check_nda_status",
  "Check NDA acceptance status — optionally filter by email",
  {
    email: z.string().optional().describe("Filter NDA acceptances by email address"),
  },
  async ({ email }) => {
    const data = await orbiqFetch("/nda-acceptances");
    let acceptances = data.data ?? [];

    if (email) {
      acceptances = acceptances.filter(
        (nda: any) => nda.email?.toLowerCase() === email.toLowerCase()
      );
    }

    const summary = acceptances.map((nda: any) => ({
      email: nda.email,
      status: nda.status,
      signed_at: nda.signed_at,
      nda_template: nda.nda_template_title,
    }));

    return {
      content: [
        {
          type: "text" as const,
          text: summary.length > 0
            ? JSON.stringify(summary, null, 2)
            : email
              ? `No NDA acceptance found for ${email}.`
              : "No NDA acceptances found.",
        },
      ],
    };
  }
);

server.tool(
  "get_access_requests",
  "List pending access requests for compliance documents",
  {},
  async () => {
    const data = await orbiqFetch("/access-requests");
    const requests = (data.data ?? []).filter(
      (req: any) => req.review_status === "to_review"
    );

    const summary = requests.map((req: any) => ({
      id: req.id,
      email: req.email,
      company: req.company,
      document_title: req.document_title,
      review_status: req.review_status,
      created_at: req.created_at,
    }));

    return {
      content: [
        {
          type: "text" as const,
          text: summary.length > 0
            ? JSON.stringify(summary, null, 2)
            : "No pending access requests.",
        },
      ],
    };
  }
);

Step 6: Test with an MCP Client

Option A: MCP Inspector

The fastest way to test is with the MCP Inspector:

npx @modelcontextprotocol/inspector npx tsx src/index.ts

This opens a browser-based interface where you can call each tool and see the responses.

Option B: Claude Desktop

Add the server to your Claude Desktop configuration at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "orbiq-compliance": {
      "command": "npx",
      "args": ["tsx", "/path/to/orbiq-mcp-server/src/index.ts"],
      "env": {
        "ORBIQ_API_KEY": "your_api_key_here"
      }
    }
  }
}

Restart Claude Desktop. You can now ask questions like:

  • "What compliance certifications do we have?"
  • "Are there any pending access requests?"
  • "Where is customer data stored?" (answered from your knowledge base)
  • "Has vendor@bigcorp.com signed our NDA?"

Claude will call the appropriate MCP tools and answer using your live trust center data.

Option C: Cursor / Windsurf

Both Cursor and Windsurf support MCP servers. Add the same configuration to your editor's MCP settings. This lets developers query compliance status directly from their IDE while writing code.


Use Cases

AI Assistant That Answers "Are You SOC 2 Compliant?"

A sales engineer adds your MCP server to their Claude Desktop. When a prospect asks "Are you SOC 2 compliant?", the assistant calls get_certifications, finds the SOC 2 Type II entry, checks its expiry date, and responds with a specific, accurate answer — including the audit period and validity status.

Automated Vendor Security Reviews

An AI agent working through an MCP client can answer incoming vendor security questionnaires by calling answer_question for each question. The agent produces a draft response document with answers grounded in your knowledge base, flagging any questions it could not answer for human review.

Developer Compliance Checks

A developer building a new feature can ask their IDE's AI assistant "What are our data residency requirements?" and get an answer pulled directly from the company's compliance knowledge base — no Slack messages to the security team required.


Deploying Your MCP Server

For team-wide deployment, package the server as an npm package or Docker container:

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist/ ./dist/
CMD ["node", "dist/index.js"]

For production use, consider:

  • Authentication: Use a dedicated API key with read-only permissions for the MCP server
  • Rate limiting: Orbiq's API has rate limits — add appropriate backoff logic
  • Logging: Log all tool invocations for audit trail purposes
  • Error handling: Return clear error messages that help the AI agent understand what went wrong

How Orbiq Helps

Orbiq's REST API is designed to be agent-friendly — structured endpoints, consistent response schemas, and predictable authentication make it straightforward to wrap as an MCP server. The Ask API provides retrieval-augmented generation grounded in your actual compliance knowledge base, so AI agents get accurate answers rather than hallucinations.

By combining Orbiq's API with MCP, you create a bridge between AI assistants and your compliance operations. Sales teams can answer prospect questions instantly, compliance teams can automate questionnaire responses, and developers can check compliance requirements without leaving their editor.

Explore the full API at the Orbiq Developer Hub or read the API reference at docs.orbiqhq.com. For the foundational trust center setup that this MCP server builds on, see How to Build a Trust Center with the Orbiq API. For the broader agentic compliance vision, see Agentic AI for Compliance.


FAQ

What is an MCP server?

An MCP (Model Context Protocol) server is a program that exposes tools and data to AI agents through a standardized protocol. It acts as a bridge between AI applications — like Claude Desktop, Cursor, or custom LLM agents — and external systems. Any MCP-compatible client can discover and use the tools your server exposes without custom integration code.

Why would I build an MCP server for compliance?

Compliance data lives in specialized systems that AI agents cannot access by default. An MCP server lets AI agents query your certifications, retrieve compliance documents, and answer security questions using your actual trust center data — not the model's general training knowledge. This means more accurate answers, fewer hallucinations, and AI assistants that can genuinely help with compliance workflows.

What AI clients support MCP?

As of 2026, MCP is supported by Claude Desktop, Cursor, Windsurf, Cline, and a growing number of custom AI applications built with the MCP SDK. The protocol is open-source and maintained by Anthropic, with active adoption across the AI developer tooling ecosystem.

Is it safe to connect compliance data to AI agents via MCP?

Yes, when implemented correctly. Use read-only API keys for the MCP server so agents cannot modify compliance data. Log all tool invocations for audit purposes. The Orbiq Ask API grounds answers in your knowledge base content, preventing hallucination. For sensitive operations like approving access requests, keep those behind a human-in-the-loop workflow rather than exposing them as autonomous MCP tools.

How is an MCP server different from a regular API integration?

A regular API integration is specific to one AI platform — you write custom code for each client. An MCP server implements a standard protocol that any MCP-compatible client can use. Write the server once, and Claude Desktop, Cursor, custom agents, and future MCP clients all work with it automatically. It is the difference between writing a USB driver for every device versus using a standard USB port.

How to Build an MCP Server for Compliance Automation | Orbiq Developers