Skip to main content

tigergraph-mcp

Model Context Protocol (MCP) server for TigerGraph — lets AI agents interact with TigerGraph through the MCP standard. All tools use pyTigerGraph's async APIs for optimal performance.

Table of Contents

Requirements

Recommended: TigerGraph 4.2+ to enable TigerVector and advanced hybrid retrieval features.

Installation

Install with pip:

pip install tigergraph-mcp

Or with conda (from the tigergraph channel):

conda install -c tigergraph tigergraph-mcp

This installs:

  • pyTigerGraph>=2.0.5 — the TigerGraph Python SDK
  • mcp>=1.0.0 — the MCP SDK
  • pydantic>=2.0.0 — for data validation
  • click — for the CLI entry point
  • python-dotenv>=1.0.0 — for loading .env files

To serve over HTTP (--transport streamable-http or sse), also install a web stack:

pip install uvicorn starlette

To enable the tigergraph__generate_gsql and tigergraph__generate_cypher tools (LLM-powered query generation), install the optional [llm] extras (pip only):

pip install "tigergraph-mcp[llm]"

Getting Started

TigerGraph-MCP supports multiple AI agent frameworks. Choose the one that fits your workflow:

LangGraph is ideal for building stateful, agent-based workflows with complex tool chaining. Setup guide and full chatbot example:

CrewAI

CrewAI provides a simpler starting point for basic agentic workflows with a web-based UI:

GitHub Copilot Chat (VS Code)

For quick tasks or straightforward tool invocations directly in your editor:

Usage

Running the MCP Server

stdio (default — single user, one IDE/agent)

tigergraph-mcp

The server talks MCP over its own stdin and stdout: it reads JSON-RPC messages from standard input and writes replies to standard output, then exits when standard input closes. Run it in a terminal and it simply waits for messages — there is no prompt and no human-facing console. You normally never start it this way; the MCP client (Claude Code, Cursor, GitHub Copilot Chat, a LangChain agent) spawns it as a subprocess and owns the pipes. Running it by hand is mainly useful for checking that it starts:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"manual","version":"1"}}}' \
  | tigergraph-mcp

Because the client owns the process, credentials must reach it as environment variables — from a .env file, or from the client's own env mapping. This is the right mode for any single-user IDE integration.

With a custom .env file:

tigergraph-mcp --env-file /path/to/.env

With verbose logging:

tigergraph-mcp -v    # INFO level
tigergraph-mcp -vv   # DEBUG level

Or programmatically:

from tigergraph_mcp import serve
import asyncio

asyncio.run(serve())

Streamable HTTP / SSE (multi-user, shared server)

tigergraph-mcp --transport streamable-http --host 0.0.0.0 --port 8000
# legacy SSE shape:
tigergraph-mcp --transport sse --host 0.0.0.0 --port 8000

Here the server binds the chosen port and serves MCP over HTTP, staying up until you stop it — a long-lived service you start once, not a process a client spawns. Many clients connect to it concurrently, each getting its own isolated TigerGraph connections, and it does not read standard input at all. Requires uvicorn and starlette.

HTTP Mode End-to-End walks through configuring, starting, and connecting to one.

Use with Claude Code

tigergraph-mcp ships as a Claude Code plugin, which replaces installing the package, writing a .env, and hand-writing an MCP client config. Claude Code prompts for the connection details and launches the server itself.

Requires uv on your PATH — the plugin runs the server with uvx, which fetches it from PyPI on demand. uv can also provide a suitable Python, so nothing else needs installing.

claude plugin marketplace add tigergraph/tigergraph-mcp
claude plugin install tigergraph@tigergraph

Claude Code then asks for the TigerGraph host (required), and optionally a username, password, default graph, API token, and a tool selection. The password and API token are masked and held in secure storage rather than a settings file. To change any of them later, open /plugin, select TigerGraph (Self-Managed MCP) on the Installed tab, and choose Configure options — no reinstall needed.

Supplying an API token makes it take precedence over the password.

The tool selection accepts the same selectors as --allowed-tools (Serving a Subset of the Tools); leaving it empty offers all of them.

In permission rules, a skill's allowed-tools, or a hook matcher, the plugin's server is named plugin:tigergraph:tigergraph. A pattern like mcp__tigergraph__.* does not match a plugin-provided server.

