Back to all guides
MCP

How to use the MCP server?

Requirements, access, endpoints to use the MCP.

What is the IndyKite MCP Server?

The IndyKite MCP (Model Context Protocol) server enables AI agents and LLM applications to interact with IndyKite's authorization and data services. It provides a standardized interface for:

  • AuthZEN authorization: Make access control decisions (evaluate, search resources, search actions).
  • ContX IQ (CIQ): Execute knowledge queries to read and write graph data.
  • Resource discovery: List available knowledge queries with agent-friendly descriptions.

The server implements the Model Context Protocol specification, making it compatible with MCP-enabled AI tools and agents.

What is the MCP URL?

The MCP server is available in two regions:

Full endpoint URL:

<MCP_REGIONAL_URL>/mcp/v1/<project_gid>

Replace <project_gid> with your IndyKite project GID.

What do I need before using the MCP server?

Prerequisites

  • IndyKite environment: Project, Application, Application Agent, and Application Agent credentials.
  • Token Introspect configuration: Required to validate user access tokens.
  • MCP Server configuration: Binds the runtime MCP endpoint to an AppAgent and a Token Introspect, and declares the OAuth scopes the server advertises. The MCP server will not accept requests for a project until this configuration exists.
  • Project GID: Your IndyKite project identifier.
  • Data and policies: Captured data, KBAC policies, and/or CIQ policies and Knowledge Queries.

How do I create an MCP server configuration?

Before the MCP runtime endpoint will accept requests for your project, you must create an MCP Server configuration. This configuration tells IndyKite which AppAgent and Token Introspect the MCP server should use, and which OAuth scopes it advertises.

Required fields

Field Type Description
namestringURL-friendly identifier, unique within the project. Immutable.
project_idstring (GID)Project that owns this MCP server configuration.
app_agent_idstring (GID)AppAgent the MCP server uses to call IndyKite APIs at runtime. Needs Authorization API and ContX IQ API permissions.
token_introspect_idstring (GID)Token Introspect configuration used to validate inbound Bearer tokens.
enabledbooleanWhether the MCP server accepts requests.
scopes_supportedstring[]OAuth scopes advertised in .well-known/oauth-protected-resource. Must contain at least one entry.

Optional fields

  • display_name (string, 2-254 chars): Human-readable name.
  • description (string, 2-65000 chars): Free-text description.

Example: create an MCP server configuration

curl -X POST <API_URL>/configs/v1/mcp-servers
-H "Content-Type: application/json"
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
-d '{
      "name": "mcp-server-name",
      "display_name": "MCP Server name",
      "description": "MCP Server configuration description",
      "project_id": "gid-of-project",
      "app_agent_id": "gid-of-app-agent",
      "token_introspect_id": "gid-of-token-introspect",
      "enabled": true,
      "scopes_supported": ["name", "email"]
    }'

Response (201 Created): Returns the new configuration's id (GID), create_time, created_by, and update_time.

Reference: POST /mcp-servers

How do I authenticate with the MCP server?

The MCP server authenticates each request with a single Bearer token - the end-user's OAuth 2.0 access token. The AppAgent the server uses to call IndyKite APIs at runtime is resolved server-side from your MCP Server configuration (app_agent_id). Clients send only the Bearer token.

Bearer Token (Authorization)

This identifies the user (subject) making the request.

  • Header: Authorization: Bearer <user-access-token>
  • Source: OAuth 2.0 access token from your identity provider
  • Validation: Token is introspected using your Token Introspect configuration
  • Purpose: Used as the subject in authorization decisions

Configure token introspection: POST /token-introspects

What happens without a Bearer token?

If you call the MCP server without a Bearer token, it returns:

  • 401 Unauthorized status
  • .well-known/oauth-protected-resource metadata (per RFC9728)

Note: Contact IndyKite to have your identity providers and scopes added to the .well-known/oauth-protected-resource file for your project.

Why does a multi-audience Bearer token return 401?

A multi-audience Bearer token - one whose aud claim lists more than one audience - works through the MCP server only if exactly one Token Introspect configuration in the relevant app space matches it. The MCP Server configuration binds a single token_introspect_id, but that binding does not protect you from ambiguity created by other Token Introspect configurations that share the same issuer in that app space.

Two independent audience checks

An inbound token passes through two checks that use different selection logic:

  • Pre-check (membership): the audience bound to the MCP server must be present in the token's aud claim.
  • Introspection (lookup): the token's audiences are matched against the Token Introspect configurations in the app space.
    • 0 matchesNotFound
    • 2 or more matchesFailedPrecondition: "multiple matches for issuer-audiences"

Why ambiguity produces a 401

Consider a token with aud = [A, B], an MCP server bound to the Token Introspect for audience A, and a second (even unlinked) Token Introspect for audience B that shares the same issuer in that app space:

  • Pre-check: A ∈ [A, B] → passes.
  • Introspection: matching ANY('{A,B}') hits both A and B → 2 rows → FailedPrecondition, which the MCP server maps to a generic 401 invalid_token.

Configuration facts to keep in mind

  • A Token Introspect configuration holds one audience; "two audiences" means two separate configuration rows. The combination (app_space_id, issuer, audience) is unique.
  • The MCP Server configuration binds exactly one token_introspect_id.

To avoid this: for a given issuer in an app space, make sure a multi-audience token resolves to a single Token Introspect configuration - do not keep multiple Token Introspect configs whose audiences overlap with the same token's aud claim.

