Skip to main content

Connecting Agent Frameworks to OpenMetadata MCP

This section also includes guides for Claude Desktop, Cursor, VS Code, and Goose. Each of those assumes a person runs the client interactively and can complete a browser sign-in. This guide covers the opposite case: a programmatic agent framework such as CrewAI, LangChain, the OpenAI Agents SDK, or your own orchestration code. It calls the MCP server directly over HTTP with no one present.

When to Use This Guide

Use this guide if:
  • You’re wiring an agent framework directly to the MCP endpoint, not through one of the interactive clients covered elsewhere in this section.
  • Your process runs unattended, on a schedule, or as part of a larger pipeline. No one is available to complete an OAuth browser login.
  • You need a service identity whose access is separate from any individual’s account.

1. Authenticate with a Bot Token

OAuth 2.0 (see OAuth 2.0 Authentication) requires a person to sign in through a browser, so it doesn’t fit an unattended agent. Bots also can’t generate a Personal Access Token — OpenMetadata rejects that request. Use a Bot’s JSON Web Token (JWT) instead:
  1. Follow How to Set Up Bots to create a Bot and assign it the role-based access policy your agent needs.
  2. On the Bot’s details page, click Generate New Token to issue its JWT, following Bot Token.
  3. Store the token in an environment variable or secrets manager, never in source control.
Every request to the MCP endpoint carries this token in the Authorization header:

2. Set Up a Raw JSON-RPC Session

Before your first tool call, initialize the connection and confirm it:
From here, call any tool with tools/call:
See the MCP Server Connection Guide for the full protocol reference, including headers, tools/list, and prompts. See the MCP Tools Reference for every available tool.

3. Wrap the Session in LangChain

The following snippet wraps the raw session shown earlier as a LangChain StructuredTool. It’s illustrative, not a maintained SDK: A full LangChain or CrewAI MCP adapter, if one becomes available, would replace hand-rolled HTTP calls like these. It targets Python 3.10+ because the code uses the X | None type-hint syntax introduced in that release.
The same pattern works for other tools, such as get_entity_details and get_entity_lineage. Wrap each one the same way: one small function per tool, each calling session.call_tool with that tool’s name and arguments.

4. Check isError on Every Response

Because there’s no human watching for a stuck spinner, a headless caller must explicitly check result.isError on every tool call rather than assuming a 200-shaped response succeeded. See Tool Execution Errors for the full envelope shape and a worked example.