If you would rather not install uv, install the package yourself and point a plain MCP client config at the tigergraph-mcp command, as in stdio above.

Configuration

The MCP server reads connection configuration from environment variables. You can set these either directly or in a .env file.

Create a .env file in your project directory:

# .env — Username/Password authentication
TG_HOST=http://localhost
TG_GRAPHNAME=MyGraph  # Optional — can be omitted if the database has multiple graphs
TG_USERNAME=tigergraph
TG_PASSWORD=tigergraph
TG_RESTPP_PORT=9000
TG_GS_PORT=14240

Or use an API token instead of username/password:

# .env — API Token authentication
TG_HOST=http://localhost
TG_GRAPHNAME=MyGraph
TG_API_TOKEN=your_api_token_here

When TG_API_TOKEN (or TG_JWT_TOKEN) is set, the server uses token-based authentication (Authorization: Bearer <token>) and ignores username/password. You can obtain a token via pyTigerGraph's getToken() method or by directly calling TigerGraph's token generation endpoint.

When only username/password are provided and the TigerGraph instance requires a token for RESTPP endpoints, pyTigerGraph auto-mints one on the first 401 response and transparently retries the request — no manual token setup needed.

The server loads the .env file automatically. Environment variables take precedence over .env values.

Environment Variables

Variable Default Description
TG_HOST http://127.0.0.1 TigerGraph host
TG_GRAPHNAME (empty) Graph name (optional)
TG_USERNAME tigergraph Username
TG_PASSWORD tigergraph Password
TG_SECRET (empty) GSQL secret (optional)
TG_API_TOKEN (empty) API token (optional)
TG_JWT_TOKEN (empty) JWT token (optional)
TG_RESTPP_PORT 9000 REST++ port
TG_GS_PORT 14240 GSQL port
TG_SSL_PORT 443 SSL port
TG_TGCLOUD false Whether using TigerGraph Cloud
TG_CERT_PATH (empty) Path to certificate (optional)
TG_LOG_TOOL_CALLS false Log one line per tool call
TG_LOG_CALLER_IDENTITY none Caller identity in those lines: none, profile, or username

Multiple Connection Profiles

Define named profiles in your .env to work with multiple TigerGraph environments without changing any code.

Defining profiles

Each named profile uses a <PROFILE>_ prefix on the standard TG_* variables. Only variables that differ from the default need to be set.

# .env

# Default profile (no prefix) — password auth
TG_HOST=http://localhost
TG_USERNAME=tigergraph
TG_PASSWORD=tigergraph
TG_GRAPHNAME=MyGraph

# Staging profile — token auth
STAGING_TG_HOST=https://staging.example.com
STAGING_TG_API_TOKEN=staging_token_here
STAGING_TG_TGCLOUD=true

# Production profile — password auth
PROD_TG_HOST=https://prod.example.com
PROD_TG_USERNAME=admin
PROD_TG_PASSWORD=prod_secret
PROD_TG_GRAPHNAME=ProdGraph
PROD_TG_TGCLOUD=true

Profiles are discovered automatically at startup. Any variable matching <PROFILE>_TG_HOST registers a new profile. Values not set for a named profile fall back to the default profile's values.

Selecting the default profile

# Switch to staging for this run
TG_DEFAULT_PROFILE=staging tigergraph-mcp

# Or set permanently in .env
TG_DEFAULT_PROFILE=prod

TG_DEFAULT_PROFILE names the profile used when a call does not specify one. If it is not set, the unprefixed TG_* variables are the default profile. TG_PROFILE is accepted as an alias.

Omitting the profile argument and passing profile="default" mean the same thing — the default profile — in both stdio and HTTP mode.

Switching profiles per call

Every tool accepts an optional profile argument, so an agent can route individual calls to different environments without restarting the server. Connections are pooled per profile and reused across calls. list_connections reports the configured profiles, which one is the default, and which are currently connected — in HTTP mode scoped to the calling session.

User: Compare the vertex count of MyGraph between staging and prod.

Agent:
  → get_vertex_count(profile="staging", graph_name="MyGraph")
  → get_vertex_count(profile="prod",    graph_name="MyGraph")

User: Show me the schema on staging, then run this GSQL on prod:
      SHOW VERTEX Person