How does the MCP session work?

The MCP server uses JSON-RPC over HTTP POST:

  1. Initialize: Send an initialize request to start a session.
  2. Receive Session ID: The server returns an Mcp-Session-Id header.
  3. Include Session ID: All subsequent requests must include the Mcp-Session-Id header.

The server is built using the official MCP Go SDK, so you can also use Go SDK clients to interact with it.

What is the MCP process flow?

How do I make MCP requests?

Step 1: Initialize the MCP session

Start a new MCP session and receive a session ID.

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2025-11-25",
        "capabilities": {},
        "clientInfo": {"name": "curl", "version": "1.0"}
      }
    }'

Response: Returns Mcp-Session-Id header. Save this for subsequent requests.

What happens without a Bearer token?

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2025-11-25",
        "capabilities": {},
        "clientInfo": {"name": "curl", "version": "1.0"}
      }
    }'   

Response: Returns 401 Unauthorized and .well-known/oauth-protected-resource metadata.

Step 2: Confirm initialization

Verify the session is initialized.

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "notifications/initialized",
      "params": {
        "protocolVersion": "2025-11-25",
        "capabilities": {},
        "clientInfo": {"name": "curl", "version": "1.0"}
      }
    }'

How do I discover available resources and tools?

List MCP resources

Discover what resources are available in the MCP server.

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 2,
      "method": "resources/list",
      "params": {}
    }'  

List MCP tools

Discover what tools are available for the AI agent to call.

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 3,
      "method": "tools/list",
      "params": {}
    }'

List Knowledge Queries

Get a list of available CIQ Knowledge Queries with agent-friendly descriptions.

curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 4,
      "method": "resources/read",
      "params": {
        "uri": "indykite://knowledge-queries/"
      }
    }'

Response: Returns list of Knowledge Query IDs and descriptions, formatted for AI agents to understand how to call the ciq_execute tool.

What tools are available?

AuthZEN Tools

These tools make authorization decisions based on KBAC policies.

Tool Description
authzen_evaluate Check if a subject can perform an action on a resource
authzen_evaluations Batch evaluate multiple authorization requests
authzen_search_resource Find all resources a subject can access with a given action
authzen_search_action Find all actions a subject can perform on a resource

CIQ Tools

Tool Description
ciq_execute Execute a Knowledge Query to read or write graph data

How do I use the AuthZEN tools?

authzen_evaluate: Single authorization check

Check if a subject can perform a specific action on a resource.

# random values to adapt in arguments
# subject_id is Bearer token sub
curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 5,
      "method": "tools/call",
      "params": {
        "name": "authzen_evaluate",
        "arguments": {
          "subject_type": "Person",
          "subject_id": "alice",
          "resource_type": "Car",
          "resource_id": "cadillacv16",
          "action_name": "CAN_DRIVE"
        }
      }
    }'

authzen_evaluations: Batch authorization checks

Evaluate multiple authorization requests in a single call.

# random values to adapt in arguments
# subject_id is Bearer token sub
curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 6,
      "method": "tools/call",
      "params": {
        "name": "authzen_evaluations",
        "arguments": {
          "subject_type": "user",
          "subject_id": "user-123",
          "evaluations": [
            {"action": {"name": "read"}, "resource": {"type": "doc", "id": "doc1"}},
            {"action": {"name": "write"}, "resource": {"type": "doc", "id": "doc2"}}
          ]
        }
      }
    }' 

authzen_search_resource: Find accessible resources

Find all resources of a given type that a subject can access with a specific action.

# random values to adapt in arguments
# subject_id is Bearer token sub
curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 7,
      "method": "tools/call",
       "params": {
        "name": "authzen_search_resource",
        "arguments": {
          "subject_type": "User",
          "subject_id": "user-123",
          "action_name": "READ",
          "resource_type": "Document"
        }
      }
    }' 

authzen_search_action: Find permitted actions

Find all actions a subject can perform on a specific resource.

# random values to adapt in arguments
# subject_id is Bearer token sub
curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 8,
      "method": "tools/call",
      "params": {
        "name": "authzen_search_action",
        "arguments": {
          "subject_type": "User",
          "subject_id": "user-123",
          "resource_type": "Document",
          "resource_id": "doc-456"
        }
      }
    }' 

How do I use the CIQ tool?

ciq_execute: Run a Knowledge Query

Execute a CIQ Knowledge Query to read or write data in the Identity Knowledge Graph.

# random keys/values to adapt in input_params
curl -v -i -X POST <MCP_URL>/mcp/v1/<project_gid>
-H "Content-Type: application/json"
-H "Authorization: Bearer $BEARER_TOKEN"
-H "Mcp-Session-Id: $SESSION_ID"
-d '{
      "jsonrpc": "2.0",
      "id": 9,
      "method": "tools/call",
      "params": {
        "name": "ciq_execute",
        "arguments": {
          "id": ",
          "input_params": {"license": "AL98745", "app_external_id": "applicationParking"}
        }
      }
    }'

What arguments does ciq_execute need?

Argument Description
id The GID or name of the Knowledge Query to execute
input_params Key-value pairs for partial filter variables defined in the query

Tip: Use the resources/read method with URI indykite://knowledge-queries/ to get agent-friendly descriptions of available queries and their required parameters.

Next Steps