> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP returns empty logs for SaaS org from self-hosted endpoint

export const plans_0 = "Any"

export const deployments_0 = "Self-hosted"

export const data_plane_version_0 = undefined

export const use_case_0 = "Use case - Users with both a self-hosted Braintrust org and a SaaS (Braintrust-hosted) org who find that MCP sql_query returns 0 rows for SaaS org project_logs when connected via their self-hosted MCP endpoint"

<Note>
  **Applies to:**

  * Plan - {plans_0}
  * Deployment - {deployments_0}
  * {data_plane_version_0}
  * {use_case_0}
</Note>

## Summary

**Issue:** `sql_query` against `project_logs` returns 0 rows for a SaaS org, and `resolve_object` returns `Missing read access` for the same projects, even though logs are visible in the UI and the MCP OAuth token works for other orgs.

**Cause:** The Braintrust MCP endpoint is data-plane-scoped — a self-hosted MCP endpoint can resolve control-plane metadata (projects, experiments) across orgs, but can only read log data from its own Brainstore instance; SaaS org log data lives in Braintrust's public Brainstore.

**Resolution:** Add a second MCP server connection pointing at the SaaS data plane endpoint and complete a fresh OAuth flow against it.

## Resolution steps

### Step 1: Identify which MCP endpoint you are connected to

If your current MCP connection points at a self-hosted data plane URL (e.g., `https://d8k4dyx7j51un.cloudfront.net/mcp`) rather than `https://api.braintrust.dev/mcp`, log queries for SaaS org projects will always return empty — this is a routing issue, not a permissions issue.

Symptoms that confirm this:

* `sql_query` on `project_logs` returns `{ "data": [] }` with no time filter and a direct `object_ids` value
* `resolve_object` returns `Missing read access` for a SaaS org project
* The same token returns rows for projects in your self-hosted org

### Step 2: Add a second MCP server connection for the SaaS data plane

Add a new MCP server entry in your client pointing at the Braintrust SaaS endpoint:

| Region | Endpoint                            |
| ------ | ----------------------------------- |
| US     | `https://api.braintrust.dev/mcp`    |
| EU     | `https://api-eu.braintrust.dev/mcp` |

Example using the Claude CLI:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
claude mcp add --transport http braintrust-saas \
  https://api.braintrust.dev/mcp
```

Your client will run a fresh OAuth flow against this endpoint. Do not remove your existing self-hosted MCP connection — keep both running side by side.

### Step 3: Use the correct connection per org

After adding the second connection, tools from each MCP server are namespaced separately in your client (e.g., `braintrust-saas:sql_query` vs your self-hosted connection's tools).

Use the SaaS connection when querying projects in Braintrust-hosted orgs, and the self-hosted connection for projects in your self-hosted org.

### Step 4: Verify access

Run the following query against the SaaS connection to confirm rows are returned:

```json theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "object_type": "project_logs",
  "object_ids": ["<your-saas-project-id>"],
  "select": "id, created",
  "order_by": "created DESC",
  "limit": 5
}
```

The response should now contain `data` with rows matching what is visible in the UI.

## Notes

* This issue is not caused by user permissions. Being an org admin does not grant cross-data-plane read access through the wrong MCP endpoint.
* Control-plane metadata (project names, experiment lists) is shared, which is why `list` operations succeed even on the wrong endpoint — only log data reads are affected.
* No changes to your self-hosted deployment are required.