Agent:
  → get_graph_schema(profile="staging", graph_name="MyGraph")
  → gsql(profile="prod", command="SHOW VERTEX Person")

Helping the agent pick the right environment

Users normally name an environment the way it is configured — "staging", "the prod cluster". list_connections reports each profile's name and its host, so the agent can also resolve the occasional bare hostname or URL to the profile that reaches it:

{
  "default_profile": "dev",
  "profiles": [
    {"profile": "dev",     "host": "http://localhost",                "username": "tigergraph", "is_default": true,  "connected": true},
    {"profile": "prod",    "host": "https://mycompany.i.tgcloud.io",  "username": "analyst",    "is_default": false, "connected": false},
    {"profile": "staging", "host": "https://tg-staging.example.com",  "username": "analyst",    "is_default": false, "connected": false}
  ]
}

Note that prod's host carries no hint of the profile name, so a user who names that host cannot be served by guessing from profile names alone.

A system prompt that puts that to work:

You are a TigerGraph assistant. The tigergraph-mcp server may be configured
with several environments, each identified by a profile name.

Discovering profiles
- Call `list_connections` before your first data access, and again whenever
  the user mentions an environment you have not seen.
- Each profile reports its name, host, and username, which one is the
  default, and which are already connected.
- Never invent or hardcode a profile name.

Choosing one
- Users normally name an environment, not a machine. If the user names a
  profile ("use staging", "on the prod cluster"), use that profile.
- If the user names a host or URL instead, match it against the `host`
  field. Several profiles may share one host, differing only in the user
  they connect as. In that case run the request against every matching
  profile and report the results per profile, rather than asking which
  one was meant.
- If nothing matches what the user named, say so and list the configured
  profiles with their hosts. Do not guess.
- If the user says nothing about an environment, use the default profile
  and mention which one you used.

Using one
- Pass `profile="<name>"` on every tool call meant for that environment.
- A single turn may use different profiles when the user compares
  environments.

Reporting
- Answer about the environments the user asked about. Do not list the
  profiles you considered and skipped, and do not narrate the lookup.
- Name the environment alongside each answer, so the user knows which
  one it came from — especially when reporting more than one.

With that prompt, a site named in plain language resolves to a profile:

User: How many vertices does MyGraph have on staging?

Agent:
  → get_vertex_count(profile="staging", graph_name="MyGraph")
  "On staging: 1,204 vertices."

User: And on mycompany.i.tgcloud.io?          # a host, not an environment

Agent:                                        # tool calls, not shown to the user
  → list_connections()                        # prod and prod_ro share that host
  → get_vertex_count(profile="prod",    graph_name="MyGraph")
  → get_vertex_count(profile="prod_ro", graph_name="MyGraph")

Agent replies:
  "Two profiles reach that host:
     prod (as analyst):     1,204 vertices
     prod_ro (as readonly): 1,204 vertices"

The reply names the environment behind each number and says nothing about dev or staging, which the user did not ask about.

Omitting profile, or passing "default", uses the default profile — TG_DEFAULT_PROFILE if set (or its alias TG_PROFILE), otherwise the unprefixed TG_* variables.

HTTP Mode End-to-End

Run one shared server that several people or services connect to. Five steps.

1. Install with the web stack

pip install tigergraph-mcp uvicorn starlette

2. Describe your TigerGraph sites

Put the environments in an env file. The unprefixed TG_* variables are the default profile; each <NAME>_TG_* group adds another. Credentials here are optional — include them for a shared or demo deployment, omit them to require every client to send its own:

# /etc/tigergraph-mcp/.env
TG_DEFAULT_PROFILE=prod

PROD_TG_HOST=https://mycompany.i.tgcloud.io
PROD_TG_USERNAME=analyst
PROD_TG_PASSWORD=...

STAGING_TG_HOST=https://tg-staging.example.com
STAGING_TG_USERNAME=analyst
STAGING_TG_PASSWORD=...

3. Start the server

tigergraph-mcp --transport streamable-http \
  --host 0.0.0.0 --port 8000 \
  --env-file /etc/tigergraph-mcp/.env

It binds the port and serves until stopped, so run it under systemd, a container, or whatever supervises your services. Put a reverse proxy or API gateway in front for TLS and to control who may reach the URL.

4. Check that it is up

