Skip to main content
Glama

@arizeai/phoenix-mcp

Official
by Arize-ai
RelayEnvironment.ts3.9 kB
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay"; import { Environment, FetchFunction, Network, Observable, RecordSource, Store, } from "relay-runtime"; import invariant from "tiny-invariant"; import { authFetch } from "@phoenix/authFetch"; import { BASE_URL } from "@phoenix/config"; import { isObject } from "./typeUtils"; const graphQLPath = BASE_URL + "/graphql"; const isAuthenticationEnabled = window.Config.authenticationEnabled; const graphQLFetch = isAuthenticationEnabled ? authFetch : fetch; /** * Create an observable that fetches JSON from the given input and returns an error if * the data has errors. * * The observable aborts in-flight network requests when the unsubscribe function is * called. * * @param input - The input to fetch from. * @param init - The request init options. * @param hasErrors - A function that returns an error if the data has errors. * @returns An observable that emits the data or an error. */ function fetchJsonObservable<T>( input: RequestInfo | URL, init?: RequestInit, hasErrors?: (data: unknown) => Error | undefined ): Observable<T> { return Observable.create((sink) => { const controller = new AbortController(); graphQLFetch(input, { ...init, signal: controller.signal }) .then((response) => { invariant(response instanceof Response, "response must be a Response"); return response.json(); }) .then((data) => { const error = hasErrors?.(data); if (error) { throw error; } sink.next(data as T); sink.complete(); }) .catch((error) => { if (error.name === "AbortError") { // this is triggered when the controller is aborted sink.complete(); } else { // this is triggered when graphQLFetch throws an error or the response // data has errors sink.error(error); } }); return () => { // abort the fetch request when the observable is unsubscribed controller.abort(); }; }); } /** * Relay requires developers to configure a "fetch" function that tells Relay how to load * the results of GraphQL queries from your server (or other data source). See more at * https://relay.dev/docs/en/quick-start-guide#relay-environment. */ const fetchRelay: FetchFunction = (params, variables, _cacheConfig) => fetchJsonObservable( graphQLPath, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query: params.text, variables, }), }, // GraphQL returns exceptions (for example, a missing required variable) in the "errors" // property of the response. If any exceptions occurred when processing the request, // throw an error to indicate to the developer what went wrong. (data) => { if (!isObject(data) || !("errors" in data)) { return; } if (Array.isArray(data.errors)) { return new Error( `Error fetching GraphQL query '${params.name}' with variables '${JSON.stringify( variables )}': ${JSON.stringify(data.errors)}` ); } } ); const subscribe = createFetchMultipartSubscription(graphQLPath, { fetch: graphQLFetch, }); // Export a singleton instance of Relay Environment configured with our network layer: export default new Environment({ network: Network.create(fetchRelay, subscribe), store: new Store(new RecordSource(), { // This property tells Relay to not immediately clear its cache when the user // navigates around the app. Relay will hold onto the specified number of // query results, allowing the user to return to recently visited pages // and reusing cached data if its available/fresh. gcReleaseBufferSize: 20, }), });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Arize-ai/phoenix'

If you have feedback or need assistance with the MCP directory API, please join our Discord server