Repository: openops-cloud/openops
Pull request #603: Add mcp baserow
Author: login: rmn-snpk
Created: 2025-05-15T02:07:31Z | Merged: 2025-05-15T08:38:15Z

<!--
Ensure the title clearly reflects what was changed.
Provide a clear and concise description of the changes made. The PR should only contain the changes related to the issue, and no other unrelated changes.
-->

Fixes OPS-1722.

<!--
Why was it changed?
Any relevant context or links?
Add refactoring notes (if applicable), preferably as comments in the code (if you refactored code, explain what was moved/changed and why).
-->

## Testing Checklist

Check all that apply:

- [X] I tested the feature thoroughly, including edge cases

- [X] I verified all affected areas still work as expected

- [X] Automated tests were added/updated if necessary

- [X] Changes are backwards compatible with any existing data, otherwise a migration script is provided

## Visual Changes (if applicable)
![image](https://github.com/user-attachments/assets/761d6b85-7d08-4093-baed-71f2286e740a)




Diff:
diff --git a/ai-prompts/mcp.txt b/ai-prompts/mcp.txt
index 1cd9723ece..7410e63bec 100644
--- a/ai-prompts/mcp.txt
+++ b/ai-prompts/mcp.txt
@@ -35,3 +35,15 @@ You must know how to:
 - Field names match exactly with the dataset schema (case-sensitive)
 - No inferred or aliased column names are used unless explicitly confirmed
 * When you are asked about "my dashboard", "finops dashboard", "homepage dashboard", "analytics dashboard", or "main dashboard" -- if you don't have the dashboard id and you are not given it, search for it by the slug 'finops'.
+
+OpenOps Tables Integration
+When invoking the OpenOps Tables (Baserow) MCP, you must fully understand the Baserow REST API and its core functionality. Specifically:
+- Perform operations on database tables, rows, and fields.
+- Understand how to create	(Add new records), query (Query existing data), update ( and delete data and in a table.
+- **Strict** Do not manage table schema (e.g., adding, removing and changing fields).
+- Always ensure:
+  - Table IDs, row IDs, and field IDs are correctly obtained through API calls and not assumed.
+  - Names, field types, or constraints match Baserow's schema or configuration exactly.
+  - Token-based authentication is used for all API interactions.
+- Format payloads appropriately for each endpoint, adhering to Baserow's API requirements (e.g., the types and structure of fields and rows).
+
diff --git a/packages/openops/src/lib/openops-tables/requests-helpers.ts b/packages/openops/src/lib/openops-tables/requests-helpers.ts
index 6925b00ed0..ed38a83dff 100644
--- a/packages/openops/src/lib/openops-tables/requests-helpers.ts
+++ b/packages/openops/src/lib/openops-tables/requests-helpers.ts
@@ -111,7 +111,7 @@ export async function makeOpenOpsTablesGet<T>(
   return responses;
 }
 
-async function makeOpenOpsTablesRequest<T>(
+export async function makeOpenOpsTablesRequest<T>(
   method: Method,
   route: string,
   body?: any,
diff --git a/packages/openops/src/lib/openops-tables/types/index.ts b/packages/openops/src/lib/openops-tables/types/index.ts
index 886505edb7..833e470bfc 100644
--- a/packages/openops/src/lib/openops-tables/types/index.ts
+++ b/packages/openops/src/lib/openops-tables/types/index.ts
@@ -1,3 +1,5 @@
 export * from './application';
 export * from './auth-user';
+export * from './mcp';
+export * from './table-workspace';
 export * from './user';
diff --git a/packages/openops/src/lib/openops-tables/types/mcp.ts b/packages/openops/src/lib/openops-tables/types/mcp.ts
new file mode 100644
index 0000000000..7d16dcf0f4
--- /dev/null
+++ b/packages/openops/src/lib/openops-tables/types/mcp.ts
@@ -0,0 +1,8 @@
+export type TablesMcpEndpoint = {
+  id: number;
+  name: string;
+  key: string;
+  workspace_id: number;
+  workspace_name: string;
+  created: string;
+};
diff --git a/packages/openops/src/lib/openops-tables/types/table-workspace.ts b/packages/openops/src/lib/openops-tables/types/table-workspace.ts
new file mode 100644
index 0000000000..c679f564b5
--- /dev/null
+++ b/packages/openops/src/lib/openops-tables/types/table-workspace.ts
@@ -0,0 +1,20 @@
+type User = {
+  id: number;
+  name: string;
+  email: string;
+  workspace: number;
+  permissions: string;
+  created_on: string;
+  user_id: number;
+  to_be_deleted: boolean;
+};
+
+export type TableWorkspace = {
+  id: number;
+  name: string;
+  users: User[];
+  order: number;
+  permissions: string;
+  unread_notifications_count: number;
+  generative_ai_models_enabled: string;
+};
diff --git a/packages/server/api/src/app/ai/mcp/mcp-tools.ts b/packages/server/api/src/app/ai/mcp/mcp-tools.ts
index d6b6084224..3e201dcd65 100644
--- a/packages/server/api/src/app/ai/mcp/mcp-tools.ts
+++ b/packages/server/api/src/app/ai/mcp/mcp-tools.ts
@@ -2,6 +2,7 @@ import { logger } from '@openops/server-shared';
 import { ToolSet } from 'ai';
 import { getDocsTools } from './docs-tools';
 import { getSupersetTools } from './superset-tools';
+import { getTablesTools } from './tables-tools';
 
 let toolSet: ToolSet | undefined;
 
@@ -12,10 +13,12 @@ export const getMCPTools = async (): Promise<ToolSet> => {
 
   const supersetTools = await safeGetTools('superset', getSupersetTools);
   const docsTools = await safeGetTools('docs', getDocsTools);
+  const tablesTools = await safeGetTools('tables', getTablesTools);
 
   toolSet = {
     ...supersetTools,
     ...docsTools,
+    ...tablesTools,
   } as ToolSet;
 
   return toolSet;
diff --git a/packages/server/api/src/app/ai/mcp/tables-tools.ts b/packages/server/api/src/app/ai/mcp/tables-tools.ts
new file mode 100644
index 0000000000..5a2ea1e89a
--- /dev/null
+++ b/packages/server/api/src/app/ai/mcp/tables-tools.ts
@@ -0,0 +1,30 @@
+import {
+  authenticateDefaultUserInOpenOpsTables,
+  createAxiosHeaders,
+} from '@openops/common';
+import { AppSystemProp, system } from '@openops/server-shared';
+import { experimental_createMCPClient as createMCPClient, ToolSet } from 'ai';
+import { openopsTables } from '../../openops-tables';
+
+export async function getTablesTools(): Promise<ToolSet> {
+  const { token } = await authenticateDefaultUserInOpenOpsTables();
+  const mcpEndpoint = await openopsTables.getMcpEndpointList(token);
+
+  if (!mcpEndpoint) {
+    return {};
+  }
+
+  const url =
+    system.get(AppSystemProp.OPENOPS_TABLES_API_URL) +
+    `/openops-tables/mcp/${mcpEndpoint[0].key}/sse`;
+
+  const client = await createMCPClient({
+    transport: {
+      type: 'sse',
+      url,
+      headers: createAxiosHeaders(token),
+    },
+  });
+
+  return client.tools();
+}
diff --git a/packages/server/api/src/app/database/seeds/create-open-ops-tables-mcp-endpoint.ts b/packages/server/api/src/app/database/seeds/create-open-ops-tables-mcp-endpoint.ts
new file mode 100644
index 0000000000..bd5193b6a3
--- /dev/null
+++ b/packages/server/api/src/app/database/seeds/create-open-ops-tables-mcp-endpoint.ts
@@ -0,0 +1,19 @@
+import { authenticateDefaultUserInOpenOpsTables } from '@openops/common';
+import { logger } from '@openops/server-shared';
+import { openopsTables } from '../../openops-tables';
+import { OPENOPS_DEFAULT_WORKSPACE_NAME } from '../../openops-tables/default-workspace-database';
+
+export const createOpenOpsTablesMcpEndpoint = async () => {
+  const { token } = await authenticateDefaultUserInOpenOpsTables();
+  const mcpEndpoints = await openopsTables.getMcpEndpointList(token);
+  const workspace = await openopsTables.getWorkspaceByName(
+    token,
+    OPENOPS_DEFAULT_WORKSPACE_NAME,
+  );
+
+  if (!mcpEndpoints?.length && workspace) {
+    logger.info(`MCP endpoint does not exist, creating it`);
+
+    await openopsTables.createMcpEndpoint(workspace?.id, token);
+  }
+};
diff --git a/packages/server/api/src/app/openops-tables/create-mcp-endpoint.ts b/packages/server/api/src/app/openops-tables/create-mcp-endpoint.ts
new file mode 100644
index 0000000000..b634f96d3d
--- /dev/null
+++ b/packages/server/api/src/app/openops-tables/create-mcp-endpoint.ts
@@ -0,0 +1,21 @@
+import {
+  createAxiosHeaders,
+  makeOpenOpsTablesPost,
+  TablesMcpEndpoint,
+} from '@openops/common';
+
+export async function createMcpEndpoint(
+  workspaceId: number,
+  token: string,
+): Promise<void> {
+  const requestBody = {
+    name: 'OpenOps MCP Endpoint',
+    workspace_id: workspaceId,
+  };
+
+  await makeOpenOpsTablesPost<TablesMcpEndpoint>(
+    `api/mcp/endpoints/`,
+    requestBody,
+    createAxiosHeaders(token),
+  );
+}
diff --git a/packages/server/api/src/app/openops-tables/default-workspace-database.ts b/packages/server/api/src/app/openops-tables/default-workspace-database.ts
index d7800f120e..d7ae237811 100644
--- a/packages/server/api/src/app/openops-tables/default-workspace-database.ts
+++ b/packages/server/api/src/app/openops-tables/default-workspace-database.ts
@@ -1,11 +1,13 @@
 import { OPENOPS_DEFAULT_DATABASE_NAME } from '@openops/common';
 import { openopsTables } from './index';
 
+export const OPENOPS_DEFAULT_WORKSPACE_NAME = 'OpenOps Workspace';
+
 export async function createDefaultWorkspaceAndDatabase(
   token: string,
 ): Promise<{ workspaceId: number; databaseId: number }> {
   const workspace = await openopsTables.createWorkspace(
-    'OpenOps Workspace',
+    OPENOPS_DEFAULT_WORKSPACE_NAME,
     token,
   );
 
diff --git a/packages/server/api/src/app/openops-tables/get-mcp-endpoint-list.ts b/packages/server/api/src/app/openops-tables/get-mcp-endpoint-list.ts
new file mode 100644
index 0000000000..08c7fa1363
--- /dev/null
+++ b/packages/server/api/src/app/openops-tables/get-mcp-endpoint-list.ts
@@ -0,0 +1,16 @@
+import {
+  createAxiosHeaders,
+  makeOpenOpsTablesRequest,
+  TablesMcpEndpoint,
+} from '@openops/common';
+
+export async function getMcpEndpointList(
+  token: string,
+): Promise<TablesMcpEndpoint[]> {
+  return makeOpenOpsTablesRequest<TablesMcpEndpoint[]>(
+    'get',
+    `api/mcp/endpoints/`,
+    undefined,
+    createAxiosHeaders(token),
+  );
+}
diff --git a/packages/server/api/src/app/openops-tables/get-workspace-by-name.ts b/packages/server/api/src/app/openops-tables/get-workspace-by-name.ts
new file mode 100644
index 0000000000..741c160aa3
--- /dev/null
+++ b/packages/server/api/src/app/openops-tables/get-workspace-by-name.ts
@@ -0,0 +1,18 @@
+import {
+  createAxiosHeaders,
+  makeOpenOpsTablesRequest,
+  Workspace,
+} from '@openops/common';
+
+export async function getWorkspaceByName(
+  token: string,
+  name: string,
+): Promise<Workspace | undefined> {
+  const allWorkspaces = await makeOpenOpsTablesRequest<Workspace[]>(
+    'get',
+    `api/workspaces/`,
+    undefined,
+    createAxiosHeaders(token),
+  );
+  return allWorkspaces?.find((workspace) => workspace.name === name);
+}
diff --git a/packages/server/api/src/app/openops-tables/index.ts b/packages/server/api/src/app/openops-tables/index.ts
index 73fef834cc..c410df5d39 100644
--- a/packages/server/api/src/app/openops-tables/index.ts
+++ b/packages/server/api/src/app/openops-tables/index.ts
@@ -1,9 +1,12 @@
 import { addUserToWorkspace } from './add-user-workspace';
 import { createDatabase } from './create-database';
+import { createMcpEndpoint } from './create-mcp-endpoint';
 import { createTable } from './create-table';
 import { createUser } from './create-user';
 import { createWorkspace } from './create-workspace';
 import { createDefaultWorkspaceAndDatabase } from './default-workspace-database';
+import { getMcpEndpointList } from './get-mcp-endpoint-list';
+import { getWorkspaceByName } from './get-workspace-by-name';
 import { renameDatabase } from './rename-database';
 
 export const openopsTables = {
@@ -14,4 +17,7 @@ export const openopsTables = {
   createWorkspace,
   createDefaultWorkspaceAndDatabase,
   renameDatabase,
+  getMcpEndpointList,
+  createMcpEndpoint,
+  getWorkspaceByName,
 };
diff --git a/packages/server/api/src/main.ts b/packages/server/api/src/main.ts
index ba68bf2e33..1bc375f047 100644
--- a/packages/server/api/src/main.ts
+++ b/packages/server/api/src/main.ts
@@ -11,6 +11,7 @@ import { isNil } from '@openops/shared';
 import { FastifyInstance } from 'fastify';
 import { appPostBoot } from './app/app';
 import { databaseConnection } from './app/database/database-connection';
+import { createOpenOpsTablesMcpEndpoint } from './app/database/seeds/create-open-ops-tables-mcp-endpoint';
 import { seedDevData } from './app/database/seeds/dev-seeds';
 import { seedFocusDataAggregationTemplateTable } from './app/database/seeds/openops-aggregated-costs-seed';
 import * as analytics from './app/database/seeds/openops-analytics-seed';
@@ -98,6 +99,7 @@ const main = async (): Promise<void> => {
     await databaseConnection().runMigrations();
 
     await upsertAdminUser();
+    await createOpenOpsTablesMcpEndpoint();
     await updateOpenopsTablesDatabase();
     await deleteOldOpportunitiesTable();
     await seedDevData();


Reviews:
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T02:19:27Z
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T02:20:07Z
user: login: rita-gorokhod
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T07:12:14Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR adds support for managing MCP endpoints in OpenOps Tables by introducing new MCP-related functions and integrating them into both the API bootup and AI tools.  
- Introduces functions to create and retrieve MCP endpoints.  
- Updates the application's initialization to include MCP endpoint creation.  
- Extends API and AI modules with MCP endpoint integration.

### Reviewed Changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

<details>
<summary>Show a summary per file</summary>

| File | Description |
| ---- | ----------- |
| packages/server/api/src/main.ts | Invokes checkAndCreateMcpEndpoint during application startup. |
| packages/server/api/src/app/openops-tables/index.ts | Exports new MCP endpoint functions and workspace retrieval function. |
| packages/server/api/src/app/openops-tables/get-workspace-by-name.ts | Adds a new function to fetch a workspace by its name. |
| packages/server/api/src/app/openops-tables/get-mcp-endpoint-list.ts | Introduces a function to retrieve the list of MCP endpoints. |
| packages/server/api/src/app/openops-tables/create-mcp-endpoint.ts | Implements endpoint creation functionality. |
| packages/server/api/src/app/database/seeds/check-and-create-mcp-endpoint.ts | Contains logic to seed the MCP endpoint if it is missing. |
| packages/server/api/src/app/ai/mcp/tables-tools.ts | Integrates MCP endpoint into the AI tools by creating a client interface. |
| packages/server/api/src/app/ai/mcp/mcp-tools.ts | Merges MCP tools with existing AI toolsets. |
| packages/openops/src/lib/openops-tables/types/table-workspace.ts | Defines a type for table workspace data. |
| packages/openops/src/lib/openops-tables/types/mcp.ts | Defines a type for MCP endpoint data. |
| packages/openops/src/lib/openops-tables/types/index.ts | Exports the newly added MCP and workspace types. |
| packages/openops/src/lib/openops-tables/requests-helpers.ts | Modifies the makeOpenOpsTablesRequest export to be publicly accessible. |
</details>


<details>
<summary>Files not reviewed (1)</summary>

* **ai-prompts/mcp.txt**: Language not supported
</details>



state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T07:15:04Z
user: login: rita-gorokhod
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T07:16:20Z
user: login: rita-gorokhod
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T07:23:13Z
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T08:14:57Z
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T08:15:07Z
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T08:25:11Z
user: login: rita-gorokhod
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T08:33:42Z
user: login: rita-gorokhod
body: Amazing work 👏 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T08:34:17Z
user: login: rmn-snpk
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T08:36:07Z

Review comments:
diff_hunk: @@ -98,6 +99,7 @@ const main = async (): Promise<void> => {
     await databaseConnection().runMigrations();
 
     await upsertAdminUser();
+    await checkAndCreateMcpEndpoint();
path: packages/server/api/src/main.ts
user: login: rmn-snpk
body: We check for the mcp (and create, if needed). because fetching inside the `getTablesTools` is triggered on each request. 
created_at: 2025-05-15T02:19:27Z
author_association: NONE
diff_hunk: @@ -111,7 +111,7 @@ export async function makeOpenOpsTablesGet<T>(
   return responses;
 }
 
-async function makeOpenOpsTablesRequest<T>(
+export async function makeOpenOpsTablesRequest<T>(
path: packages/openops/src/lib/openops-tables/requests-helpers.ts
user: login: rmn-snpk
body: Get method wraps the content inside array, which is not suitable here 
created_at: 2025-05-15T02:20:07Z
author_association: NONE
diff_hunk: @@ -34,3 +34,19 @@ You must know how to:
 - Do not assume column or metric names. Always ensure:
 - Field names match exactly with the dataset schema (case-sensitive)
 - No inferred or aliased column names are used unless explicitly confirmed
+
+
+OpenOps Tables Integration
+When invoking the OpenOps Tables (Baserow) MCP, you must fully understand the Baserow REST API and its core functionality. Specifically:
+- Perform operations on database tables, rows, and fields.
+- Understand how to create, update, delete, and retrieve rows and fields in a table.
+- Be able to manage table schema (e.g., adding or removing fields) using the appropriate endpoints.
+- Always ensure:
+  - Table IDs, row IDs, and field IDs are correctly obtained through API calls and not assumed.
+  - Names, field types, or constraints match Baserow's schema or configuration exactly.
+  - Token-based authentication is used for all API interactions.
+- Format payloads appropriately for each endpoint, adhering to Baserow's API requirements (e.g., the types and structure of fields and rows).
+
+Failure to meet any of these requirements could result in invalid API calls or data mismatches.
+* When you are asked about "my dashboard", "finops dashboard", "homepage dashboard", "analytics dashboard", or "main dashboard" -- if you don't have the dashboard id and you are not given it, search for it by the slug 'finops'.
+* When you are asked about "my dashboard", "finops dashboard", "homepage dashboard", "analytics dashboard", or "main dashboard" -- if you don't have the dashboard id and you are not given it, search for it by the slug 'finops'.
path: ai-prompts/mcp.txt
user: login: rita-gorokhod
body: this is part of the superset prompt
created_at: 2025-05-15T07:12:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,18 @@
+import {
+  createAxiosHeaders,
+  makeOpenOpsTablesRequest,
+  Workspace,
+} from '@openops/common';
+
+export async function getWorkspaceByName(
+  token: string,
+  name: string,
+): Promise<Workspace | undefined> {
+  const allWorkspaces = await makeOpenOpsTablesRequest<Workspace[]>(
+    'get',
+    `api/workspaces/`,
+    'undefined',
path: packages/server/api/src/app/openops-tables/get-workspace-by-name.ts
user: login: Copilot
body: The third argument passed to makeOpenOpsTablesRequest is the string 'undefined' rather than the JavaScript undefined. This may lead to unintended API behavior; consider removing the quotes to pass the actual undefined value.
```suggestion
    undefined,
```
created_at: 2025-05-15T07:15:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,6 +99,7 @@ const main = async (): Promise<void> => {
     await databaseConnection().runMigrations();
 
     await upsertAdminUser();
+    await checkAndCreateMcpEndpoint();
path: packages/server/api/src/main.ts
user: login: rita-gorokhod
body: maybe createOpenOpsTablesMcpEndpoint()?
created_at: 2025-05-15T07:16:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,3 +34,19 @@ You must know how to:
 - Do not assume column or metric names. Always ensure:
 - Field names match exactly with the dataset schema (case-sensitive)
 - No inferred or aliased column names are used unless explicitly confirmed
+
+
+OpenOps Tables Integration
+When invoking the OpenOps Tables (Baserow) MCP, you must fully understand the Baserow REST API and its core functionality. Specifically:
+- Perform operations on database tables, rows, and fields.
+- Understand how to create, update, delete, and retrieve rows and fields in a table.
+- Be able to manage table schema (e.g., adding or removing fields) using the appropriate endpoints.
path: ai-prompts/mcp.txt
user: login: rita-gorokhod
body: I think we need to remove this and change instead to "you cannot add or delete tables, or change table schema (adding, removing, or changing fields)", because it's not supported in the baserow mcp right now
created_at: 2025-05-15T07:23:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,6 +99,7 @@ const main = async (): Promise<void> => {
     await databaseConnection().runMigrations();
 
     await upsertAdminUser();
+    await checkAndCreateMcpEndpoint();
path: packages/server/api/src/main.ts
user: login: rmn-snpk
body: done
created_at: 2025-05-15T08:14:57Z
author_association: NONE
diff_hunk: @@ -34,3 +34,19 @@ You must know how to:
 - Do not assume column or metric names. Always ensure:
 - Field names match exactly with the dataset schema (case-sensitive)
 - No inferred or aliased column names are used unless explicitly confirmed
+
+
+OpenOps Tables Integration
+When invoking the OpenOps Tables (Baserow) MCP, you must fully understand the Baserow REST API and its core functionality. Specifically:
+- Perform operations on database tables, rows, and fields.
+- Understand how to create, update, delete, and retrieve rows and fields in a table.
+- Be able to manage table schema (e.g., adding or removing fields) using the appropriate endpoints.
+- Always ensure:
+  - Table IDs, row IDs, and field IDs are correctly obtained through API calls and not assumed.
+  - Names, field types, or constraints match Baserow's schema or configuration exactly.
+  - Token-based authentication is used for all API interactions.
+- Format payloads appropriately for each endpoint, adhering to Baserow's API requirements (e.g., the types and structure of fields and rows).
+
+Failure to meet any of these requirements could result in invalid API calls or data mismatches.
+* When you are asked about "my dashboard", "finops dashboard", "homepage dashboard", "analytics dashboard", or "main dashboard" -- if you don't have the dashboard id and you are not given it, search for it by the slug 'finops'.
+* When you are asked about "my dashboard", "finops dashboard", "homepage dashboard", "analytics dashboard", or "main dashboard" -- if you don't have the dashboard id and you are not given it, search for it by the slug 'finops'.
path: ai-prompts/mcp.txt
user: login: rmn-snpk
body: fixed

created_at: 2025-05-15T08:15:07Z
author_association: NONE
diff_hunk: @@ -34,3 +34,19 @@ You must know how to:
 - Do not assume column or metric names. Always ensure:
 - Field names match exactly with the dataset schema (case-sensitive)
 - No inferred or aliased column names are used unless explicitly confirmed
+
+
+OpenOps Tables Integration
+When invoking the OpenOps Tables (Baserow) MCP, you must fully understand the Baserow REST API and its core functionality. Specifically:
+- Perform operations on database tables, rows, and fields.
+- Understand how to create, update, delete, and retrieve rows and fields in a table.
+- Be able to manage table schema (e.g., adding or removing fields) using the appropriate endpoints.
path: ai-prompts/mcp.txt
user: login: rmn-snpk
body: done
created_at: 2025-05-15T08:25:11Z
author_association: NONE
diff_hunk: @@ -12,10 +13,12 @@ export const getMCPTools = async (): Promise<ToolSet> => {
 
   const supersetTools = await safeGetTools('superset', getSupersetTools);
   const docsTools = await safeGetTools('docs', getDocsTools);
+  const tablesTools = await safeGetTools('docs', getTablesTools);
path: packages/server/api/src/app/ai/mcp/mcp-tools.ts
user: login: rita-gorokhod
body: 'tables'
created_at: 2025-05-15T08:33:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -12,10 +13,12 @@ export const getMCPTools = async (): Promise<ToolSet> => {
 
   const supersetTools = await safeGetTools('superset', getSupersetTools);
   const docsTools = await safeGetTools('docs', getDocsTools);
+  const tablesTools = await safeGetTools('docs', getTablesTools);
path: packages/server/api/src/app/ai/mcp/mcp-tools.ts
user: login: rmn-snpk
body: done
created_at: 2025-05-15T08:36:07Z
author_association: NONE

PR comments:
user: login: linear[bot]
created_at: 2025-05-15T02:07:34Z
body: <p><a href="https://linear.app/openops/issue/OPS-1722/connect-chatbot-to-baserows-mcp">OPS-1722 Connect chatbot to baserow's MCP</a></p>
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-05-15T08:29:32Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=openops-cloud_openops&pullRequest=603) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=openops-cloud_openops&pullRequest=603&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=openops-cloud_openops&pullRequest=603&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=openops-cloud_openops&pullRequest=603&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=openops-cloud_openops&pullRequest=603&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=openops-cloud_openops&pullRequest=603&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=openops-cloud_openops&pullRequest=603)


author_association: NONE