curl -s -o /dev/null -w '%{http_code}\n' -X POST http://localhost:8000/mcp/ \
  -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":"curl","version":"1"}}}'
Response Meaning
200 Up, and the default profile's credentials work
400 Up, but the request does not name a reachable site (e.g. an unknown profile)
401 Up, but no usable credentials — the client must send them
502 Up, but TigerGraph itself could not be reached
307 You omitted the trailing slash on /mcp/
connection refused The server is not running

5. Point a client at it

The URL is http://<host>:<port>/mcp/ — keep the trailing slash. Credentials, when the client supplies them, travel as X-TG-* headers; omit them to use the server's default profile as configured.

Cursor, VS Code, or any editor using mcp.json:

{
  "servers": {
    "tigergraph-mcp-server": {
      "type": "http",
      "url": "http://localhost:8000/mcp/",
      "headers": {
        "X-TG-Profile": "staging"
      }
    }
  }
}

The scheme is whatever the server is reachable on. tigergraph-mcp itself serves plain HTTP and does not terminate TLS, so use http:// when connecting to it directly. A deployed instance normally sits behind a reverse proxy that adds TLS, in which case the URL is the proxy's — https://my-tg-mcp.internal/mcp/. Credentials travel in headers, so anything beyond localhost should be https://.

To connect as yourself rather than as the profile's configured user, add your own credentials — keeping secrets out of the file by referencing the environment:

      "headers": {
        "X-TG-Host": "https://mycompany.i.tgcloud.io",
        "X-TG-Api-Token": "${env:TG_API_TOKEN}"
      }

Python, LangChain, or any MCP SDK client: see Client Examples for runnable versions of both. The HTTP client API differs between MCP SDK generations, so check which one you have with pip show mcp:

# MCP SDK 2.x
import httpx2
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

async with httpx2.AsyncClient(headers={"X-TG-Profile": "staging"}) as http_client:
    async with streamable_http_client(
        "http://localhost:8000/mcp/", http_client=http_client
    ) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            await session.call_tool("tigergraph__list_graphs", {})
# MCP SDK 1.x
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async with streamablehttp_client(
    "http://localhost:8000/mcp/", headers={"X-TG-Profile": "staging"}
) as (read, write, _):
    async with ClientSession(read, write) as session:
        await session.initialize()
        await session.call_tool("tigergraph__list_graphs", {})

Which connection a request gets

Profiles come from the server's env file, exactly as in Multiple Connection Profiles above. A request picks one with X-TG-Profile, and any other X-TG-* header overrides that profile's value for that session only:

Headers sent Connection used
X-TG-Profile only that profile's topology and its configured credentials
X-TG-Profile + credential headers that profile's topology, the caller's identity
Credential headers only the default profile's topology, the caller's identity
No headers the default profile exactly as configured

Whether profiles carry credentials at all is your decision when writing the env file. Credentials there are a shared identity usable by anyone who can reach the server, which suits a demo or single-user deployment; an env file with topology only forces every caller to identify itself, which is what you want when several people share the server.

Recognised headers mirror the TG_* variables used in stdio mode:

Header Env-var equivalent
X-TG-Profile selects a server-side profile (<PROFILE>_TG_*)
X-TG-Host TG_HOST
X-TG-Graphname TG_GRAPHNAME
X-TG-Username + X-TG-Password TG_USERNAME + TG_PASSWORD
X-TG-Secret TG_SECRET
X-TG-Api-Token TG_API_TOKEN
X-TG-Jwt-Token TG_JWT_TOKEN
X-TG-Restpp-Port, X-TG-Gs-Port, X-TG-Ssl-Port TG_RESTPP_PORT, TG_GS_PORT, TG_SSL_PORT
X-TG-Tgcloud (true/false) TG_TGCLOUD
X-TG-Cert-Path TG_CERT_PATH

Once connected, a tool call may still name any configured profile with its profile argument; that connection opens in the calling session and is never shared with another.

Serving several users

Each session gets its own connections, so concurrent users never share state or credentials. Two patterns work:

  • Each person's editor connects directly, with their own profile or credentials in mcp.json — the configuration shown above.
  • An application connects on its users' behalf, opening one session per logged-in user with that user's credentials in the headers, held for their lifetime so the LLM never sees credentials. A working reference is in examples/multi_user_backend/.

Two settings matter for a long-running server: TG_HTTP_SESSION_IDLE_TIMEOUT (default 900s) reclaims connections from sessions that have gone quiet, and TG_HTTP_ALLOWED_PROFILES=demo,staging narrows which profiles clients may name.

Access control to the endpoint itself is the deployment's responsibility — the server checks TigerGraph credentials, not who may reach the URL. Put a reverse proxy or API gateway in front, which is also where TLS belongs.

The authenticate tool can re-point a live session mid-conversation, which is not needed when credentials arrive as headers.

Serving a Subset of the Tools

All 69 tools are offered by default. An agent carries every tool it is given on every request, so a deployment that only needs some of them can say so:

# only the tools that read
tigergraph-mcp --allowed-tools read-only

# a task-shaped subset
tigergraph-mcp --allowed-tools schema,query

# everything except the ones that remove data
tigergraph-mcp --blocked-tools destructive

TG_ALLOWED_TOOLS and TG_BLOCKED_TOOLS do the same from the environment or an env file; the flags win where both are set.

A selector is a comma-separated list of:

Selector Meaning
schema, data, query, vector, loading, utility, discovery a category
read-only the tools that change nothing
destructive the tools that may remove or overwrite something
list_graphs, tigergraph__list_graphs one tool, with or without the prefix

--blocked-tools is applied after --allowed-tools, so --allowed-tools schema --blocked-tools drop_graph serves the schema tools without that one. An unrecognised selector stops the server at startup rather than quietly serving a short list, and a selection that leaves nothing to serve is likewise an error.

Roughly what each choice costs an agent:

Served Tools ~Tokens
everything 69 29,100
read-only 37 12,400
schema,query 21 9,100

Note that discovery and utility are not added automatically. If you narrow by category, include them where the agent needs to discover tools or route calls by profile: --allowed-tools schema,query,discovery,utility.

Per-session narrowing over HTTP

A client may restrict its own session with an X-TG-Tools header, using the same selectors:

{
  "servers": {
    "tigergraph-mcp-server": {
      "type": "http",
      "url": "http://localhost:8000/mcp/",
      "headers": {
        "X-TG-Profile": "prod",
        "X-TG-Tools": "read-only"
      }
    }
  }
}

This only ever narrows. A session cannot reach a tool the deployment withheld, so asking for destructive on a server started with --blocked-tools destructive yields no tools rather than the blocked ones.

What a tool declares about itself

Every tool carries the MCP behavioural hints, which is how an editor decides whether to run something silently or ask first:

"annotations": {
  "title": "Drop graph",
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": false
}

These reach the client, not the model, so they cost nothing in context. read-only and destructive selectors resolve from the same classification. Tools that execute caller-supplied query text — gsql, run_query, run_installed_query — are marked destructive, because what they do depends on the text they are given.

Logging Tool Calls

Nothing is logged about tool calls by default. A shared deployment usually wants a record of what has been run against an instance:

tigergraph-mcp --transport streamable-http --log-tool-calls

One line per call goes to stderr:

tool call tool=tigergraph__drop_graph session=b1f2c3 host=https://mycompany.i.tgcloud.io

Who made the call is a separate opt-in, because a TigerGraph account name generally identifies a person. It requires --log-tool-calls — on its own it does nothing, and the server says so at startup:

# the connection profile the call used
tigergraph-mcp --log-tool-calls --log-caller profile

# the TigerGraph account as well
tigergraph-mcp --log-tool-calls --log-caller username
--log-caller Line carries
none (default) tool, session, host
profile the above, plus the connection profile
username the above, plus the account name and how it authenticated
tool call tool=tigergraph__drop_graph session=b1f2c3 host=https://mycompany.i.tgcloud.io profile=prod user=alice auth=password

TG_LOG_TOOL_CALLS and TG_LOG_CALLER_IDENTITY do the same from the environment or an env file; the flags win where both are set. TG_LOG_CALLER_IDENTITY is gated the same way, so leaving it in an env file has no effect until tool-call logging is turned on — and turning it on later will not silently start writing account names.

Two things to know before turning on username:

  • Callers who authenticate with a token or a GSQL secret appear as user=-. TigerGraph tokens do not tell the server which account is behind them, so there is no name to record.
  • The logs then contain personal data. Whatever retention, access, and disclosure rules apply to your other logs apply to these. profile is the smaller disclosure and is often enough — it says which configured connection was used without naming anyone.

In stdio mode there is a single configured identity for the process, so every line carries the same profile and account. The record is more useful over HTTP, where each session authenticates separately.

Never logged, at any setting: passwords, GSQL secrets, API and JWT tokens, and tool arguments — arguments hold query text and vertex payloads, which is graph data rather than an audit record. Access to the endpoint itself is still the deployment's concern; a reverse proxy is where request-level access logs belong.

Using with Existing Connection

from pyTigerGraph import AsyncTigerGraphConnection
from tigergraph_mcp import ConnectionManager

async with AsyncTigerGraphConnection(
    host="http://localhost",
    graphname="MyGraph",
    username="tigergraph",
    password="tigergraph",
) as conn:
    ConnectionManager.set_default_connection(conn)
    # ... run MCP tools ...
# HTTP connection pool is released on exit

Client Examples

Hold one session for the run. MultiServerMCPClient(...) connects nothing, and await client.get_tools() opens a session only to list the tools, then closes it — the returned tools carry a connection config, so each tool call opens a new session. Over stdio that spawns a tigergraph-mcp process per call; over HTTP it creates a session, a connection, and a credential check per call. Binding tools to a session held open by client.session(...) reuses one process (or one session and its pooled connection) for the whole run — in a measured 8-call agent run, 1 session instead of 9, and roughly 4× faster. Use get_tools() only for one-shot scripts.

LangChain / LangGraph over stdio

The client starts tigergraph-mcp as a subprocess and passes credentials as env vars.

import asyncio
from pathlib import Path

from dotenv import dotenv_values
from langchain.chat_models import init_chat_model
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent

env_dict = dotenv_values(dotenv_path=Path(".env").expanduser().resolve())

client = MultiServerMCPClient(
    {
        "tigergraph-mcp-server": {
            "transport": "stdio",
            "command": "tigergraph-mcp",
            "args": ["-vv"],
            "env": env_dict,
        },
    }
)


async def main():
    # One session for the whole run; every tool call reuses it.
    async with client.session("tigergraph-mcp-server") as session:
        tools = await load_mcp_tools(session)

        agent = create_react_agent(init_chat_model("openai:gpt-4.1-mini"), tools)
        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "Which graphs are available?"}]}
        )
        print(result["messages"][-1].content)


asyncio.run(main())

create_react_agent is one option; init_chat_model(...).bind_tools(tools) works too if you are driving the model yourself. Either way, build the agent inside the session so the tools stay bound to it.

Note: Instead of loading a .env file, you can pass credentials directly in the env mapping:

    "env": {
      "TG_HOST": "http://localhost",
      "TG_USERNAME": "tigergraph",
      "TG_PASSWORD": "tigergraph",
      "TG_GRAPHNAME": "MyGraph"
    }

Either way the credentials must be in env: the subprocess does not inherit your shell environment.

LangChain / LangGraph over HTTP

The server is already running elsewhere; the client only connects. Credentials travel as headers, so nothing about TigerGraph needs to be configured on this side.

import asyncio

from langchain.chat_models import init_chat_model
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient(
    {
        "tigergraph-mcp-server": {
            "transport": "streamable_http",
            "url": "http://localhost:8000/mcp/",   # trailing slash required
            "headers": {
                # Omit these entirely to use the server's default profile.
                "X-TG-Profile": "staging",
                "X-TG-Username": "my_user",
                "X-TG-Password": "my_password",
            },
        },
    }
)


async def main():
    async with client.session("tigergraph-mcp-server") as session:
        tools = await load_mcp_tools(session)

        agent = create_react_agent(init_chat_model("openai:gpt-4.1-mini"), tools)
        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "How many vertices are in MyGraph?"}]}
        )
        print(result["messages"][-1].content)


asyncio.run(main())

MCP SDK over stdio

stdio_client does not pass your environment to the subprocess — it forwards only a minimal safe set (HOME, PATH, SHELL, …). Credentials must be supplied explicitly via env, or the server will fall back to its defaults and try http://127.0.0.1.

import asyncio
from pathlib import Path

from dotenv import dotenv_values
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import get_default_environment, stdio_client

env_dict = dotenv_values(dotenv_path=Path(".env").expanduser().resolve())


async def main():
    server_params = StdioServerParameters(
        command="tigergraph-mcp",
        args=["-vv"],
        env={**get_default_environment(), **env_dict},
    )

    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await session.list_tools()
            print(f"Available tools: {[t.name for t in tools.tools]}")

            result = await session.call_tool("tigergraph__list_graphs", arguments={})
            for content in result.content:
                print(content.text)


asyncio.run(main())

MCP SDK over HTTP

The HTTP client API changed between MCP SDK generations. Check yours with pip show mcp — a fresh pip install currently gets 2.x. In 1.x the function took headers and yielded three values; in 2.x it takes an http_client carrying the headers and yields two.

# MCP SDK 2.x
import asyncio

import httpx2
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

URL = "http://localhost:8000/mcp/"           # trailing slash required
HEADERS = {                                  # omit to use the default profile
    "X-TG-Profile": "staging",
}


async def main():
    async with httpx2.AsyncClient(headers=HEADERS) as http_client:
        async with streamable_http_client(URL, http_client=http_client) as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()

                tools = await session.list_tools()
                print(f"Available tools: {[t.name for t in tools.tools]}")

                # Every call reuses this session's pooled connection.
                result = await session.call_tool("tigergraph__list_graphs", arguments={})
                for content in result.content:
                    print(content.text)

                # Route one call to another configured profile.
                await session.call_tool(
                    "tigergraph__list_graphs", arguments={"profile": "prod"}
                )


asyncio.run(main())
# MCP SDK 1.x
import asyncio

from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

URL = "http://localhost:8000/mcp/"
HEADERS = {"X-TG-Profile": "staging"}


async def main():
    async with streamablehttp_client(URL, headers=HEADERS) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool("tigergraph__list_graphs", arguments={})
            for content in result.content:
                print(content.text)


asyncio.run(main())

Available Tools

Global Schema Operations

  • tigergraph__get_global_schema — Get the complete global schema via GSQL LS

Graph Operations

  • tigergraph__list_graphs — List all graph names in the database
  • tigergraph__create_graph — Create a new graph with schema
  • tigergraph__drop_graph — Drop a graph and its schema
  • tigergraph__clear_graph_data — Clear all data from a graph (keeps schema)

Schema Operations

  • tigergraph__get_graph_schema — Get schema as structured JSON
  • tigergraph__show_graph_details — Show schema, queries, loading jobs, and data sources

Node Operations

  • tigergraph__add_node / tigergraph__add_nodes
  • tigergraph__get_node / tigergraph__get_nodes
  • tigergraph__delete_node / tigergraph__delete_nodes
  • tigergraph__has_node
  • tigergraph__get_node_edges

Edge Operations

  • tigergraph__add_edge / tigergraph__add_edges
  • tigergraph__get_edge / tigergraph__get_edges
  • tigergraph__delete_edge / tigergraph__delete_edges
  • tigergraph__has_edge

Query Operations

  • tigergraph__run_query — Run an interpreted query
  • tigergraph__run_installed_query — Run an installed query
  • tigergraph__install_query / tigergraph__drop_query
  • tigergraph__show_query / tigergraph__get_query_metadata / tigergraph__is_query_installed
  • tigergraph__update_query_description / tigergraph__get_query_description — Set or read query and per-parameter descriptions (TigerGraph 4.0+)
  • tigergraph__get_neighbors

Loading Job Operations

  • tigergraph__create_loading_job — from files, or from a data_source + query pair to load the result of a SQL query against a warehouse
  • tigergraph__run_loading_job_with_file / tigergraph__run_loading_job_with_data
  • tigergraph__get_loading_jobs / tigergraph__get_loading_job_status
  • tigergraph__drop_loading_job

Statistics Operations

  • tigergraph__get_vertex_count / tigergraph__get_edge_count
  • tigergraph__get_node_degree

GSQL Operations

  • tigergraph__gsql — Execute raw GSQL
  • tigergraph__generate_gsql — Generate GSQL from natural language (requires [llm])
  • tigergraph__generate_cypher — Generate openCypher from natural language (requires [llm])

Vector Schema Operations

  • tigergraph__add_vector_attribute / tigergraph__drop_vector_attribute
  • tigergraph__list_vector_attributes / tigergraph__get_vector_index_status

Vector Data Operations

  • tigergraph__upsert_vectors
  • tigergraph__load_vectors_from_csv / tigergraph__load_vectors_from_json
  • tigergraph__search_top_k_similarity / tigergraph__fetch_vector

Data Source Operations

  • tigergraph__create_data_source / tigergraph__update_data_source
  • tigergraph__get_data_source / tigergraph__drop_data_source
  • tigergraph__get_all_data_sources / tigergraph__drop_all_data_sources
  • tigergraph__get_data_source_types — List supported types and their configuration keys
  • tigergraph__preview_sample_data

Supported data source types:

Family Types
Object storage s3, gcs, abs (alias: azure_blob)
Data warehouse snowflake, bigquery, postgresql
Lakehouse iceberg
Streaming kafka, kafka_v2, mirrormaker

Each type takes different configuration keys. Call tigergraph__get_data_source_types for the required keys and a worked example, or see Loading from a data warehouse.

Credentials in config are sent to TigerGraph but masked in tool responses, so they do not appear in a conversation transcript.

Connection / Session

  • tigergraph__list_connections / tigergraph__show_connection — Inspect configured profiles
  • tigergraph__authenticate — Register per-session TigerGraph credentials (HTTP/SSE mode)

Discovery & Navigation

  • tigergraph__discover_tools — Search for tools by description or keywords
  • tigergraph__get_workflow — Get step-by-step workflow templates
  • tigergraph__get_tool_info — Get detailed information about a specific tool

LLM-Friendly Features

Structured Responses

Every tool returns a consistent JSON structure:

{
  "success": true,
  "operation": "get_node",
  "summary": "Found vertex 'p123' of type 'Person'",
  "data": { ... },
  "suggestions": ["View connected edges: get_node_edges(...)"],
  "metadata": { "graph_name": "MyGraph" }
}

Error responses include actionable recovery hints:

{
  "success": false,
  "operation": "get_node",
  "error": "Vertex not found",
  "suggestions": ["Verify the vertex_id is correct"]
}

Rich Tool Descriptions

Each tool includes detailed descriptions with use cases, common workflows, tips, warnings, and related tools.

Token Optimization

Responses are designed for efficient LLM token usage — no echoing of input parameters, only new information (results, counts, boolean answers).

Tool Discovery

# Find the right tool
result = await session.call_tool("tigergraph__discover_tools",
    arguments={"query": "how to add data to the graph"})

# Get a workflow template
result = await session.call_tool("tigergraph__get_workflow",
    arguments={"workflow_type": "data_loading"})

# Get detailed tool info
result = await session.call_tool("tigergraph__get_tool_info",
    arguments={"tool_name": "tigergraph__add_node"})

Notes

  • Transport: stdio by default
  • Error Detection: GSQL operations include error detection for syntax and semantic errors
  • Connection Management: Connections are pooled by profile and reused across requests; pool is released at server shutdown
  • Performance: Persistent HTTP connection pool per profile; async non-blocking I/O; v.outdegree() for O(1) degree counting; batch operations for multiple vertices/edges

Metadata

Release files for tigergraph-mcp 1.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tigergraph-mcp 1.0.4
File Size Uploaded
tigergraph_mcp-1.0.4.tar.gz 195.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tigergraph-mcp 1.0.4
File Interpreter ABI Platform
tigergraph_mcp-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 335.0 kB

Release files / tigergraph_mcp-1.0.4.tar.gz

Download URL tigergraph_mcp-1.0.4.tar.gz
Size 195.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bfdddd8065cabc3ecd25cee89ec7f0a3066576273a45f1c43d6fce3d45fc8229
BLAKE2b-256 checksum
How to use checksums
aced87973b6b538f06084b1a5eecf565eaa57bb4f970a3989c92d7dff41b3d2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / tigergraph_mcp-1.0.4-py3-none-any.whl

Download URL tigergraph_mcp-1.0.4-py3-none-any.whl
Size 139.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47eb5b51ea2c3f956d984400a5ffa9c352e8a9e654fb96c48e3ca922dadb1e90
BLAKE2b-256 checksum
How to use checksums
1a937c38ac224eaf9a2eafdae3b05dcbc9b44a5c8e2ae98b4a649fb6416a0ddf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page